Ignore:
Timestamp:
07/06/13 03:51:11 (11 years ago)
Author:
psniegowski
Message:

HIGHLIGHTS:

  • add proper exception passing between communication sides:

if exception occur during handling client request, it is
automatically passed as comment to error response.

it may be used to snoop communication between peers

  • fix algorithm choosing text controls in GUI
  • allow GUI testing in virtual frame buffer (xvfb)

FEST had some problem with xvfb but workaround was found

supports tab-completion based on requests history

CHANGELOG:
Further improve handling of exceptions in GUI.

Add StatusBar? implementing ExceptionResultHandler?.

Make completion processing asynchronous.

Minor changes.

Improve completion in console.

Improve history in InteractiveConsole?.

First working version of DirectConsole?.

Minor changes.

Make Connection.address non final.

It is more suitable to use in configuration.

Improvement of consoles.

Improve PopupMenu? and closing of FrameJoinable?.

Fix BrowserTest?.

Found bug with FEST running under xvfb.

JButtonFixture.click() is not working under xvfb.
GuiTest? has wrapper which uses JButton.doClick() directly.

Store CompositeParam? param in TreeNode?.

Simplify ClientSideManagedConnection? connecting.

There is now connectedFunctor needed, ApplicationRequests? can be
send right after creation. They are buffered until the version
and features are negotiated.

Narow down interface of ClientSideManagedConnection?.

Allow that connection specialization send only
ApplicationRequests?.

Improve policy of text control choosing.

Change name of Genotype in BrowserTest?.

Make BrowserTest? change name of Genotype.

Minor change.

First working draft of TrackConsole?.

Simplify Consoles.

More improvements with gui joinables.

Unify initialization on gui joinables.

More rework of Frame based entities.

Refactorize structure of JFrames based entities.

Extract GuiTest? from BrowserBaseTest?.

Reorganize Console classes structure.

Add Collection view to JoinableCollection?.

Configure timeout in testing.

Minor changes.

Rework connections hierarchy.

Add Mode to the get operation.

Make get and set in Tree take PrimitiveParam?.

Unify naming of operations.

Make RunAt? use the given ExceptionHandler?.

It wraps the virtual runAt() method call with
try-catch passing exception to handler.

Force RunAt? to include ExceptionHandler?.

Improve ClientAtServer?.

Minor change.

Another sweep with FindBugs?.

Rename Instance to Tree.

Minor changes.

Minor changes.

Further clarify semantics of Futures.

Add FutureHandler?.

FutureHandler? is refinement of Future, that proxifies
exception handling to ExceptionResultHandler? given
at construction time.

Remove StateFunctor? (use Future<Void> instead).

Make Connection use Future<Void>.

Unparametrize *ResponseFuture?.

Remove StateCallback? not needed anymore.

Distinguish between sides of ResponseFuture?.

Base ResponseCallback? on Future (now ResponseFuture?).

Make asynchronous store taking Future for flags.

