source: java/main/src/main/java/com/framsticks/gui/Frame.java @ 98

Last change on this file since 98 was 98, checked in by psniegowski, 11 years ago

HIGHLIGHTS:

CHANGELOG:
Get data also on tree expansion.

Use nice framstick icon for empty nodes.

Update panel after reload if it is current.

Add shallow reload procedure.

Cut Gui prefix from several tree classes.

Bring back counter of GuiTreeNode?.

Use IdentityHashMap? were it is more appriopriate.

Remove TreeListener?.

Do not use TreeListener? in GUI.

Minor change.

Done migration to GuiTreeModel?.

BrowserTest? in that version always crashes frams.linux.

Move rendering implementation into GuiAbstractNode?.

Use hand-crafted list in GuiTreeNode?.

Generally, it would be a great place for WeakIdentityHashMap?
(but there is none in Java Collection Framework).

Remove superfluous logging.

Fix bug in GuiTreeNode?.

Use IdentityHashMap? instead of HashMap?.

Improve structure update.

Filter out invalid uids in UniqueListAccess?.

Improve TreeCellRenderer?.

Add filtering in TrackConsole?.

Improve TreeModel?.

More changes.

More improvements.

More changes.

Remove TreeNode?.

Support MetaNode? in the GuiTreeModel?.

Implement more in GuiTreeModel?.

Add CompositeParam? interface to FramsClass? and AccessInterface?.

Allow access by number to UniqueList?.

Add UidComparator?.

Use TreeMap? as a default accessee in unique list.

It keeps order of keys.

Introduce classes to use with new TreeModel?.

Another step.

Migrate from TreeNode? to Node in many places.

Remove some uses of TreeNode? as DefaultMutableTreeNode?.

Remove Path from TreeNode? interface.

Remove Path from TreeNode?.

Add Path recration from node feature.

Reworking TreeCellRenderer?.

Minor change of TreeOperations? interface.

Remove last methods from TreeNode?.

Another minor step.

Do not store reference to TreeAtFrame? in TreeNode?.

Add proxy exceptionHandler to StatusBar?.

Move panels management to TreeAtFrame?.

Store localChanges in the NodeAtFrame?.

More cleanup.

Move name computing to TreeCellRenderer?.

Move tooltip and icon computations to TreeCellRenderer?.

More dispatches removed.

Remove most dispatching from TreeNode?.

TreeNode? does not actually redispatch tasks.

Make Tree embedded in Browser use SwingDispatcher?.

Make lazy binding of Tree with Dispatcher.

Minor changes.

Organizational change in AbstractTree?.

Make AbstractTree? compose from Thread instead of inherit from it.

Make SwingDispatcher? and AtOnceDispatcher? Joinable compatible.

Add ListPanelProvider?.

Improve Controls readonly and enabled handling.

Properly pass ExceptionHandlers? in more places.

Make Tree.get accept ValueParam?.

  • This is to allow access number of list elements.

Remove not needed get redirection in ClientAtServer?.

Rename tryResolve to tryGet.

Unify tryResolveAndGet into tryResolve.

Remove resolveTop from Tree interface.

Make Tree.get accept Future<Path>.

Use get to implement resolveTop also in ObjectTree?.

Unify resolveTop and get in RemoteTree?.

Another minor step.

More minor changes in tree operations.

Minor organizational changes.

In RemoteTree? first fetch info for root.

Reworking resolving.

Minor changes.

Make ListAccess? return proxy iterators (instead of creating temporary collection).

Let AccessInterface? return Iterable<Param>.

Improve resolving.

More improvements.

First working completion in ManagedConsole?.

Rename resolve to resolveTop.

This reflects the actuall functionality.

Change semantic of tryResolve and tryResolveAndGet.

