KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > compiere > grid > GridController


1 /******************************************************************************
2  * The contents of this file are subject to the Compiere License Version 1.1
3  * ("License"); You may not use this file except in compliance with the License
4  * You may obtain a copy of the License at http://www.compiere.org/license.html
5  * Software distributed under the License is distributed on an "AS IS" basis,
6  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
7  * the specific language governing rights and limitations under the License.
8  * The Original Code is Compiere ERP & CRM Business Solution
9  * The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc.
10  * Portions created by Jorg Janke are Copyright (C) 1999-2001 Jorg Janke, parts
11  * created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved.
12  * Contributor(s): ______________________________________.
13  *****************************************************************************/

14 package org.compiere.grid;
15
16 import java.awt.*;
17 import java.awt.event.*;
18 import javax.swing.*;
19 import javax.swing.table.*;
20 import javax.swing.event.*;
21 import java.beans.*;
22 import java.util.*;
23
24 import org.compiere.grid.ed.*;
25 import org.compiere.grid.tree.*;
26 import org.compiere.apps.*;
27 import org.compiere.model.*;
28 import org.compiere.util.*;
29 import org.compiere.swing.*;
30 import org.compiere.plaf.*;
31
32 /**
33  * The Grid Controller is the panel for single and multi-row presentation
34  * and links to the Model Tab.
35  *
36  * <pre>
37  * UI Structure:
38  * this (BorderLayout)
39  * splitPane (JSplitPane)
40  * left
41  * graphicPanel
42  * right
43  * cardPanel JPanel (CardLayout)
44  * srPane JSplitPane
45  * vPane JScrollPane
46  * vPanel VPanel (GridBagLayout)
47  * vIncludedGC GridController
48  * mrPane JScrollPane
49  * vTable VTable
50  *
51  * <B>DataBinding:<B>
52  * - MultiRow - is automatic between VTable and MTable
53  * - SingleRow
54  * - from VEditors via fireVetoableChange(m_columnName, null, getText());
55  * (vetoableChange)
56  * - to VEditors via updateSingleRow -> Editor.setValue(object)
57  *
58  * Event Chains
59  * -- Navigation --
60  * (VTable selection -> GridController.valueChanged)
61  * (APanel selection)
62  * + MTab.navivate
63  * + MTab.setCurrentRow
64  * + Update all MFields
65  * + MField.setValue
66  * + setContext
67  * + fire PropertyChange "Value"
68  * + VEditor.propertyChange
69  * + VEditor.setValue
70  * + MTab.fireProperyChange "CurrentRow"
71  * + VTable.propertyChange (setRowSelectionInterval)
72  * + GridController.valueChange
73  * + GridController.dynamicDisplay(complete)
74  * + MTab.fireDataStatusChanged
75  * + APanel.statusChanged
76  *
77  * -- ValueChanges --
78  * VEditor.fireVetoableChange
79  * + (VCellEditor.vetoableChange/getCellEditorValue) -- multi-row source
80  * + (GridController.vetoableChange) -- single-row source
81  * + MTable.setValueAt
82  * + MField.setValue
83  * + setContext
84  * + fire PropertyChange "Value"
85  * + VEditor.setValue
86  * + MTable.fireDataStatusChanged
87  * + MTab.dataStatusChanged
88  * + MTab.fireDataStatusChanged
89  * + APanel.statusChanged
90  * + GridController.dataStatusChanged
91  * + GridController.dynamicDisplay(selective)
92  * </pre>
93  * @author Jorg Janke
94  * @version $Id: GridController.java,v 1.45 2003/10/27 15:22:02 jjanke Exp $
95  */