Implement storeValue in ObjectInstance?.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • java/main/src/main/java/com/framsticks/gui/Frame.java

    r96 r97  
    11package com.framsticks.gui;
    22
    3 import com.framsticks.core.Instance;
    4 import com.framsticks.core.Path;
    5 import com.framsticks.gui.view.*;
    6 import com.framsticks.gui.view.TreeCellRenderer;
    7 import com.framsticks.util.dispatching.Dispatcher;
    8 import com.framsticks.util.dispatching.JoinableCollection;
    9 import com.framsticks.util.lang.ScopeEnd;
    10 import com.framsticks.util.swing.KeyboardModifier;
    11 import com.framsticks.util.swing.MenuConstructor;
    12 
    13 import org.apache.log4j.Logger;
    14 
    15 import javax.swing.*;
     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.HashMap;
     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;
    1630import javax.swing.event.TreeModelEvent;
    1731import javax.swing.event.TreeModelListener;
    1832import javax.swing.event.TreeSelectionEvent;
    1933import javax.swing.event.TreeSelectionListener;
    20 import javax.swing.tree.*;
    21 
    22 import java.awt.*;
    23 import java.awt.datatransfer.StringSelection;
    24 import java.awt.event.*;
    25 import java.util.HashMap;
    26 import java.util.Map;
     34import javax.swing.tree.DefaultMutableTreeNode;
     35import javax.swing.tree.DefaultTreeModel;
     36import javax.swing.tree.DefaultTreeSelectionModel;
     37import javax.swing.tree.TreePath;
     38import javax.swing.tree.TreeSelectionModel;
     39
     40import org.apache.log4j.Logger;
     41
     42import com.framsticks.core.Path;
     43import com.framsticks.core.Tree;
     44import com.framsticks.gui.view.TreeCellRenderer;
     45import com.framsticks.util.FramsticksException;
     46import com.framsticks.util.dispatching.Dispatching;
     47import com.framsticks.util.dispatching.ExceptionResultHandler;
     48import com.framsticks.util.dispatching.Joinable;
     49import com.framsticks.util.dispatching.JoinableCollection;
     50import com.framsticks.util.dispatching.JoinableParent;
     51import com.framsticks.util.dispatching.JoinableState;
    2752import com.framsticks.util.dispatching.RunAt;
     53import com.framsticks.util.lang.ScopeEnd;
     54import com.framsticks.util.swing.KeyboardModifier;
     55import com.framsticks.util.swing.MenuConstructor;
    2856
    2957/**
     
    3159 */
    3260@SuppressWarnings("serial")
    33 public class Frame extends JoinableCollection<Instance> implements Dispatcher<Frame> {
     61public class Frame extends FrameJoinable implements JoinableParent {
    3462
    3563        private static final Logger log = Logger.getLogger(Frame.class.getName());
     
    4270        protected JPanel cardPanel;
    4371
    44         protected final String title;
    45         protected JFrame swing;
    4672        protected JScrollPane treeScrollPane;
    47         protected JTree tree;
     73        protected JTree jtree;
    4874        protected DefaultTreeModel treeModel;
    4975        protected javax.swing.tree.MutableTreeNode rootNode;
    50         //final Instance instance;
    5176        protected JPanel treePanel;
    5277        protected JPopupMenu treePopupMenu;
     
    5479
    5580        TreeNode currentlyPoppedTreeNode;
    56         protected JLabel statusBar;
    5781        protected JPanel mainPanel;
    5882        protected JPanel leftPanel;
     
    6791        protected JMenu helpMenu;
    6892
    69         protected final Map<Instance, InstanceAtFrame> instancesAtFrames = new HashMap<Instance, InstanceAtFrame>();
    70 
    71         public Frame(String title, Browser browser) {
    72                 this.title = title;
     93        protected final Map<Tree, TreeAtFrame> treeAtFrames = new HashMap<Tree, TreeAtFrame>();
     94        protected JoinableCollection<Tree> trees = new JoinableCollection<Tree>();
     95
     96        public Frame(Browser browser) {
    7397                this.browser = browser;
    7498        }
    7599
    76         public void configure() {
    77                 swing = new JFrame(title);
    78                 swing.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    79                 swing.addWindowListener(new WindowAdapter() {
    80                         @Override
    81                         public void windowClosing(WindowEvent e) {
    82                                 log.info("received closing");
    83                                 interrupt();
    84                         }
    85                 });
     100        protected void initializeGui() {
     101                super.initializeGui();
    86102                /** this is done to remove the current value label from above the slider,
    87103                 * because it cannot put to work properly with floating-point value sliders,
     
    90106                log.debug("creating " + this);
    91107
    92                 statusBar = new JLabel("not connected");
    93 
    94                 Container contentPane = swing.getContentPane();
    95                 contentPane.setLayout(new BorderLayout());
    96 
     108
     109                Container contentPane = getSwing().getContentPane();
    97110                treePopupMenu = new JPopupMenu("title");
    98111                treePopupMenu.setName("popup");
    99                 treePopupMenuHeader = new JMenuItem();
    100                 treePopupMenuHeader.setForeground(Color.BLUE);
    101                 treePopupMenu.add(treePopupMenuHeader);
    102                 treePopupMenu.addSeparator();
    103                 //TODO: add to favourites
    104                 //TODO: remove from favourites
    105                 //TODO: open in new window as root
    106                 //TODO: refresh
    107                 //TODO: open in console
    108 
    109                 treePopupMenu.add(new JMenuItem("Refresh"));
    110                 treePopupMenu.add(new JMenuItem("Open in new frame as root"));
    111                 addNodeActionToTreePopupMenu("Copy path to clipboard", new NodeAction() {
    112                         @Override
    113                         public void actionPerformed(TreeNode treeNode) {
    114                                 Path path = treeNode.getInstancePath();
    115                                 StringSelection selection = new StringSelection(path.toString());
    116                                 swing.getToolkit().getSystemClipboard().setContents(selection, selection);
    117                         }
    118                 });
    119                 //this.add(createMenuItem("Add to favourites", null));
    120                 //this.add(createMenuItem("Remove from favourites", null));
    121112
    122113                treePanel = new JPanel();
     
    147138                });
    148139
    149                 tree = new JTree(treeModel);
    150                 tree.setName("tree");
    151                 tree.setRootVisible(false);
    152                 tree.setExpandsSelectedPaths(true);
    153                 tree.setSelectionModel(new DefaultTreeSelectionModel());
    154                 ToolTipManager.sharedInstance().registerComponent(tree);
    155 
    156                 tree.addTreeSelectionListener(new TreeSelectionListener() {
     140                jtree = new JTree(treeModel);
     141                jtree.setName("tree");
     142                jtree.setRootVisible(false);
     143                jtree.setExpandsSelectedPaths(true);
     144                jtree.setSelectionModel(new DefaultTreeSelectionModel());
     145                ToolTipManager.sharedInstance().registerComponent(jtree);
     146
     147                jtree.addTreeSelectionListener(new TreeSelectionListener() {
    157148                        @Override
    158149                        public void valueChanged(TreeSelectionEvent e) {
     
    161152                });
    162153
    163                 tree.setExpandsSelectedPaths(true);
    164                 tree.setEditable(false);
    165                 tree.setDoubleBuffered(true);
    166                 tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    167                 tree.setShowsRootHandles(true);
    168                 tree.setRowHeight(26);
    169                 tree.setDoubleBuffered(true);
    170                 tree.addMouseListener(new MouseAdapter() {
     154                jtree.setExpandsSelectedPaths(true);
     155                jtree.setEditable(false);
     156                jtree.setDoubleBuffered(true);
     157                jtree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
     158                jtree.setShowsRootHandles(true);
     159                jtree.setRowHeight(26);
     160                jtree.setDoubleBuffered(true);
     161                jtree.addMouseListener(new MouseAdapter() {
    171162                        @Override
    172163                        public void mousePressed(MouseEvent e) {
     
    182173                });
    183174
    184                 new KeyboardModifier(tree, JComponent.WHEN_FOCUSED).join(KeyStroke.getKeyStroke('h'), KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)).join(KeyStroke.getKeyStroke('j'), KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)).join(KeyStroke.getKeyStroke('k'), KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)).join(KeyStroke.getKeyStroke('l'), KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));
    185 
    186                 tree.setCellRenderer(new TreeCellRenderer());
    187 
    188                 treeScrollPane = new JScrollPane(tree);
     175                new KeyboardModifier(jtree, JComponent.WHEN_FOCUSED).join(KeyStroke.getKeyStroke('h'), KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)).join(KeyStroke.getKeyStroke('j'), KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)).join(KeyStroke.getKeyStroke('k'), KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)).join(KeyStroke.getKeyStroke('l'), KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));
     176
     177                jtree.setCellRenderer(new TreeCellRenderer());
     178
     179                treeScrollPane = new JScrollPane(jtree);
    189180                treeScrollPane.setBorder(BorderFactory.createEmptyBorder());
    190181
     
    215206                contentPane.add(menuBar, BorderLayout.NORTH);
    216207                contentPane.add(mainPanel, BorderLayout.CENTER);
    217                 contentPane.add(statusBar, BorderLayout.SOUTH);
    218208
    219209                leftPanel = new JPanel();
     
    246236                cardPanel.setLayout(cardPanelLayout);
    247237
    248                 swing.pack();
    249                 tree.requestFocusInWindow();
     238                getSwing().pack();
     239                jtree.requestFocusInWindow();
    250240
    251241                log.debug("frame configured: " + this);
     
    266256        public void addRootPath(Path path) {
    267257                assert isActive();
    268                 Instance instance = path.getInstance();
    269                 assert browser.getInstances().contains(instance);
    270 
    271                 InstanceAtFrame e = new InstanceAtFrame(instance, this);
    272                 instance.addListener(e);
    273                 instancesAtFrames.put(instance, e);
     258                Tree tree = path.getTree();
     259                assert browser.getTrees().contains(tree);
     260
     261                TreeAtFrame e = new TreeAtFrame(tree, this);
     262                tree.addListener(e);
     263                treeAtFrames.put(tree, e);
    274264                TreeNode node = new TreeNode(e, path);
    275265                e.rootTreeNode = node;
    276266                treeModel.insertNodeInto(node, rootNode, rootNode.getChildCount());
    277                 tree.expandPath(new TreePath(rootNode));
    278         }
    279 
    280         @Override
    281         public boolean isActive() {
    282                 return SwingDispatcher.instance.isActive();
    283         }
    284 
    285         @Override
    286         public void dispatch(RunAt<? extends Frame> runnable) {
    287                 SwingDispatcher.getInstance().dispatch(runnable);
    288         }
    289 
    290         public Action addActionToTreePopupMenu(Action action) {
    291                 assert isActive();
    292                 treePopupMenu.add(action);
    293                 return action;
    294         }
    295 
    296         public Action addNodeActionToTreePopupMenu(String title, final NodeAction nodeAction) {
    297                 assert isActive();
    298                 return addActionToTreePopupMenu(new AbstractAction(title) {
    299                         @Override
    300                         public void actionPerformed(ActionEvent e) {
    301                                 TreeNode treeNode = getCurrentlyPoppedTreeNode();
    302                                 if (treeNode == null) {
    303                                         return;
    304                                 }
    305                                 nodeAction.actionPerformed(treeNode);
    306                         }
    307                 });
    308         }
     267                jtree.expandPath(new TreePath(rootNode));
     268        }
     269
    309270
    310271        public void showPanel(Panel panel) {
     
    319280                        return;
    320281                }
    321                 currentlyPoppedTreeNode = findTreeNodeByTreePath(tree.getPathForLocation(e.getX(), e.getY()));
     282                currentlyPoppedTreeNode = findTreeNodeByTreePath(jtree.getPathForLocation(e.getX(), e.getY()));
    322283                if (currentlyPoppedTreeNode == null) {
    323284                        return;
    324285                }
     286
     287                Path path = currentlyPoppedTreeNode.getTreePath();
     288                treePopupMenu.removeAll();
     289
     290                for (PopupMenuEntryProvider provider : browser.popupMenuEntryProviders) {
     291                        provider.provide(treePopupMenu, path);
     292                }
     293                // treePopupMenuHeader.setText(path.getTree().getName() + path.getTextual());
    325294                treePopupMenu.show(e.getComponent(), e.getX(), e.getY());
    326295                //currentlyPoppedPanel.getNode().getFramsClass().getName()
    327                 //treePopupMenuHeader.setText(currentlyPoppedTreeNode.getNode().getPath());
    328         }
    329 
    330         /**
    331          * @return the swing
    332          */
    333         public JFrame getSwing() {
    334                 return swing;
    335296        }
    336297
     
    344305                cardPanel.removeAll();
    345306                cardPanel.updateUI();
    346                 tree.setEnabled(false);
     307                jtree.setEnabled(false);
    347308        }
    348309
    349310        public ScopeEnd startChange(final DefaultMutableTreeNode node) {
    350311                assert isActive();
    351                 final TreePath selection = tree.getSelectionPath();
     312                final TreePath selection = jtree.getSelectionPath();
    352313                return new ScopeEnd() {
    353314                        @Override
     
    355316                                assert isActive();
    356317                                treeModel.nodeChanged(node);
    357                                 tree.setSelectionPath(selection);
     318                                jtree.setSelectionPath(selection);
    358319                        }
    359320                };
     
    391352        }
    392353
     354        protected final ExceptionResultHandler dialogHandler = new ExceptionResultHandler() {
     355
     356                @Override
     357                public void handle(FramsticksException exception) {
     358                        //TODO TEH
     359                        throw exception;
     360
     361                }
     362        };
     363
    393364        public void goTo(Path path) {
    394365                assert isActive();
    395                 final TreePath treePath = instancesAtFrames.get(path.getInstance()).getTreePath(path, false);
     366                final TreePath treePath = treeAtFrames.get(path.getTree()).getTreePath(path, false);
    396367                log.info("go to path: " + path + "(" + treePath + ")");
    397368
    398                 new RunAt<Frame>(this) {
    399                         @Override
    400                         public void run() {
     369                this.dispatch(new RunAt<Frame>(dialogHandler) {
     370                        @Override
     371                        protected void runAt() {
    401372                                log.info("executed");
    402                                 tree.setSelectionPath(treePath);
    403                                 tree.makeVisible(treePath);
    404                                 assert tree.isVisible(treePath);
    405                         }
    406                 };
     373                                jtree.setSelectionPath(treePath);
     374                                jtree.makeVisible(treePath);
     375                                assert jtree.isVisible(treePath);
     376                        }
     377                });
    407378
    408379        }
     
    422393
    423394        @Override
     395        protected void joinableStart() {
     396                super.joinableStart();
     397                Dispatching.use(trees, this);
     398        }
     399
     400        @Override
    424401        protected void joinableInterrupt() {
    425                 assert isActive();
     402                Dispatching.drop(trees, this);
    426403                super.joinableInterrupt();
    427 
    428                 dispatch(new RunAt<Frame>() {
    429                         @Override
    430                         public void run() {
    431                                 finish();
    432                         }
    433                 });
    434404        }
    435405
    436406        @Override
    437407        protected void joinableFinish() {
    438                 assert isActive();
    439                 log.debug("disposing frame " + this);
    440                 swing.dispose();
    441         }
    442 
    443         // @Override
    444         // public boolean isDone() {
    445         //      return super.isDone() && !swing.isDisplayable();
    446         // }
    447 
    448 
    449         @Override
    450         public String getName() {
    451                 return title;
    452         }
    453 
     408                super.joinableFinish();
     409        }
     410
     411        @Override
     412        protected void joinableJoin() throws InterruptedException {
     413                Dispatching.join(trees);
     414                super.joinableJoin();
     415        }
     416
     417        @Override
     418        public void childChangedState(Joinable joinable, JoinableState state) {
     419                if (joinable == trees) {
     420                        proceedToState(state);
     421                }
     422        }
    454423
    455424}
Note: See TracChangeset for help on using the changeset viewer.