File size: 11.4 KB
Line 
1package com.framsticks.gui;
2
3import java.awt.BorderLayout;
4import java.awt.CardLayout;
5import java.awt.Color;
6import java.awt.Container;
7import java.awt.Dimension;
8import java.awt.Toolkit;
9import java.awt.event.ActionEvent;
10import java.awt.event.KeyEvent;
11import java.awt.event.MouseAdapter;
12import java.awt.event.MouseEvent;
13import java.util.IdentityHashMap;
14import java.util.Map;
15
16import javax.swing.AbstractAction;
17import javax.swing.BorderFactory;
18import javax.swing.JComponent;
19import javax.swing.JMenu;
20import javax.swing.JMenuBar;
21import javax.swing.JMenuItem;
22import javax.swing.JPanel;
23import javax.swing.JPopupMenu;
24import javax.swing.JScrollPane;
25import javax.swing.JSplitPane;
26import javax.swing.JTree;
27import javax.swing.KeyStroke;
28import javax.swing.ToolTipManager;
29import javax.swing.UIManager;
30import javax.swing.event.TreeExpansionEvent;
31import javax.swing.event.TreeExpansionListener;
32import javax.swing.event.TreeSelectionEvent;
33import javax.swing.event.TreeSelectionListener;
34import javax.swing.tree.DefaultTreeSelectionModel;
35import javax.swing.tree.TreePath;
36import javax.swing.tree.TreeSelectionModel;
37
38import org.apache.log4j.Logger;
39
40import com.framsticks.core.Mode;
41import com.framsticks.core.Path;
42import com.framsticks.core.Tree;
43import com.framsticks.core.TreeOperations;
44import com.framsticks.gui.view.TreeCellRenderer;
45import com.framsticks.params.AccessInterface;
46import com.framsticks.util.dispatching.Dispatching;
47import com.framsticks.util.dispatching.FutureHandler;
48import com.framsticks.util.dispatching.Joinable;
49import com.framsticks.util.dispatching.JoinableCollection;
50import com.framsticks.util.dispatching.JoinableParent;
51import com.framsticks.util.dispatching.JoinableState;
52import com.framsticks.util.swing.KeyboardModifier;
53import com.framsticks.util.swing.MenuConstructor;
54
55/**
56 * @author Piotr Sniegowski
57 */
58@SuppressWarnings("serial")
59public class Frame extends FrameJoinable implements JoinableParent {
60
61        private static final Logger log = Logger.getLogger(Frame.class.getName());
62
63        protected final Browser browser;
64
65        protected final Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
66
67        protected CardLayout cardPanelLayout;
68        protected JPanel cardPanel;
69
70        protected JScrollPane treeScrollPane;
71        protected JTree jtree;
72        protected TreeModel treeModel;
73
74        protected MetaNode rootNode;
75
76        protected JPanel treePanel;
77        protected JPopupMenu treePopupMenu;
78        protected JMenuItem treePopupMenuHeader;
79
80        protected JPanel mainPanel;
81        protected JPanel leftPanel;
82        protected JPanel normalWorkPanel;
83        protected CardLayout mainPanelLayout;
84
85        protected JMenuBar menuBar;
86        protected JMenu fileMenu;
87        protected JMenu editMenu;
88        protected JMenu viewMenu;
89        protected JMenu windowMenu;
90        protected JMenu helpMenu;
91
92        protected final Map<Tree, TreeAtFrame> treeAtFrames = new IdentityHashMap<>();
93        protected JoinableCollection<Tree> trees = new JoinableCollection<>();
94
95        public Frame(Browser browser) {
96                this.browser = browser;
97        }
98
99        protected void initializeGui() {
100                super.initializeGui();
101                /** this is done to remove the current value label from above the slider,
102                 * because it cannot put to work properly with floating-point value sliders,
103                 * nor it can be removed in normal way through JSlider methods  */
104                UIManager.put("Slider.paintValue", false);
105                log.debug("creating " + this);
106
107                Container contentPane = getSwing().getContentPane();
108                treePopupMenu = new JPopupMenu("title");
109                treePopupMenu.setName("popup");
110
111                treePanel = new JPanel();
112                treePanel.setLayout(new BorderLayout());
113
114                rootNode = new MetaNode();
115                rootNode.setName("root");
116                treeModel = new TreeModel(this);
117
118                jtree = new JTree(treeModel);
119                jtree.setName("tree");
120                jtree.setRootVisible(false);
121                jtree.setExpandsSelectedPaths(true);
122                jtree.setSelectionModel(new DefaultTreeSelectionModel());
123                ToolTipManager.sharedInstance().registerComponent(jtree);
124
125                jtree.addTreeSelectionListener(new TreeSelectionListener() {
126                        @Override
127                        public void valueChanged(TreeSelectionEvent e) {
128                                chooseTreeNode(e.getNewLeadSelectionPath());
129                        }
130                });
131
132                jtree.addTreeExpansionListener(new TreeExpansionListener() {
133
134                        @Override
135                        public void treeCollapsed(TreeExpansionEvent e) {
136
137                        }
138
139                        @Override
140                        public void treeExpanded(TreeExpansionEvent e) {
141                                loadChildren(treeModel.convertToPath(e.getPath()), false);
142                        }
143                });
144
145                jtree.setExpandsSelectedPaths(true);
146                jtree.setEditable(false);
147                jtree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
148                jtree.setShowsRootHandles(true);
149                jtree.setRowHeight(26);
150                jtree.setDoubleBuffered(true);
151                jtree.addMouseListener(new MouseAdapter() {
152                        @Override
153                        public void mousePressed(MouseEvent e) {
154                                assert isActive();
155                                showPopup(e);
156                        }
157
158                        @Override
159                        public void mouseReleased(MouseEvent e) {
160                                assert isActive();
161                                showPopup(e);
162                        }
163                });
164
165                new KeyboardModifier(jtree, JComponent.WHEN_FOCUSED)
166                        .join(KeyStroke.getKeyStroke('h'), KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0))
167                        .join(KeyStroke.getKeyStroke('j'), KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0))
168                        .join(KeyStroke.getKeyStroke('k'), KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0))
169                        .join(KeyStroke.getKeyStroke('l'), KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));
170
171                jtree.setCellRenderer(new TreeCellRenderer());
172
173                treeScrollPane = new JScrollPane(jtree);
174                treeScrollPane.setBorder(BorderFactory.createEmptyBorder());
175
176                treePanel.add(treeScrollPane);
177
178
179                normalWorkPanel = new JPanel();
180                normalWorkPanel.setLayout(new BorderLayout());
181                normalWorkPanel.setName("browser");
182
183                mainPanel = new JPanel();
184                mainPanel.setName("main");
185                mainPanelLayout = new CardLayout();
186                mainPanel.setLayout(mainPanelLayout);
187                mainPanel.add(normalWorkPanel, "browser");
188
189                menuBar = new JMenuBar();
190
191                fileMenu = menuBar.add(new JMenu("File"));
192                editMenu = menuBar.add(new JMenu("Edit"));
193                viewMenu = menuBar.add(new JMenu("View"));
194                windowMenu = menuBar.add(new JMenu("Window"));
195                helpMenu = menuBar.add(new JMenu("Help"));
196
197                contentPane.add(menuBar, BorderLayout.NORTH);
198                contentPane.add(mainPanel, BorderLayout.CENTER);
199
200                leftPanel = new JPanel();
201                leftPanel.setLayout(new BorderLayout());
202                //leftPanel.add(new ViewerTest(), BorderLayout.PAGE_START);
203                //        JPanel leftTopPanel = createLeftTopPanel();
204                //        if (leftTopPanel != null) {
205                //            leftPanel.add(leftTopPanel, BorderLayout.PAGE_START);
206                //        }
207                leftPanel.add(treePanel, BorderLayout.CENTER);
208                leftPanel.setBackground(Color.WHITE);
209                leftPanel.setForeground(Color.WHITE);
210
211                cardPanel = new JPanel();
212                cardPanel.setName("card");
213                JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, cardPanel);
214                split.setPreferredSize(browser.defaultFrameDimension);
215                split.setMaximumSize(screenDimension);
216                split.setOneTouchExpandable(true);
217                split.setDividerLocation(250);
218                split.setDividerSize(5);
219                split.setName("split");
220
221                normalWorkPanel.add(split);
222
223                //this.setVisible(true);
224                mainPanelLayout.show(mainPanel, "browser");
225
226                cardPanelLayout = new CardLayout();
227                cardPanel.setLayout(cardPanelLayout);
228
229                getSwing().pack();
230                jtree.requestFocusInWindow();
231
232                log.debug("frame configured: " + this);
233
234                new MenuConstructor(fileMenu).add(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK), new AbstractAction("Close") {
235                        @Override
236                        public void actionPerformed(ActionEvent actionEvent) {
237                                interrupt();
238                        }
239                });
240
241                new MenuConstructor(fileMenu).add(KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.CTRL_MASK), new AbstractAction("Reload current") {
242                        @Override
243                        public void actionPerformed(ActionEvent actionEvent) {
244
245                                loadPath(treeModel.convertToPath(jtree.getSelectionPath()), true);
246                        }
247                });
248
249        }
250
251        protected JPanel createLeftTopPanel() {
252                return null;
253        }
254
255        public void addRootPath(final Path path) {
256                assert isActive();
257
258                Tree tree = path.getTree();
259
260                log.info("trying mount: " + path);
261                if (!tree.getAssignedRoot().isResolved()) {
262                        tree.get(path, Mode.FETCH, new FutureHandler<Path>(this) {
263
264                                @Override
265                                protected void result(Path result) {
266                                        addRootPath(result);
267                                }
268                        });
269                        return;
270                }
271
272                assert browser.getTrees().contains(tree);
273
274                TreeAtFrame e = new TreeAtFrame(tree, this);
275                treeAtFrames.put(tree, e);
276
277                rootNode.getChildren().add(new TreeNode(tree.getAssignedRoot()));
278                e.rootNode = tree.getAssignedRoot();
279                treeModel.nodeStructureChanged(new TreePath(rootNode));
280                // jtree.expandPath(new TreePath(rootNode));
281        }
282
283
284        public void showPanel(Panel panel) {
285                assert isActive();
286                assert panel != null;
287                cardPanelLayout.show(cardPanel, panel.getUniqueName());
288        }
289
290
291        private void showPopup(MouseEvent e) {
292                assert isActive();
293                if (!e.isPopupTrigger()) {
294                        return;
295                }
296                TreePath treePath = jtree.getPathForLocation(e.getX(), e.getY());
297
298                Path path = treeModel.convertToPath(treePath);
299                treePopupMenu.removeAll();
300
301                for (PopupMenuEntryProvider provider : browser.popupMenuEntryProviders) {
302                        provider.provide(treePopupMenu, path);
303                }
304                treePopupMenu.show(e.getComponent(), e.getX(), e.getY());
305        }
306
307        public void clear() {
308                cardPanel.removeAll();
309                cardPanel.updateUI();
310                jtree.setEnabled(false);
311        }
312
313        public void loadChildren(Path path, boolean reload) {
314                if (path == null) {
315                        return;
316                }
317                AccessInterface access = TreeOperations.bindAccess(path);
318
319                int count = access.getCompositeParamCount();
320                for (int i = 0; i < count; ++i) {
321                        Path childPath = path.appendParam(access.getCompositeParam(i)).tryFindResolution();
322                        loadPath(childPath, reload);
323                }
324
325        }
326
327        public void loadPath(Path path, boolean reload) {
328                if (path == null) {
329                        return;
330                }
331                if (path.isResolved() && !reload) {
332                        return;
333                }
334                path.getTree().get(path, Mode.FETCH, new FutureHandler<Path>(this) {
335                        @Override
336                        protected void result(Path result) {
337                                final TreePath treePath = treeModel.convertToTreePath(result);
338
339                                treeModel.nodeStructureChanged(treePath);
340                                if (treePath.equals(jtree.getSelectionPath())) {
341                                        treeAtFrames.get(result.getTree()).useOrCreatePanel(treePath);
342                                }
343                        }
344                });
345        }
346
347        public void chooseTreeNode(final TreePath treePath) {
348                assert isActive();
349                if (treePath == null) {
350                        return;
351                }
352                if (treeModel.isChanging()) {
353                        return;
354                }
355
356                Path path = treeModel.convertToPath(treePath);
357                if (path == null) {
358                        return;
359                }
360                path = path.assureResolved();
361                final Tree tree = path.getTree();
362
363                treeAtFrames.get(tree).useOrCreatePanel(treePath);
364                loadChildren(path, false);
365
366        }
367
368
369        // public void goTo(Path path) {
370        //      assert isActive();
371        //      final TreePath treePath = treeModel.convertToTreePath(path);
372        //      log.info("go to path: " + path + "(" + treePath + ")");
373
374        //      this.dispatch(new RunAt<Frame>(this) {
375        //              @Override
376        //              protected void runAt() {
377        //                      log.info("executed");
378        //                      jtree.setSelectionPath(treePath);
379        //                      jtree.makeVisible(treePath);
380        //                      assert jtree.isVisible(treePath);
381        //              }
382        //      });
383
384        // }
385
386        @Override
387        public String toString() {
388                return title + "@" + browser.getName();
389        }
390
391        @Override
392        protected void joinableStart() {
393                super.joinableStart();
394                Dispatching.use(trees, this);
395        }
396
397        @Override
398        protected void joinableInterrupt() {
399                Dispatching.drop(trees, this);
400                super.joinableInterrupt();
401        }
402
403        @Override
404        protected void joinableFinish() {
405                super.joinableFinish();
406        }
407
408        @Override
409        protected void joinableJoin() throws InterruptedException {
410                Dispatching.join(trees);
411                super.joinableJoin();
412        }
413
414        @Override
415        public void childChangedState(Joinable joinable, JoinableState state) {
416                if (joinable == trees) {
417                        proceedToState(state);
418                }
419        }
420
421        /**
422         * @return the treeModel
423         */
424        public TreeModel getTreeModel() {
425                return treeModel;
426        }
427
428}
Note: See TracBrowser for help on using the repository browser.