96 public class GridController extends CPanel
97     implements DataStatusListener, ListSelectionListener, VetoableChangeListener, PropertyChangeListener, MouseListener
98 {
99     /**
100      * Constructor - you need to call initGrid for instanciation
101      */

102     public GridController()
103     {
104         try
105         {
106             jbInit();
107         }
108         catch(Exception JavaDoc e)
109         {
110             Log.error("GridController", e);
111         }
112     } // GridController
113

114     /**
115      * toString
116      * @return string representation
117      */

118     public String JavaDoc toString()
119     {
120         return "GridController for " + m_mTab;
121     } // toString
122

123     /**
124      * The Layout
125      */

126     private BorderLayout mainLayout = new BorderLayout();
127     private JSplitPane splitPane = new JSplitPane();
128     private CPanel graphPanel = new CPanel();
129     private BorderLayout graphLayout = new BorderLayout();
130     private CPanel cardPanel = new CPanel();
131     private CardLayout cardLayout = new CardLayout();
132     private JSplitPane srPane = new JSplitPane();
133     private JScrollPane vPane = new JScrollPane();
134     private GridController vIncludedGC = null;
135     private JScrollPane mrPane = new JScrollPane();
136     private CPanel xPanel = new CPanel();
137     private FlowLayout xLayout = new FlowLayout();
138     private VTable vTable = new VTable();
139     private VPanel vPanel = new VPanel();
140
141     /**
142      * Static Layout init
143      * @throws Exception
144      */

145     private void jbInit() throws Exception JavaDoc
146     {
147         this.setLayout(mainLayout);
148         this.add(splitPane, BorderLayout.CENTER);
149         splitPane.setOpaque(false);
150         graphPanel.setLayout(graphLayout);
151         //
152
splitPane.add(graphPanel, JSplitPane.LEFT);
153         splitPane.add(cardPanel, JSplitPane.RIGHT);
154         splitPane.setBorder(null);
155         splitPane.setName("gc_splitPane");
156         //
157
cardPanel.setLayout(cardLayout);
158         cardPanel.add(srPane, "srPane"); // Sequence Important!
159
cardPanel.add(mrPane, "mrPane");
160         cardPanel.setBorder(null);
161         cardPanel.setName("gc_cardPanel");
162         // single row (w/o xPane it would be centered)
163
srPane.setBorder(null);
164         srPane.setName("gc_srPane");
165         srPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
166         srPane.add(vPane, JSplitPane.TOP);
167         srPane.setTopComponent(vPane);
168         vPane.getViewport().add(xPanel, null);
169         xPanel.add(vPanel);
170         vPane.setBorder(null);
171         xPanel.setLayout(xLayout);
172         xPanel.setName("gc_xPanel");
173         xLayout.setAlignment(FlowLayout.LEFT);
174         xLayout.setHgap(0);
175         xLayout.setVgap(0);
176         // multi-row
177
mrPane.setBorder(null);
178         mrPane.getViewport().add(vTable, null);
179         mrPane.setName("gc_mrPane");
180         //
181
graphPanel.setBorder(null);
182         graphPanel.setName("gc_graphPanel");
183         srPane.setDividerLocation(200);
184     } // jbInit
185

186     /**
187      * Displose
188      */

189     public void dispose()
190     {
191         Log.trace(Log.l2_Sub, "GridController.dispose (" + m_mTab.toString() + ")");
192         // clear info
193
stopEditor(false);
194         if (m_mTab.needSave(true, false))
195             m_mTab.dataIgnore();
196         vIncludedGC = null;
197
198         // Listeners
199
m_mTab.getTableModel().removeDataStatusListener(this);
200         m_mTab.getTableModel().removeVetoableChangeListener(this);
201         vTable.getSelectionModel().removeListSelectionListener(this);
202         m_mTab.removePropertyChangeListener(vTable);
203
204         // editors
205
Component[] comp = vPanel.getComponents();
206         for (int i = 0; i < comp.length; i++)
207         {
208             if (comp[i] instanceof VEditor)
209             {
210                 VEditor vEditor = (VEditor)comp[i];
211                 vEditor.removeVetoableChangeListener(this);
212                 String JavaDoc columnName = comp[i].getName();
213                 MField mField = m_mTab.getField(columnName);
214                 if (mField != null)
215                     mField.removePropertyChangeListener(vEditor);
216                 vEditor.dispose();
217             }
218         }
219         /** @todo Remove APanel Button listeners */
220
221         vTable.removeAll();
222         vTable.setModel(new DefaultTableModel()); // remove reference
223
vTable = null;
224         vPanel.removeAll();
225         vPanel = null;
226         splitPane.removeAll();
227         splitPane = null;
228         m_mTab = null;
229         m_tree = null;
230         this.removeAll();
231     } // dispose
232

233     /** Model Tab */
234     private MTab m_mTab = null;
235     /** Window */
236     private int m_WindowNo;
237     /** Only Multi-Row exist */
238     private boolean m_onlyMultiRow = false;
239     /** Single/Multi Row indicator */
240     private boolean m_singleRow = true;
241     /** Veto Active */
242     private boolean m_vetoActive = false;
243     /** Tree Panel (optional) */
244     private VTreePanel m_tree;
245
246     /*************************************************************************/
247
248     /**
249      * Init Grid.
250      * <pre>
251      * - Map table to model
252      * - Update (multi-row) table info with renderers/editors
253      * - build single-row panel
254      * - initialize display
255      * </pre>
256      * @param mTab tab
257      * @param onlyMultiRow only table
258      * @param WindowNo window no
259      * @param aPanel optional Application Panel for adding button listeners
260      * @param mWindow parent Window Model
261      * @return true if initialized
262      */

263     public boolean initGrid (MTab mTab, boolean onlyMultiRow, int WindowNo, APanel aPanel, MWindow mWindow)
264     {
265         Log.trace(Log.l2_Sub, "GridController.initGrid (" + mTab.toString() + ")");
266         m_mTab = mTab;
267         m_WindowNo = WindowNo;
268         m_onlyMultiRow = onlyMultiRow;
269
270         // Set up Multi Row Table
271
vTable.setModel(m_mTab.getTableModel());
272
273         // Update Table Info -------------------------------------------------
274
int size = setupVTable (aPanel, m_mTab, vTable);
275
276         // Set Color on Tab Level
277
// this.setBackgroundColor (mTab.getColor());
278

279         // Single Row -------------------------------------------------------
280
if (!m_onlyMultiRow)
281         {
282             for (int i = 0; i < size; i++)
283             {
284                 MField mField = m_mTab.getField(i);
285
286                 if (mField.isDisplayed())
287                 {
288                     VEditor vEditor = VEditorFactory.getEditor(m_mTab, mField, false);
289                     // MField => VEditor - New Field value to be updated to editor
290
mField.addPropertyChangeListener(vEditor);
291                     // VEditor => this - New Editor value to be updated here (MTable)
292
vEditor.addVetoableChangeListener(this);
293                     // Add to VPanel
294
vPanel.addField(VEditorFactory.getLabel(mField), vEditor,
295                         mField.isSameLine(),
296                         mField.isLongField(),
297                         mField.getDisplayType(),
298                         mField.getFieldGroup());
299                     // APanel Listen to buttons
300
if (mField.getDisplayType() == DisplayType.Button && aPanel != null)
301                         ((JButton)vEditor).addActionListener (aPanel);
302                 }
303             } // for all fields
304

305             // No Included Grid Controller
306
srPane.setResizeWeight(1); // top part gets all
307
srPane.setDividerSize (0);
308             srPane.setDividerLocation (9999);
309
310             // Use SR to size MR
311
mrPane.setPreferredSize(vPanel.getPreferredSize());
312         } // Single-Row
313

314         // Tree Graphics Layout
315
int AD_Tree_ID = 0;
316         if (m_mTab.isTreeTab())
317             AD_Tree_ID = MTree.getAD_Tree_ID (m_mTab.getKeyColumnName());
318         if (m_mTab.isTreeTab() && AD_Tree_ID != 0)
319         {
320             m_tree = new VTreePanel(m_WindowNo, false, true);
321             if (m_mTab.getTabNo() == 0) // initialize other tabs later
322
m_tree.initTree(AD_Tree_ID);
323             m_tree.addPropertyChangeListener(VTreePanel.NODE_SELECTION, this);
324             graphPanel.add(m_tree, BorderLayout.CENTER);
325             splitPane.setDividerLocation(250);
326         // splitPane.resetToPreferredSizes();
327
}
328         else // No Graphics - hide
329
{
330             graphPanel.setPreferredSize(new Dimension(0,0));
331             splitPane.setDividerSize(0);
332             splitPane.setDividerLocation(0);
333         }
334
335         // Receive DataStatusChanged info from MTab
336
m_mTab.addDataStatusListener(this);
337         // Receive vetoableChange info from MTable when saving
338
m_mTab.getTableModel().addVetoableChangeListener(this);
339         // Selection Listener -> valueChanged
340
vTable.getSelectionModel().addListSelectionListener(this);
341         // Navigation (RowChanged)
342
m_mTab.addPropertyChangeListener(vTable);
343
344         // Update UI
345
vTable.autoSize();
346
347         setTabLevel(m_mTab.getTabLevel());
348
349         // Set initial presentation
350
if (onlyMultiRow || !m_mTab.isSingleRow())
351             switchMultiRow();
352         else
353             switchSingleRow();
354     // Log.trace(Log.l2_Sub, "GridController.dynInit (" + mTab.toString() + ") - fini");
355
return true;
356     } // initGrid
357

358     /**
359      * Include Tab
360      * @param gc grod controller to add
361      * @return true if included
362      */

363     public boolean includeTab (GridController gc)
364     {
365         MTab imcludedMTab = gc.getMTab();
366         if (m_mTab.getIncluded_Tab_ID () != imcludedMTab.getAD_Tab_ID())
367             return false;
368         //
369
vIncludedGC = gc;
370         vIncludedGC.switchMultiRow();
371         //
372
Dimension size = getPreferredSize();
373         srPane.setResizeWeight(.75); // top part gets 75%
374
srPane.add(vIncludedGC, JSplitPane.BOTTOM);
375         srPane.setBottomComponent(vIncludedGC);
376         srPane.setDividerSize (5);
377         //
378
int height = 150;
379         vIncludedGC.setPreferredSize(new Dimension(600, height));
380         setPreferredSize(new Dimension(size.width, size.height+height));
381         srPane.setDividerLocation (size.height);
382         //
383
imcludedMTab.setIncluded (true);
384         imcludedMTab.query (false, 0);
385         //
386
JRootPane rt = SwingUtilities.getRootPane(this);
387         if (rt == null)
388             System.out.println("Root pane null");
389         else
390         {
391             System.out.println("Root=" + rt);
392             rt.addMouseListener(vIncludedGC);
393             Component gp = rt.getGlassPane();
394             if (gp == null)
395                 System.out.println("No Glass Pane");
396             else
397             {
398                 System.out.println("Glass=" + gp);
399                 gp.addMouseListener(vIncludedGC);
400             }
401
402         }
403
404
405
406         vIncludedGC.addMouseListener(vIncludedGC);
407         vIncludedGC.enableEvents(AWTEvent.HIERARCHY_EVENT_MASK + AWTEvent.MOUSE_EVENT_MASK);
408         /**
409         vIncludedGC.splitPane.addMouseListener(vIncludedGC);
410         vIncludedGC.cardPanel.addMouseListener(vIncludedGC);
411         vIncludedGC.mrPane.addMouseListener(vIncludedGC);
412         vIncludedGC.vTable.addMouseListener(vIncludedGC);
413         **/

414         return true;
415     } // IncludeTab
416

417     /**
418      * Setup Multi-Row Table (add fields)
419      * @param aPanel Panel
420      * @param mTab Model Tab
421      * @param table JTable
422      * @return size
423      */

424     private int setupVTable (APanel aPanel, MTab mTab, VTable table)
425     {
426         int size = mTab.getFieldCount ();
427         for (int i = 0; i < size; i++)
428         {
429             TableColumn tc = getTableColumn (table, i);
430             MField mField = mTab.getField (i);
431             //
432
if (mField.getColumnName ().equals (tc.getIdentifier ().toString ()))
433             {
434                 if (mField.getDisplayType () == DisplayType.RowID)
435                 {
436                     tc.setCellRenderer (new VRowIDRenderer (false));
437                     tc.setCellEditor (new VRowIDEditor (false));
438                     tc.setHeaderValue ("");
439                     tc.setMaxWidth (2);
440                 }
441                 else
442                 {
443                     // need to set CellEditor explicitly as default editor based on class causes problem (YesNo-> Boolean)
444
if (mField.isDisplayed ())
445                     {
446                         tc.setCellRenderer (new VCellRenderer (mField));
447                         VCellEditor ce = new VCellEditor (mField);
448                         tc.setCellEditor (ce);
449                         //
450
tc.setHeaderValue (mField.getHeader ());
451                         tc.setPreferredWidth (Math.max (mField.getDisplayLength (), 30));
452                         tc.setHeaderRenderer (new VHeaderRenderer (mField.getDisplayType ()));
453
454                         // Enable Button actions in grid
455
if (mField.getDisplayType () == DisplayType.Button)
456                         {
457                             VEditor button = ce.getEditor ();
458                             if (button != null && aPanel != null)
459                                 ((JButton)button).addActionListener (aPanel);
460                         }
461                     }
462                     else // column not displayed
463
{
464                         tc.setHeaderValue (null);
465                         tc.setMinWidth (0);
466                         tc.setMaxWidth (0);
467                         tc.setPreferredWidth (0);
468                     }
469                 }
470             // System.out.println ("TableColumnID " + tc.getIdentifier ()
471
// + " Renderer=" + tc.getCellRenderer ()
472
// + mField.getHeader ());
473

474                 tc.setMinWidth(30);
475             } // found field
476
else
477                 Log.error ("GridController.setupVTable - TableColumn " + tc.getIdentifier ()
478                   + " <> MField " + mField.getColumnName() + mField.getHeader());
479         } // for all fields
480
return size;
481     } // setupVTable
482

483     /**
484      * Activate Grid Controller.
485      * Called by APanel when GridController is displayed (foreground)
486      */

487     public void activate ()
488     {
489         // Tree to be initiated on second/.. tab
490
if (m_mTab.isTreeTab() && m_mTab.getTabNo() != 0)
491         {
492             int AD_Tree_ID = Env.getContextAsInt (Env.getCtx(), m_WindowNo, "AD_Tree_ID");
493             if (AD_Tree_ID == 0)
494                 AD_Tree_ID = MTree.getAD_Tree_ID (m_mTab.getKeyColumnName());
495             m_tree.initTree (AD_Tree_ID);
496         }
497     } // activate
498

499
500     /**
501      * Register ESC Actions
502      * - overwrite VTable's Keystroks assigment for ESC
503      * @param aIgnore ignore
504      */

505     public void registerESCAction (AppsAction aIgnore)
506     {
507         int c = VTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
508         vTable.getInputMap(c).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), aIgnore.getName());
509         vTable.getActionMap().put(aIgnore.getName(), aIgnore);
510
511     // AEnv.printActionInputMap(vTable);
512
} // registerESCAction
513

