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

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

HIGHLIGHTS:

  • upgrade to Java 7
    • use try-multi-catch clauses
    • use try-with-resources were appropriate
  • configure FindBugs? (use mvn site and then navigate in browser to the report)
    • remove most bugs found
  • parametrize Dispatching environment (Dispatcher, RunAt?) to enforce more control on the place of closures actual call

CHANGELOG:
Rework FavouritesXMLFactory.

FindBugs?. Thread start.

FindBugs?. Minor change.

FindBugs?. Iterate over entrySet.

FindBugs?. Various.

FindBug?.

FindBug?. Encoding.

FindBug?. Final fields.

FindBug?.

Remove synchronization bug in ClientConnection?.

Experiments with findbugs.

Finish parametrization.

Make RunAt? an abstract class.

More changes in parametrization.

More changes in parametrizing dispatching.

Several changes to parametrize tasks.

Rename Runnable to RunAt?.

Add specific framsticks Runnable.

Add JSR305 (annotations).

Add findbugs reporting.

More improvements to ParamBuilder? wording.

Make FramsClass? accept also ParamBuilder?.

Change wording of ParamBuilder?.

Change wording of Request creation.

Use Java 7 exception catch syntax.

Add ScopeEnd? class.

Upgrade to Java 7.

File size: 11.3 KB
Line 
1package com.framsticks.gui;
2
3import com.framsticks.core.Instance;
4import com.framsticks.core.Path;
5import com.framsticks.gui.view.*;
6import com.framsticks.gui.view.TreeCellRenderer;
7import com.framsticks.util.dispatching.Dispatcher;
8import com.framsticks.util.lang.ScopeEnd;
9import com.framsticks.util.swing.KeyboardModifier;
10import org.apache.log4j.Logger;
11
12import javax.swing.*;
13import javax.swing.event.TreeModelEvent;
14import javax.swing.event.TreeModelListener;
15import javax.swing.event.TreeSelectionEvent;
16import javax.swing.event.TreeSelectionListener;
17import javax.swing.tree.*;
18
19import java.awt.*;
20import java.awt.datatransfer.StringSelection;
21import java.awt.event.*;
22import java.util.HashMap;
23import java.util.Map;
24import com.framsticks.util.dispatching.RunAt;
25
26/**
27 * @author Piotr Sniegowski
28 */
29@SuppressWarnings("serial")
30public class Frame extends JFrame implements Dispatcher<Frame> {
31
32        private static final Logger log = Logger.getLogger(Frame.class.getName());
33
34        protected final Browser browser;
35
36        protected final Dimension screenDimension = Toolkit.getDefaultToolkit()
37                        .getScreenSize();
38
39        final protected CardLayout cardPanelLayout = new CardLayout();
40        protected final JPanel cardPanel = new JPanel();
41
42        protected JScrollPane treeScrollPane;
43        protected JTree tree;
44        protected DefaultTreeModel treeModel;
45        protected javax.swing.tree.MutableTreeNode rootNode;
46        //final Instance instance;
47        protected JPanel treePanel;
48        protected JPopupMenu treePopupMenu;
49        protected JMenuItem treePopupMenuHeader;
50
51        TreeNode currentlyPoppedTreeNode;
52        protected JLabel statusBar;
53        protected JPanel mainPanel;
54        protected JPanel leftPanel;
55        protected JPanel normalWorkPanel;
56        protected CardLayout mainPanelLayout;
57
58        protected JMenuBar menuBar;
59        protected JMenu fileMenu;
60        protected JMenu editMenu;
61        protected JMenu viewMenu;
62        protected JMenu windowMenu;
63        protected JMenu helpMenu;
64
65        protected final Map<BrowserEndpoint, EndpointAtFrame> endpoints = new HashMap<BrowserEndpoint, EndpointAtFrame>();
66        protected final Map<Instance, EndpointAtFrame> endpointsByInstance = new HashMap<Instance, EndpointAtFrame>();
67
68        public Frame(String title, Browser browser) {
69                super(title);
70                /** this is done to remove the current value label from above the slider,
71                 * because it cannot put to work properly with floating-point value sliders,
72                 * nor it can be removed in normal way through JSlider methods  */
73                UIManager.put("Slider.paintValue", false);
74                this.browser = browser;
75                log.debug("creating " + this);
76        }
77
78        public void configure() {
79
80                Container contentPane = this.getContentPane();
81                contentPane.setLayout(new BorderLayout());
82
83                treePopupMenu = new JPopupMenu("title");
84                treePopupMenu.setName("popup");
85                treePopupMenuHeader = new JMenuItem();
86                treePopupMenuHeader.setForeground(Color.BLUE);
87                treePopupMenu.add(treePopupMenuHeader);
88                treePopupMenu.addSeparator();
89                //TODO: add to favourites
90                //TODO: remove from favourites
91                //TODO: open in new window as root
92                //TODO: refresh
93                //TODO: open in console
94
95                treePopupMenu.add(new JMenuItem("Refresh"));
96                treePopupMenu.add(new JMenuItem("Open in new frame as root"));
97                addNodeActionToTreePopupMenu("Copy path to clipboard",
98                                new NodeAction() {
99                                        @Override
100                                        public void actionPerformed(TreeNode treeNode) {
101                                                Path path = treeNode.getInstancePath();
102                                                StringSelection selection = new StringSelection(path
103                                                                .toString());
104                                                getToolkit().getSystemClipboard().setContents(
105                                                                selection, selection);
106                                        }
107                                });
108                //this.add(createMenuItem("Add to favourites", null));
109                //this.add(createMenuItem("Remove from favourites", null));
110
111                treePanel = new JPanel();
112                treePanel.setLayout(new BorderLayout());
113
114                treeModel = new DefaultTreeModel(null);
115                treeModel.addTreeModelListener(new TreeModelListener() {
116
117                        @Override
118                        public void treeNodesChanged(TreeModelEvent arg0) {
119                                log.trace("treeNodesChanged: " + arg0);
120                        }
121
122                        @Override
123                        public void treeNodesInserted(TreeModelEvent arg0) {
124                                // log.trace("treeNodesInserted: " + arg0);
125                        }
126
127                        @Override
128                        public void treeNodesRemoved(TreeModelEvent arg0) {
129                                log.trace("treeNodesRemoved: " + arg0);
130                        }
131
132                        @Override
133                        public void treeStructureChanged(TreeModelEvent arg0) {
134                                log.trace("treeStructureChanged: " + arg0);
135                        }
136                });
137
138                tree = new JTree(treeModel);
139                tree.setName("tree");
140                tree.setRootVisible(false);
141                tree.setExpandsSelectedPaths(true);
142                tree.setSelectionModel(new DefaultTreeSelectionModel());
143                ToolTipManager.sharedInstance().registerComponent(tree);
144
145                tree.addTreeSelectionListener(new TreeSelectionListener() {
146                        @Override
147                        public void valueChanged(TreeSelectionEvent e) {
148                                chooseTreeNode(e.getNewLeadSelectionPath());
149                        }
150                });
151
152                tree.setExpandsSelectedPaths(true);
153                tree.setEditable(false);
154                tree.setDoubleBuffered(true);
155                tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
156                tree.setShowsRootHandles(true);
157                tree.setRowHeight(26);
158                tree.setDoubleBuffered(true);
159                tree.addMouseListener(new MouseAdapter() {
160                        @Override
161                        public void mousePressed(MouseEvent e) {
162                                assert isActive();
163                                showPopup(e);
164                        }
165
166                        @Override
167                        public void mouseReleased(MouseEvent e) {
168                                assert isActive();
169                                showPopup(e);
170                        }
171                });
172
173                new KeyboardModifier(tree, JComponent.WHEN_FOCUSED)
174                        .join(KeyStroke.getKeyStroke('h'), KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0))
175                        .join(KeyStroke.getKeyStroke('j'), KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0))
176                        .join(KeyStroke.getKeyStroke('k'), KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0))
177                        .join(KeyStroke.getKeyStroke('l'), KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0))
178                        ;
179
180                tree.setCellRenderer(new TreeCellRenderer());
181
182                treeScrollPane = new JScrollPane(tree);
183                treeScrollPane.setBorder(BorderFactory.createEmptyBorder());
184
185                treePanel.add(treeScrollPane);
186
187                rootNode = new DefaultMutableTreeNode();
188                rootNode.setUserObject("root");
189                treeModel.setRoot(rootNode);
190
191                normalWorkPanel = new JPanel();
192                normalWorkPanel.setLayout(new BorderLayout());
193                normalWorkPanel.setName("browser");
194
195                mainPanel = new JPanel();
196                mainPanel.setName("main");
197                mainPanelLayout = new CardLayout();
198                mainPanel.setLayout(mainPanelLayout);
199                mainPanel.add(normalWorkPanel, "browser");
200
201                menuBar = new JMenuBar();
202
203                fileMenu = menuBar.add(new JMenu("File"));
204                editMenu = menuBar.add(new JMenu("Edit"));
205                viewMenu = menuBar.add(new JMenu("View"));
206                windowMenu = menuBar.add(new JMenu("Window"));
207                helpMenu = menuBar.add(new JMenu("Help"));
208
209                contentPane.add(menuBar, BorderLayout.NORTH);
210                contentPane.add(mainPanel, BorderLayout.CENTER);
211                contentPane.add(statusBar, BorderLayout.SOUTH);
212
213                leftPanel = new JPanel();
214                leftPanel.setLayout(new BorderLayout());
215                //leftPanel.add(new ViewerTest(), BorderLayout.PAGE_START);
216//        JPanel leftTopPanel = createLeftTopPanel();
217//        if (leftTopPanel != null) {
218//            leftPanel.add(leftTopPanel, BorderLayout.PAGE_START);
219//        }
220                leftPanel.add(treePanel, BorderLayout.CENTER);
221                leftPanel.setBackground(Color.WHITE);
222                leftPanel.setForeground(Color.WHITE);
223
224                cardPanel.setName("card");
225                JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, cardPanel);
226                split.setPreferredSize(browser.defaultFrameDimension);
227                split.setMaximumSize(screenDimension);
228                split.setOneTouchExpandable(true);
229                split.setDividerLocation(250);
230                split.setDividerSize(5);
231                split.setName("split");
232
233                normalWorkPanel.add(split);
234
235                //this.setVisible(true);
236                mainPanelLayout.show(mainPanel, "browser");
237
238                cardPanel.setLayout(cardPanelLayout);
239
240                this.pack();
241                tree.requestFocusInWindow();
242
243                log.debug("frame configured");
244
245        }
246
247        protected JPanel createLeftTopPanel() {
248                return null;
249        }
250
251        public void addRootPath(BrowserEndpoint endpoint, Path path) {
252                assert isActive();
253                assert !endpoints.containsKey(endpoint);
254
255                EndpointAtFrame e = new EndpointAtFrame(endpoint, this);
256                endpoint.getInstance().addListener(e);
257                endpoints.put(endpoint, e);
258                endpointsByInstance.put(endpoint.getInstance(), e);
259                TreeNode node = new TreeNode(e, path);
260                e.rootTreeNode = node;
261                treeModel.insertNodeInto(node, rootNode, rootNode.getChildCount());
262                tree.expandPath(new TreePath(rootNode));
263        }
264
265        @Override
266        public boolean isActive() {
267                return SwingDispatcher.instance.isActive();
268        }
269
270        @Override
271        public void invokeLater(RunAt<? extends Frame> runnable) {
272                SwingDispatcher.getInstance().invokeLater(runnable);
273        }
274
275        public Action addActionToTreePopupMenu(Action action) {
276                assert isActive();
277                treePopupMenu.add(action);
278                return action;
279        }
280
281        public Action addNodeActionToTreePopupMenu(String title, final NodeAction nodeAction) {
282                assert isActive();
283                return addActionToTreePopupMenu(new AbstractAction(title) {
284                        @Override
285                        public void actionPerformed(ActionEvent e) {
286                                TreeNode treeNode = getCurrentlyPoppedTreeNode();
287                                if (treeNode == null) {
288                                        return;
289                                }
290                                nodeAction.actionPerformed(treeNode);
291                        }
292                });
293        }
294
295        public void showPanel(Panel panel) {
296                assert isActive();
297                assert panel != null;
298                cardPanelLayout.show(cardPanel, panel.getUniqueName());
299        }
300
301
302        private void showPopup(MouseEvent e) {
303                assert isActive();
304                if (!e.isPopupTrigger()) {
305                        return;
306                }
307                currentlyPoppedTreeNode = findTreeNodeByTreePath(tree.getPathForLocation(e.getX(), e.getY()));
308                if (currentlyPoppedTreeNode == null) {
309                        return;
310                }
311                treePopupMenu.show(e.getComponent(), e.getX(), e.getY());
312                //currentlyPoppedPanel.getNode().getFramsClass().getName()
313                //treePopupMenuHeader.setText(currentlyPoppedTreeNode.getNode().getPath());
314        }
315
316        public TreeNode getCurrentlyPoppedTreeNode() {
317                assert isActive();
318                return currentlyPoppedTreeNode;
319        }
320
321
322        public void clear() {
323                treeModel.setRoot(null);
324                cardPanel.removeAll();
325                cardPanel.updateUI();
326                tree.setEnabled(false);
327        }
328
329        public ScopeEnd startChange(final DefaultMutableTreeNode node) {
330                assert isActive();
331                final TreePath selection = tree.getSelectionPath();
332                return new ScopeEnd() {
333                        @Override
334                        public void close() {
335                                assert isActive();
336                                treeModel.nodeChanged(node);
337                                tree.setSelectionPath(selection);
338                        }
339                };
340        }
341
342        public void selectTreeNode(final TreeNode treeNode) {
343                assert isActive();
344/*              final Panel panel = treeNode.getOrCreatePanel();
345                if (panel == null) {
346                        return;
347                }
348                panel.setCurrentTreeNode(treeNode);
349                treeNode.updateData();
350                showPanel(panel);*/
351        }
352
353        public TreeNode findTreeNodeByTreePath(TreePath treePath) {
354                assert isActive();
355                if (treePath == null) {
356                        return null;
357                }
358                if (!(treePath.getLastPathComponent() instanceof TreeNode)) {
359                        return null;
360                }
361                return (TreeNode)treePath.getLastPathComponent();
362        }
363
364        public void chooseTreeNode(TreePath treePath) {
365                assert isActive();
366                final TreeNode treeNode = findTreeNodeByTreePath(treePath);
367                if (treeNode == null) {
368                        return;
369                }
370                treeNode.select();
371        }
372
373        public void goTo(Path path) {
374                assert isActive();
375                final TreePath treePath = endpointsByInstance.get(path.getInstance()).getTreePath(path, false);
376                log.info("go to path: " + path + "(" + treePath + ")");
377
378                new RunAt<Frame>(this) {
379                        @Override
380                        public void run() {
381                                log.info("executed");
382                                tree.setSelectionPath(treePath);
383                                tree.makeVisible(treePath);
384                                assert tree.isVisible(treePath);
385                        }
386                };
387
388        }
389
390
391        public void addNode(TreeNode child, DefaultMutableTreeNode parent) {
392                assert isActive();
393
394                try (ScopeEnd e = startChange(parent)) {
395                        treeModel.insertNodeInto(child, parent, parent.getChildCount());
396                }
397        }
398
399        @Override
400        public String toString() {
401                return getTitle() + "@" + browser.getName();
402        }
403
404}
Note: See TracBrowser for help on using the repository browser.