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

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

HIGHLIGTS:

  • complete events implementation
  • add CLI in Java Framsticks server
  • add automatic registration for events in GUI
  • improve objects fetching (object are never overwritten with new instances)
  • properly react for ListChange? events
  • add ListPanel? with table view
    • columns to be shown may be statically specified in configuration
    • currently modyfying data through tables is not available
  • improve maven configuration
    • configuration file may be specified without touching pom.xml

CHANGELOG:
Extract constants from Flags into ParamFlags? and SetStateFlags?.

Extract flags I/O to FlagsUtils? class.

Configured maven to exec given resource configuration.

For example:
mvn exec:exec -Dframsticks.config=/configs/managed-console.xml

Cleanup pom.xml

Rename ObjectTree? to LocalTree? (also make LocalTree? and RemoteTree? final).

Minor change.

Add maximum number of columns in ListPanelProvider?.

Improve ColumnsConfig? interpretation.

Automatically fill FramsClass?.name if trying to construct empty.

Improve identitifer case mangling in XmlLoader?.

Introduce configurable ColumnsConfig?.

Draft working version of ListPanel?.

Table is being shown (although empty).

More improvements to table building.

Move some functionality from Frame to TreeModel?.

Move tree classes in gui to separate package.

Remove old table related classes.

Add draft implementation of TableModel?.

Redirect ParamBuilder?.forAccess to AccessInterface?.

Optimize ParamBuilder?.forAccess()

Do not clear list when loading.

Do not load fetched values directly.

Implement different AccessInterface? copying policy.

Optimize fetching values routine.

Remove Mode enum (work out get semantics).

Some improvements to ListChange? handling.

Improve UniqueListAccess?.

Add reaction for ListChanges? in the TreeNode?.

EventListeners? are being added in the TreeNode?.

Listeners for ListParams? are now very naive (they download
whole list).

Automatially register on events in GUI.

Events are working in RemoteTree? and Server.

Move listeners to the ClientSideManagedConnection?.

Remove old classes responsible for event subscriptions.

Improve event reading.

Improve events handling at server side.

Add register attribute in FramsClassAnnotation?
to automatically also register other classes.

Registering events works.

Setup for remote listeners registration.

More improvements.

Minor changes.

Add rootTree to the ClientAtServer?.

Moving CLI to the ClientAtServer?.

Fix bug: use Void.TYPE instead of Void.class

More development around CLI.

  • Improve Path resolving.

Add synthetic root to ObjectTree?.

It is needed to allow sybling for the original root
that would containg CLI.

Some work with registering events in RemoteTree?.

Draft implementation of listener registering in RemoteTree?.

Support events registration in the ObjectTree?.

Add events support to ReflectionAccess?.

EventParam? is recognized by ParamCandidate?.

Prepare interface for Events across project.

Add EventListener? and API for listeners in Tree.

File size: 10.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.log4j.Logger;
39
40import com.framsticks.core.Path;
41import com.framsticks.core.Tree;
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.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                                treeModel.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                                treeModel.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.debug("trying mount: " + path);
261                if (!tree.getAssignedRoot().isResolved()) {
262                        tree.get(path, 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(e, Path.to(tree, "/")));
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 updatePanelIfIsLeadSelection(TreePath treePath, Path path) {
314                assert isActive();
315                if (treePath.equals(jtree.getSelectionPath())) {
316                        treeAtFrames.get(path.getTree()).useOrCreatePanel(treePath);
317                }
318        }
319
320
321
322        // public void goTo(Path path) {
323        //      assert isActive();
324        //      final TreePath treePath = treeModel.convertToTreePath(path);
325        //      log.info("go to path: " + path + "(" + treePath + ")");
326
327        //      this.dispatch(new RunAt<Frame>(this) {
328        //              @Override
329        //              protected void runAt() {
330        //                      log.info("executed");
331        //                      jtree.setSelectionPath(treePath);
332        //                      jtree.makeVisible(treePath);
333        //                      assert jtree.isVisible(treePath);
334        //              }
335        //      });
336
337        // }
338
339        @Override
340        public String toString() {
341                return title + "@" + browser.getName();
342        }
343
344        @Override
345        protected void joinableStart() {
346                super.joinableStart();
347                Dispatching.use(trees, this);
348        }
349
350        @Override
351        protected void joinableInterrupt() {
352                Dispatching.drop(trees, this);
353                super.joinableInterrupt();
354        }
355
356        @Override
357        protected void joinableFinish() {
358                super.joinableFinish();
359        }
360
361        @Override
362        protected void joinableJoin() throws InterruptedException {
363                Dispatching.join(trees);
364                super.joinableJoin();
365        }
366
367        @Override
368        public void childChangedState(Joinable joinable, JoinableState state) {
369                if (joinable == trees) {
370                        proceedToState(state);
371                }
372        }
373
374        /**
375         * @return the jtree
376         */
377        public JTree getJtree() {
378                return jtree;
379        }
380
381        /**
382         * @return the treeModel
383         */
384        public TreeModel getTreeModel() {
385                return treeModel;
386        }
387
388        /**
389         * @return the rootNode
390         */
391        public MetaNode getRootNode() {
392                return rootNode;
393        }
394
395        /**
396         * @return the treeAtFrames
397         */
398        public Map<Tree, TreeAtFrame> getTreeAtFrames() {
399                return treeAtFrames;
400        }
401
402}
Note: See TracBrowser for help on using the repository browser.