514     /**
515      * Query Tab and resize Table
516      * (called from APanel)
517      * @param onlyCurrentRows only current rows
518      * @param onlyCurrentDays how many days back
519      */

520     public void query (boolean onlyCurrentRows, int onlyCurrentDays)
521     {
522         // start loading while building screen
523
m_mTab.query(onlyCurrentRows, onlyCurrentDays);
524         // Update UI
525
vTable.autoSize();
526     } // query
527

528     /*************************************************************************/
529
530     /**
531      * Switch from single to multi & vice versa
532      */

533     public void switchRowPresentation()
534     {
535         stopEditor(true);
536         if (m_singleRow)
537             switchMultiRow();
538         else
539             switchSingleRow();
540     } // switchRowPresentation
541

542     /**
543      * Switch to SingleRow Presentation
544      */

545     public void switchSingleRow()
546     {
547         if (m_onlyMultiRow)
548             return;
549         cardLayout.first(cardPanel);
550         m_singleRow = true;
551         dynamicDisplay(0);
552     } // switchSingleRow
553

554     /**
555      * Switch to MultiRow Presentation
556      */

557     public void switchMultiRow()
558     {
559         cardLayout.last(cardPanel);
560         m_singleRow = false;
561     } // switchSingleRow
562

563     /**
564      * Is Single Row presentation
565      * @return true if Single Row is displayed
566      */

