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

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

HIGHLIGHTS:

for Joinables running

CHANGELOG:
Add WorkPackageLogic? and classes representing prime experiment state.

Add classes for PrimeExperiment? state.

Extract single netload routine in Simulator.

Working netload with dummy content in PrimeExperiment?.

More development with NetLoadSaveLogic? and PrimeExperiment?.

Improvement around prime.

Improve BufferedDispatcher?.isActive logic.

Add prime-all.xml configuration.

Manual connecting to existing simulators from GUI.

Guard in SimulatorConnector? against expdef mismatch.

Guard against empty target dispatcher in BufferedDispatcher?.

Make BufferedDispatcher? a Dispatcher (and Joinable).

Minor improvements.

Done StackedJoinable?, improve Experiment.

Develop StackedJoinable?.

Add StackedJoinable? utility joinables controller.

Add dependency on apache-commons-lang.

Add ready ListChange? on Simulators.

Improve hints in ListChange?.

Several improvements.

Found bug with dispatching in Experiment.

Minor improvements.

Fix bug with early finishing Server.

Many changes in Dispatching.

Fix bug with connection.

Do not obfuscate log with socket related exceptions.

Add SocketClosedException?.

Add SimulatorConnector?.

Work out conception of experiment composing of logics building blocks.

Rename SinkInterface? to Sink.

Move saving of Accesses into AccessOperations?.

Some improvements to Experiment.

Improve joinables.

Fix issue with joinables closing.

Add direct and managed consoles to popup menu.

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.core.Path;
42import com.framsticks.core.Tree;
43import com.framsticks.gui.tree.AbstractNode;
44import com.framsticks.gui.tree.MetaNode;
45import com.framsticks.gui.tree.TreeCellRenderer;
46import com.framsticks.gui.tree.TreeModel;
47import com.framsticks.gui.tree.TreeNode;
48import com.framsticks.util.dispatching.Dispatching;
49import com.framsticks.util.dispatching.FutureHandler;
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 FutureHandler<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, true);
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.