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

Last change on this file since 193 was 193, checked in by Maciej Komosinski, 10 years ago

Set svn:eol-style native for all textual files

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