567     public boolean isSingleRow()
568     {
569         return m_singleRow;
570     } // isSingleRow
571

572     /*************************************************************************/
573
574     /**
575      * Remove Listener - pass on to MTab
576      * @param l listener
577      */

578     public synchronized void removeDataStatusListener(DataStatusListener l)
579     {
580         m_mTab.removeDataStatusListener(l);
581     } // removeDataStatusListener
582

583     /**
584      * Add Data Status Listener - pass on to MTab
585      * @param l listener
586      */

587     public synchronized void addDataStatusListener(DataStatusListener l)
588     {
589         m_mTab.addDataStatusListener(l);
590     }
591
592     /**
593      * Data Status Listener - for MTab events.
594      * <p>
595      * Callouts are processed here for GUI changes
596      * - same as in MTab.setValue for batch changes
597      * <p>
598      * calls dynamicDisplay
599      * @param e event
600      */

601     public void dataStatusChanged(DataStatusEvent e)
602     {
603     // if (e.getChangedColumn() == 0)
604
// return;
605
int col = e.getChangedColumn();
606         Log.trace(Log.l2_Sub, "GridController.dataStatusChanged (" + m_mTab + ") Col=" + col, e.toString());
607
608         // Process Callout only for specific columns
609
if (col != 0)
610         {
611             MField mField = m_mTab.getField(col);
612             if (mField != null && mField.getCallout().length() > 0)
613             {
614                 String JavaDoc msg = m_mTab.processFieldChange(mField); // Dependencies & Callout
615
if (msg.length() > 0)
616                     ADialog.error(m_WindowNo, this, msg);
617             }
618         }
619         dynamicDisplay(col);
620     } // dataStatusChanged
621

622     /*************************************************************************/
623
624     /**
625      * List Selection Listener (VTable) - row changed
626      * @param e event
627      */

628     public void valueChanged(ListSelectionEvent e)
629     {
630         // nothing or initiated by mouse (wait for "real" one)
631
if (e.getValueIsAdjusting())
632             return;
633         // no rows
634
if (m_mTab.getRowCount() == 0)
635             return;
636
637     // vTable.stopEditor(graphPanel);
638
int rowTable = vTable.getSelectedRow();
639         int rowCurrent = m_mTab.getCurrentRow();
640         Log.trace(Log.l2_Sub, "GridController.valueChanged (" + m_mTab.toString() + ")",
641             "Row in Table=" + rowTable + ", in Model=" + rowCurrent);
642
643         if (rowTable == -1) // nothing selected
644
{
645             if (rowCurrent >= 0)
646             {
647                 vTable.setRowSelectionInterval(rowCurrent, rowCurrent); // causes this method to be called again
648
return;
649             }
650         }
651         else
652         {
653             if (rowTable != rowCurrent)
654                 m_mTab.navigate(rowTable);
655             dynamicDisplay(0);
656         }
657
658         // TreeNavigation - Synchronize -- select node in tree
659
if (m_tree != null)
660             m_tree.setSelectedNode (m_mTab.getCurrentKeyID()); // ignores new (-1)
661

662     // Log.trace(Log.l2_Sub, "GridController.valueChanged (" + m_mTab.toString() + ") - fini",
663
// "Row in Table=" + rowTable + ", in Model=" + rowCurrent);
664

665         // Query Included Tab
666
if (vIncludedGC != null)
667             vIncludedGC.getMTab().query(false, 0);
668     } // valueChanged
669

670     /**
671      * PropertyChange Listener - Tree Panel - node selection
672      * @param e event
673      */

674     public void propertyChange(PropertyChangeEvent e)
675     {
676         System.out.println("propertyChange");
677         System.out.println(e);
678         if (e == null)
679             return;
680         Object JavaDoc value = e.getNewValue();
681         if (value == null)
682             return;
683         Log.trace(Log.l2_Sub, "GridController.propertyChange",
684             e.getPropertyName() + "=" + value
685             + " - " + value.getClass().toString());
686         if (!(value instanceof MTreeNode))
687             return;
688
689         // We Have a TreeNode
690
int nodeID = ((MTreeNode)value).getID();
691         // root of tree selected - ignore
692
if (nodeID == 0)
693             return;
694
695         // Search all rows for mode id
696
int size = m_mTab.getRowCount();
697         int row = -1;
698         for (int i = 0; i < size; i++)
699         {
700             if (m_mTab.getKeyID(i) == nodeID)
701             {
702                 row = i;
703                 break;
704             }
705         }
706         if (row == -1)
707         {
708             Log.error("GridController.propertyChange - Tab does not have ID with Node_ID=" + nodeID);
709             return;
710         }
711
712         // Navigate to node row
713
m_mTab.navigate(row);
714     } // propertyChange
715

716     /**
717      * Dynamic Display.
718      * - Single Row Screen layout and update of dynamic Lookups
719      * <p>
720      * Single Row layout:
721      * the components's name is the ColumnName; if it matches, the
722      * MField.isDisplayed(true) is used to determine if it is visible
723      * if the component is a VEditor, setEnabled is set from the MField
724      * <p>
725      * Multi Row layout is not changed:
726      * VCellRenderer calls JTable.isCellEditable -> checks MField.isEditable (Active, isDisplayed)
727      * VCellEditor.isCellEditable calls MField.isEditable(true) <br>
728      * If a column is not displayed, the width is set to 0 in dynInit
729      * <p>
730      * Dynamic update of data is handeled in VLookup.focusGained/Lost.
731      * When focus is gained the model is temporarily updated with the
732      * specific validated data, if lost, it is switched back to the
733      * unvalidated data (i.e. everything). This allows that the display
734      * methods have a lookup to display. <br>
735      * Here: if the changed field has dependents and the dependent
736      * is a Lookup and this lookup has a dynamic dependence of the changed field,
737      * the value of that field is set to null (in MTab.processDependencies -
738      * otherwise it would show an invalid value).
739      * As Editors listen for value changed of their MField, the display is updated.
740      * <p>
741      * Called from GridController.valueChanged/dataStatusChanged, APane;.stateChanged/unlock/cmd_...
742      * @param col selective column number or 0 if all
743      */

744     public void dynamicDisplay (int col)
745     {
746     // Log.trace(Log.l3_Util, "GridController.dynamicDisplay (" + m_mTab.toString() + ") SingleRow=" + isSingleRow() + ", OnlyMultiRow=" + m_onlyMultiRow);
747
// Don't update if multi-row
748
if (!isSingleRow() || m_onlyMultiRow)
749             return;
750         if (!m_mTab.isOpen())
751             return;
752         // Selective
753
if (col != 0)
754         {
755             MField changedField = m_mTab.getField(col);
756             String JavaDoc columnName = changedField.getColumnName();
757             ArrayList dependents = m_mTab.getDependentFieldList(columnName);
758             Log.trace(Log.l3_Util, "GridController.dynamicDisplay (" + m_mTab.toString() + ") "
759                 + columnName + " - Dependents=" + dependents.size());
760             // No Dependents and no Callout - Set just Background
761
if (dependents.size() == 0 && changedField.getCallout().length() > 0)
762             {
763                 Component[] comp = vPanel.getComponents();
764                 for (int i = 0; i < comp.length; i++)
765                 {
766                     if (columnName.equals(comp[i].getName ()) && comp[i] instanceof VEditor)
767                     {
768                         VEditor ve = (VEditor)comp[i];
769                         boolean manMissing = false;
770                         boolean noValue = changedField.getValue() == null || changedField.getValue().toString().length() == 0;
771                         if (noValue && changedField.isEditable(true) && changedField.isMandatory(true)) // check context
772
manMissing = true;
773                         ve.setBackground(manMissing || changedField.isError());
774                         break;
775                     }
776                 }
777                 return;
778             }
779         } // selective
780

781
782         // complete single row re-display
783
Log.trace(Log.l3_Util, "GridController.dynamicDisplay (" + m_mTab.toString() + ")");
784         // All Components in vPanel (Single Row)
785
Component[] comp = vPanel.getComponents();
786         for (int i = 0; i < comp.length; i++)
787         {
788             String JavaDoc columnName = comp[i].getName();
789             if (columnName != null)
790             {
791                 MField mField = m_mTab.getField(columnName);
792                 if (mField != null)
793                 {
794                     if (mField.isDisplayed(true)) // check context
795
{
796                         if (!comp[i].isVisible())
797                             comp[i].setVisible(true); // visibility
798
if (comp[i] instanceof VEditor)
799                         {
800                             VEditor ve = (VEditor)comp[i];
801                             boolean rw = mField.isEditable(true); // r/w - check Context
802
ve.setReadWrite(rw);
803                         // Log.trace(7, "GridController.dynamicDisplay RW=" + rw, mField);
804
boolean manMissing = false;
805                             // least expensive operations first // missing mandatory
806
if (rw && mField.getValue() == null && mField.isMandatory(true)) // check context
807
manMissing = true;
808                             ve.setBackground(manMissing || mField.isError());
809                         }
810                     }
811                     else if (comp[i].isVisible())
812                         comp[i].setVisible(false);
813                 }
814             }
815         } // all components
816
Log.trace(Log.l3_Util, "GridController.dynamicDisplay (" + m_mTab.toString() + ") - fini", col==0 ? "complete" : "seletive");
817     } // dynamicDisplay
818

819     /**
820      * Row Changed - synchronize with Tree
821      *
822      * @param save true the row was saved (changed/added), false if the row was deleted
823      * @param keyID the ID of the row changed
824      */

825     public void rowChanged (boolean save, int keyID)
826     {
827         if (m_tree == null)
828             return;
829         String JavaDoc name = (String JavaDoc)m_mTab.getValue("Name");
830         String JavaDoc description = (String JavaDoc)m_mTab.getValue("Description");
831         String JavaDoc sum = (String JavaDoc)m_mTab.getValue("IsSummary");
832         boolean isSummary = (sum == null ? false : sum.equals("Y"));
833         String JavaDoc imageIndicator = (String JavaDoc)m_mTab.getValue("Action"); // Menu - Action
834
//
835
m_tree.nodeChanged(save, keyID, name, description, isSummary, imageIndicator);
836     } // rowChanged
837

838
839     /*************************************************************************/
840
841     /**
842      * Vetoable Change Listener.
843      * Called from VEditor
844      * <pre>
845      * - for Save Confirmation dialog
846      * - for Single Row from VEditor: Update MTable
847      * </pre>
848      * @param e event
849      * @throws PropertyVetoException
850      */

851     public void vetoableChange(PropertyChangeEvent e) throws PropertyVetoException
852     {
853         Log.trace(Log.l2_Sub, "GridController.vetoableChange (" + m_mTab.toString() + ")",
854             e.getPropertyName() + "=" + e.getNewValue() + " (" + e.getOldValue() + ")");
855
856         // Save Confirmation dialog MTable-RowSave
857
if (e.getPropertyName().equals(MTable.PROPERTY))
858         {
859             // throw new PropertyVetoException calls this method (??) again
860
if (m_vetoActive)
861             {
862                 m_vetoActive = false;
863                 return;
864             }
865             if (!Env.isAutoCommit(Env.getCtx(), m_WindowNo) || m_mTab.getCommitWarning().length() > 0)
866             {
867                 if (!ADialog.ask(m_WindowNo, this, "SaveChanges?", m_mTab.getCommitWarning()))
868                 {
869                     m_vetoActive = true;
870                     throw new PropertyVetoException ("UserDeniedSave", e);
871                 }
872             }
873             return;
874         } // saveConfirmation
875

876
877         // Get Row/Col Info
878
MTable mTable = m_mTab.getTableModel();
879         int row = m_mTab.getCurrentRow();
880         int col = mTable.findColumn(e.getPropertyName());
881         //
882
if (e.getNewValue() == null && e.getOldValue() != null)
883             mTable.setChanged (true);
884         else
885         // mTable.setValueAt (e.getNewValue(), row, col, true);
886
mTable.setValueAt (e.getNewValue(), row, col); // -> dataStatusChanged -> dynamicDisplay
887

888     // Log.trace(Log.l2_Sub, "GridController.vetoableChange (" + m_mTab.toString() + ") - fini", e.getPropertyName() + "=" + e.getNewValue());
889
} // vetoableChange
890

891     /*************************************************************************/
892
893     /**
894      * Get Model Tab
895      * @return Model Tab
896      */

897     public MTab getMTab()
898     {
899         return m_mTab;
900     } // getMTab
901

902     /**
903      * Get Table Column
904      * (Find uses it to overwrite Editor/Renderer)
905      * @param table JTable to find TableColumn
906      * @param index index of column
907      * @return table column
908      */

909     protected TableColumn getTableColumn (VTable table, int index)
910     {
911     // Log.trace(Log.l5_DData, "GridController.getTableColumn", "index=" + index);
912
TableColumnModel tcm = table.getColumnModel();
913         if (index >= 0 && index < tcm.getColumnCount())
914             return tcm.getColumn(index);
915         Log.error("GridController.getTableColumn - No TableColumn for index=" + index);
916         return null;
917     } // getTableColumn
918

919     /**
920      * Get VTable
921      * @return VTable
922      */

923     public VTable getTable()
924     {
925         return vTable;
926     } // getTable
927

928     /**
929      * Stop Table & SR Editors and move focus to graphPanel
930      * @param saveValue save value
931      */

932     public void stopEditor (boolean saveValue)
933     {
934         Log.trace(Log.l2_Sub, "GridController.stopEditor (" + m_mTab.toString() + ")",
935             "TableEditing=" + vTable.isEditing());
936
937         // MultiRow - remove editors
938
vTable.stopEditor(saveValue);
939
940         // SingleRow - stop editors by changing focus
941
if (m_singleRow)
942             vPanel.transferFocus();
943         // graphPanel.requestFocus();
944
//
945
// Log.trace(Log.l2_Sub, "GridController.stopEditor (" + m_mTab.toString() + ") - fini",
946
// "Editing=" + vTable.isEditing());
947
} // stopEditors
948

949
950     public void mouseClicked(MouseEvent e)
951     {
952         System.out.println("mouseClicked - " + this + " - " + e);
953     }
954     public void mousePressed(MouseEvent e)
955     {
956         System.out.println("mousePressed - " + this + " - " + e);
957     }
958     public void mouseReleased(MouseEvent e)
959     {
960         System.out.println("mouseReleased - " + this + " - " + e);
961     }
962     public void mouseEntered(MouseEvent e)
963     {
964         System.out.println("mouseEntered - " + this + " - " + e);
965     }
966     public void mouseExited(MouseEvent e)
967     {
968         System.out.println("mouseExited - " + this + " - " + e);
969     }
970
971     public void processEvent (AWTEvent e)
972     {
973     // System.out.println("process Event " + e);
974
super.processEvent(e);
975     }
976
977 } // GridController
978
Popular Tags