View | Details | Raw Unified | Return to bug 54784
Collapse All | Expand All

(-)a/src/core/org/apache/jmeter/gui/GuiPackage.java (-70 / +35 lines)
Lines 19-24 Link Here
19
package org.apache.jmeter.gui;
19
package org.apache.jmeter.gui;
20
20
21
import java.awt.Component;
21
import java.awt.Component;
22
import java.awt.Point;
23
import java.awt.event.ActionEvent;
22
import java.awt.event.MouseEvent;
24
import java.awt.event.MouseEvent;
23
import java.beans.Introspector;
25
import java.beans.Introspector;
24
import java.util.ArrayList;
26
import java.util.ArrayList;
Lines 28-33 import java.util.Iterator; Link Here
28
import java.util.List;
30
import java.util.List;
29
import java.util.Map;
31
import java.util.Map;
30
32
33
import javax.swing.AbstractAction;
34
import javax.swing.ActionMap;
35
import javax.swing.InputMap;
31
import javax.swing.JCheckBoxMenuItem;
36
import javax.swing.JCheckBoxMenuItem;
32
import javax.swing.JOptionPane;
37
import javax.swing.JOptionPane;
33
import javax.swing.JPopupMenu;
38
import javax.swing.JPopupMenu;
Lines 37-42 import javax.swing.SwingUtilities; Link Here
37
import org.apache.jmeter.engine.util.ValueReplacer;
42
import org.apache.jmeter.engine.util.ValueReplacer;
38
import org.apache.jmeter.exceptions.IllegalUserActionException;
43
import org.apache.jmeter.exceptions.IllegalUserActionException;
39
import org.apache.jmeter.gui.UndoHistory.HistoryListener;
44
import org.apache.jmeter.gui.UndoHistory.HistoryListener;
45
import org.apache.jmeter.gui.action.ActionNames;
46
import org.apache.jmeter.gui.action.KeyStrokes;
40
import org.apache.jmeter.gui.tree.JMeterTreeListener;
47
import org.apache.jmeter.gui.tree.JMeterTreeListener;
41
import org.apache.jmeter.gui.tree.JMeterTreeModel;
48
import org.apache.jmeter.gui.tree.JMeterTreeModel;
42
import org.apache.jmeter.gui.tree.JMeterTreeNode;
49
import org.apache.jmeter.gui.tree.JMeterTreeNode;
Lines 116-135 public final class GuiPackage implements LocaleChangeListener, HistoryListener { Link Here
116
    /** The menu item toolbar. */
123
    /** The menu item toolbar. */
117
    private JCheckBoxMenuItem menuToolBar;
124
    private JCheckBoxMenuItem menuToolBar;
118
125
119
    /**
126
    /** The LoggerPanel menu item */
120
     * The LoggerPanel menu item
121
     */
122
    private JCheckBoxMenuItem menuItemLoggerPanel;
127
    private JCheckBoxMenuItem menuItemLoggerPanel;
123
128
124
    /**
129
    /** Logger Panel reference */
125
     * Logger Panel reference
126
     */
127
    private LoggerPanel loggerPanel;
130
    private LoggerPanel loggerPanel;
128
131
129
    /**
132
    /** History for tree states */
130
     * History for tree states
133
    private final UndoHistory undoHistory = new UndoHistory();
131
     */
132
    private UndoHistory undoHistory = new UndoHistory();
133
134
134
    /**
135
    /**
135
     * Private constructor to permit instantiation only from within this class.
136
     * Private constructor to permit instantiation only from within this class.
Lines 137-143 public final class GuiPackage implements LocaleChangeListener, HistoryListener { Link Here
137
     */
138
     */
138
    private GuiPackage(JMeterTreeModel treeModel, JMeterTreeListener treeListener) {
139
    private GuiPackage(JMeterTreeModel treeModel, JMeterTreeListener treeListener) {
139
        this.treeModel = treeModel;
140
        this.treeModel = treeModel;
140
        if(undoHistory.isEnabled()) {
141
        if (undoHistory.isEnabled()) {
141
            this.treeModel.addTreeModelListener(undoHistory);
142
            this.treeModel.addTreeModelListener(undoHistory);
142
        }
143
        }
143
        this.treeListener = treeListener;
144
        this.treeListener = treeListener;
Lines 151-164 public final class GuiPackage implements LocaleChangeListener, HistoryListener { Link Here
151
    public static GuiPackage getInstance() {
152
    public static GuiPackage getInstance() {
152
        return guiPack;
153
        return guiPack;
153
    }
154
    }
154
    
155
155
    /**
156
    /**
156
     * Register as listener of:
157
     * Register as listener of:
157
     * - UndoHistory
158
     * - UndoHistory
158
     * - Locale Changes
159
     * - Locale Changes
159
     */
160
     */
160
    public void registerAsListener() {
161
    public void registerAsListener() {
161
        if(undoHistory.isEnabled()) {
162
        if (undoHistory.isEnabled()) {
162
            this.undoHistory.registerHistoryListener(this);
163
            this.undoHistory.registerHistoryListener(this);
163
        }
164
        }
164
        JMeterUtils.addLocaleChangeListener(this);
165
        JMeterUtils.addLocaleChangeListener(this);
Lines 175-181 public final class GuiPackage implements LocaleChangeListener, HistoryListener { Link Here
175
     *
176
     *
176
     * @return GuiPackage
177
     * @return GuiPackage
177
     */
178
     */
178
    public static GuiPackage getInstance(JMeterTreeListener listener, JMeterTreeModel treeModel) {
179
    public synchronized static GuiPackage getInstance(JMeterTreeListener listener, JMeterTreeModel treeModel) {
179
        if (guiPack == null) {
180
        if (guiPack == null) {
180
            guiPack = new GuiPackage(treeModel, listener);
181
            guiPack = new GuiPackage(treeModel, listener);
181
            guiPack.undoHistory.add(treeModel, "Created");
182
            guiPack.undoHistory.add(treeModel, "Created");
Lines 228-237 public final class GuiPackage implements LocaleChangeListener, HistoryListener { Link Here
228
     * @param node
229
     * @param node
229
     *            the test element which this GUI is being created for
230
     *            the test element which this GUI is being created for
230
     * @param guiClass
231
     * @param guiClass
231
     *            the fully qualifed class name of the GUI component which will
232
     *            the fully qualified class name of the GUI component which will
232
     *            be created if it doesn't already exist
233
     *            be created if it doesn't already exist
233
     * @param testClass
234
     * @param testClass
234
     *            the fully qualifed class name of the test elements which have
235
     *            the fully qualified class name of the test elements which have
235
     *            to be edited by the returned GUI component
236
     *            to be edited by the returned GUI component
236
     *
237
     *
237
     * @return the GUI component corresponding to the specified test element
238
     * @return the GUI component corresponding to the specified test element
Lines 531-598 public final class GuiPackage implements LocaleChangeListener, HistoryListener { Link Here
531
                .getTestElement());
532
                .getTestElement());
532
    }
533
    }
533
534
534
    /**
535
     * Set the main JMeter frame.
536
     *
537
     * @param newMainFrame
538
     *            the new JMeter main frame
539
     */
540
    public void setMainFrame(MainFrame newMainFrame) {
535
    public void setMainFrame(MainFrame newMainFrame) {
541
        mainFrame = newMainFrame;
536
        mainFrame = newMainFrame;
542
    }
537
    }
543
538
544
    /**
545
     * Get the main JMeter frame.
546
     *
547
     * @return the main JMeter frame
548
     */
549
    public MainFrame getMainFrame() {
539
    public MainFrame getMainFrame() {
550
        return mainFrame;
540
        return mainFrame;
551
    }
541
    }
552
542
553
    /**
554
     * Get the listener for JMeter's test tree.
555
     *
556
     * @return the JMeter test tree listener
557
     */
558
    public JMeterTreeListener getTreeListener() {
543
    public JMeterTreeListener getTreeListener() {
559
        return treeListener;
544
        return treeListener;
560
    }
545
    }
561
546
562
    /**
563
     * Set the main JMeter toolbar.
564
     *
565
     * @param newToolbar
566
     *            the new JMeter main toolbar
567
     */
568
    public void setMainToolbar(JToolBar newToolbar) {
547
    public void setMainToolbar(JToolBar newToolbar) {
569
        toolbar = newToolbar;
548
        toolbar = newToolbar;
570
    }
549
    }
571
550
572
    /**
573
     * Get the main JMeter toolbar.
574
     *
575
     * @return the main JMeter toolbar
576
     */
577
    public JToolBar getMainToolbar() {
551
    public JToolBar getMainToolbar() {
578
        return toolbar;
552
        return toolbar;
579
    }
553
    }
580
554
581
    /**
582
     * Set the menu item toolbar.
583
     *
584
     * @param newMenuToolBar
585
     *            the new menu item toolbar
586
     */
587
    public void setMenuItemToolbar(JCheckBoxMenuItem newMenuToolBar) {
555
    public void setMenuItemToolbar(JCheckBoxMenuItem newMenuToolBar) {
588
        menuToolBar = newMenuToolBar;
556
        menuToolBar = newMenuToolBar;
589
    }
557
    }
590
558
591
    /**
592
     * Get the menu item  toolbar.
593
     *
594
     * @return the menu item toolbar
595
     */
596
    public JCheckBoxMenuItem getMenuItemToolbar() {
559
    public JCheckBoxMenuItem getMenuItemToolbar() {
597
        return menuToolBar;
560
        return menuToolBar;
598
    }
561
    }
Lines 607-613 public final class GuiPackage implements LocaleChangeListener, HistoryListener { Link Here
607
     *            the popup menu to display
570
     *            the popup menu to display
608
     */
571
     */
609
    public void displayPopUp(MouseEvent e, JPopupMenu popup) {
572
    public void displayPopUp(MouseEvent e, JPopupMenu popup) {
610
        displayPopUp((Component) e.getSource(), e, popup);
573
        final Point point = new Point(e.getX(), e.getY());
574
        Component invoker = (Component) e.getSource();
575
        displayPopUp(invoker, point, popup);
611
    }
576
    }
612
577
613
    /**
578
    /**
Lines 616-632 public final class GuiPackage implements LocaleChangeListener, HistoryListener { Link Here
616
     *
581
     *
617
     * @param invoker
582
     * @param invoker
618
     *            the source component
583
     *            the source component
619
     * @param e
584
     * @param p
620
     *            the mouse event causing this popup to be displayed
585
     *            the point at which to display the popup
621
     * @param popup
586
     * @param popup
622
     *            the popup menu to display
587
     *            the popup menu to display
623
     */
588
     */
624
    public void displayPopUp(Component invoker, MouseEvent e, JPopupMenu popup) {
589
    public void displayPopUp(Component invoker, Point p, JPopupMenu popup) {
625
        if (popup != null) {
590
        if (popup != null) {
626
            log.debug("Showing pop up for " + invoker + " at x,y = " + e.getX() + "," + e.getY());
591
            if (log.isDebugEnabled()) {
592
                log.debug("Showing pop up for " + invoker + " at x,y = " + p.x + "," + p.y);
593
            }
627
594
628
            popup.pack();
595
            popup.pack();
629
            popup.show(invoker, e.getX(), e.getY());
596
            popup.show(invoker, p.x, p.y);
630
            popup.setVisible(true);
597
            popup.setVisible(true);
631
            popup.requestFocusInWindow();
598
            popup.requestFocusInWindow();
632
        }
599
        }
Lines 637-643 public final class GuiPackage implements LocaleChangeListener, HistoryListener { Link Here
637
     */
604
     */
638
    @Override
605
    @Override
639
    public void localeChanged(LocaleChangeEvent event) {
606
    public void localeChanged(LocaleChangeEvent event) {
640
        // FIrst make sure we save the content of the current GUI (since we
607
        // First make sure we save the content of the current GUI (since we
641
        // will flush it away):
608
        // will flush it away):
642
        updateCurrentNode();
609
        updateCurrentNode();
643
610
Lines 647-654 public final class GuiPackage implements LocaleChangeListener, HistoryListener { Link Here
647
        nodesToGui = new HashMap<TestElement, JMeterGUIComponent>();
614
        nodesToGui = new HashMap<TestElement, JMeterGUIComponent>();
648
        testBeanGUIs = new HashMap<Class<?>, JMeterGUIComponent>();
615
        testBeanGUIs = new HashMap<Class<?>, JMeterGUIComponent>();
649
616
650
        // BeanInfo objects also contain locale-sensitive data -- flush them
617
        // BeanInfo objects also contain locale-sensitive data - flush them away
651
        // away:
652
        Introspector.flushCaches();
618
        Introspector.flushCaches();
653
619
654
        // Now put the current GUI in place. [This code was copied from the
620
        // Now put the current GUI in place. [This code was copied from the
Lines 739-756 public final class GuiPackage implements LocaleChangeListener, HistoryListener { Link Here
739
                JOptionPane.showMessageDialog(null,message,title,type);
705
                JOptionPane.showMessageDialog(null,message,title,type);
740
            }
706
            }
741
        });
707
        });
742
743
    }
708
    }
744
709
745
    /**
710
    /**
746
     * Unregister stoppable
711
     * Unregister stoppable
747
     * @param stoppable Stoppable
712
     *
713
     * @param stoppableToRemove Stoppable
748
     */
714
     */
749
    public void unregister(Stoppable stoppable) {
715
    public void unregister(Stoppable stoppableToRemove) {
750
        for (Iterator<Stoppable> iterator = stoppables .iterator(); iterator.hasNext();) {
716
        for (final Iterator<Stoppable> iterator = stoppables.iterator(); iterator.hasNext();) {
751
            Stoppable stopable = iterator.next();
717
            Stoppable stoppable = iterator.next();
752
            if(stopable == stoppable)
718
            if (stoppable == stoppableToRemove) {
753
            {
754
                iterator.remove();
719
                iterator.remove();
755
            }
720
            }
756
        }
721
        }
(-)a/src/core/org/apache/jmeter/gui/action/KeyStrokes.java (-2 / +4 lines)
Lines 30-37 import javax.swing.KeyStroke; Link Here
30
 */
30
 */
31
public final class KeyStrokes {
31
public final class KeyStrokes {
32
    // Prevent instantiation
32
    // Prevent instantiation
33
    private KeyStrokes(){
33
    private KeyStrokes() {}
34
    }
35
34
36
    // Bug 47064 - fixes for Mac LAF
35
    // Bug 47064 - fixes for Mac LAF
37
    private static final int CONTROL_MASK =Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
36
    private static final int CONTROL_MASK =Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
Lines 74-79 public final class KeyStrokes { Link Here
74
    public static final KeyStroke ALT_DOWN_ARROW    = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.ALT_DOWN_MASK);
73
    public static final KeyStroke ALT_DOWN_ARROW    = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.ALT_DOWN_MASK);
75
    public static final KeyStroke ALT_LEFT_ARROW    = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.ALT_DOWN_MASK);
74
    public static final KeyStroke ALT_LEFT_ARROW    = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.ALT_DOWN_MASK);
76
    public static final KeyStroke ALT_RIGHT_ARROW   = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.ALT_DOWN_MASK);
75
    public static final KeyStroke ALT_RIGHT_ARROW   = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.ALT_DOWN_MASK);
76
    
77
    public static final KeyStroke CONTEXT_MENU      = KeyStroke.getKeyStroke(KeyEvent.VK_CONTEXT_MENU, 0);
78
    public static final KeyStroke SHIFT_F10_CONTEXT_MENU = KeyStroke.getKeyStroke(KeyEvent.VK_F10, InputEvent.SHIFT_DOWN_MASK);
77
79
78
    /**
80
    /**
79
     * Check if an event matches the KeyStroke definition.
81
     * Check if an event matches the KeyStroke definition.
(-)a/src/core/org/apache/jmeter/gui/tree/JMeterTreeListener.java (-75 / +49 lines)
Lines 18-24 Link Here
18
18
19
package org.apache.jmeter.gui.tree;
19
package org.apache.jmeter.gui.tree;
20
20
21
import java.awt.Container;
21
import java.awt.Component;
22
import java.awt.Point;
23
import java.awt.Rectangle;
22
import java.awt.event.ActionEvent;
24
import java.awt.event.ActionEvent;
23
import java.awt.event.ActionListener;
25
import java.awt.event.ActionListener;
24
import java.awt.event.InputEvent;
26
import java.awt.event.InputEvent;
Lines 44-51 import org.apache.log.Logger; Link Here
44
public class JMeterTreeListener implements TreeSelectionListener, MouseListener, KeyListener {
46
public class JMeterTreeListener implements TreeSelectionListener, MouseListener, KeyListener {
45
    private static final Logger log = LoggingManager.getLoggerForClass();
47
    private static final Logger log = LoggingManager.getLoggerForClass();
46
48
47
    // Container endWindow;
48
    // JPopupMenu pop;
49
    private TreePath currentPath;
49
    private TreePath currentPath;
50
50
51
    private ActionListener actionHandler;
51
    private ActionListener actionHandler;
Lines 68-108 public class JMeterTreeListener implements TreeSelectionListener, MouseListener, Link Here
68
        model = m;
68
        model = m;
69
    }
69
    }
70
70
71
    /**
72
     * Sets the ActionHandler attribute of the JMeterTreeListener object.
73
     *
74
     * @param ah
75
     *            the new ActionHandler value
76
     */
77
    public void setActionHandler(ActionListener ah) {
71
    public void setActionHandler(ActionListener ah) {
78
        actionHandler = ah;
72
        actionHandler = ah;
79
    }
73
    }
80
74
81
    /**
82
     * Sets the JTree attribute of the JMeterTreeListener object.
83
     *
84
     * @param tree
85
     *            the new JTree value
86
     */
87
    public void setJTree(JTree tree) {
75
    public void setJTree(JTree tree) {
88
        this.tree = tree;
76
        this.tree = tree;
89
    }
77
    }
90
78
91
    /**
92
     * Sets the EndWindow attribute of the JMeterTreeListener object.
93
     *
94
     * @param window
95
     *            the new EndWindow value
96
     */
97
    public void setEndWindow(Container window) {
98
        // endWindow = window;
99
    }
100
101
    /**
102
     * Gets the JTree attribute of the JMeterTreeListener object.
103
     *
104
     * @return tree the current JTree value.
105
     */
106
    public JTree getJTree() {
79
    public JTree getJTree() {
107
        return tree;
80
        return tree;
108
    }
81
    }
Lines 145-153 public class JMeterTreeListener implements TreeSelectionListener, MouseListener, Link Here
145
        log.debug("value changed, updating currentPath");
118
        log.debug("value changed, updating currentPath");
146
        currentPath = e.getNewLeadSelectionPath();
119
        currentPath = e.getNewLeadSelectionPath();
147
        // Call requestFocusInWindow to ensure current component loses focus and
120
        // Call requestFocusInWindow to ensure current component loses focus and
148
        // all values are correctly saved
121
        // all values are correctly saved. See Bug IDs 55103 and 55459.
149
        // see https://issues.apache.org/bugzilla/show_bug.cgi?id=55103
150
        // see https://issues.apache.org/bugzilla/show_bug.cgi?id=55459
151
        tree.requestFocusInWindow();
122
        tree.requestFocusInWindow();
152
        actionHandler.actionPerformed(new ActionEvent(this, 3333, ActionNames.EDIT)); // $NON-NLS-1$
123
        actionHandler.actionPerformed(new ActionEvent(this, 3333, ActionNames.EDIT)); // $NON-NLS-1$
153
    }
124
    }
Lines 167-184 public class JMeterTreeListener implements TreeSelectionListener, MouseListener, Link Here
167
138
168
    @Override
139
    @Override
169
    public void mousePressed(MouseEvent e) {
140
    public void mousePressed(MouseEvent e) {
170
        // Get the Main Frame.
141
        final MainFrame mainFrame = GuiPackage.getInstance().getMainFrame();
171
        MainFrame mainFrame = GuiPackage.getInstance().getMainFrame();
142
        mainFrame.closeMenu(); // Close any open Main Menus
172
        // Close any Main Menu that is open
143
        final int selRow = tree.getRowForLocation(e.getX(), e.getY());
173
        mainFrame.closeMenu();
174
        int selRow = tree.getRowForLocation(e.getX(), e.getY());
175
        if (tree.getPathForLocation(e.getX(), e.getY()) != null) {
144
        if (tree.getPathForLocation(e.getX(), e.getY()) != null) {
176
            log.debug("mouse pressed, updating currentPath");
145
            log.debug("mouse pressed, updating currentPath");
177
            currentPath = tree.getPathForLocation(e.getX(), e.getY());
146
            currentPath = tree.getPathForLocation(e.getX(), e.getY());
178
        }
147
        }
179
        if (selRow != -1) {
148
        if (selRow != -1) {
180
            // updateMainMenu(((JMeterGUIComponent)
181
            // getCurrentNode().getUserObject()).createPopupMenu());
182
            if (isRightClick(e)) {
149
            if (isRightClick(e)) {
183
                if (tree.getSelectionCount() < 2) {
150
                if (tree.getSelectionCount() < 2) {
184
                    tree.setSelectionPath(currentPath);
151
                    tree.setSelectionPath(currentPath);
Lines 189-236 public class JMeterTreeListener implements TreeSelectionListener, MouseListener, Link Here
189
        }
156
        }
190
    }
157
    }
191
158
192
193
    @Override
159
    @Override
194
    public void mouseExited(MouseEvent ev) {
160
    public void mouseExited(MouseEvent e) {
195
    }
161
    }
196
162
197
    @Override
163
    @Override
198
    public void keyPressed(KeyEvent e) {
164
    public void keyPressed(KeyEvent e) {
199
        if (KeyStrokes.matches(e,KeyStrokes.COPY)) {
165
        String actionName = null;
200
            ActionRouter actionRouter = ActionRouter.getInstance();
166
201
            actionRouter.doActionNow(new ActionEvent(e.getSource(), e.getID(), ActionNames.COPY));
167
        if (KeyStrokes.matches(e, KeyStrokes.COPY)) {
202
            e.consume();
168
            actionName = ActionNames.COPY;
203
        } else if (KeyStrokes.matches(e,KeyStrokes.PASTE)) {
169
        } else if (KeyStrokes.matches(e, KeyStrokes.PASTE)) {
204
            ActionRouter actionRouter = ActionRouter.getInstance();
170
            actionName = ActionNames.PASTE;
205
            actionRouter.doActionNow(new ActionEvent(e.getSource(), e.getID(), ActionNames.PASTE));
171
        } else if (KeyStrokes.matches(e, KeyStrokes.CUT)) {
206
            e.consume();
172
            actionName = ActionNames.CUT;
207
        } else if (KeyStrokes.matches(e,KeyStrokes.CUT)) {
173
        } else if (KeyStrokes.matches(e, KeyStrokes.DUPLICATE)) {
208
            ActionRouter actionRouter = ActionRouter.getInstance();
174
            actionName = ActionNames.DUPLICATE;
209
            actionRouter.doActionNow(new ActionEvent(e.getSource(), e.getID(), ActionNames.CUT));
175
        } else if (KeyStrokes.matches(e, KeyStrokes.ALT_UP_ARROW)) {
210
            e.consume();
176
            actionName = ActionNames.MOVE_UP;
211
        } else if (KeyStrokes.matches(e,KeyStrokes.DUPLICATE)) {
177
        } else if (KeyStrokes.matches(e, KeyStrokes.ALT_DOWN_ARROW)) {
212
            ActionRouter actionRouter = ActionRouter.getInstance();
178
            actionName = ActionNames.MOVE_DOWN;
213
            actionRouter.doActionNow(new ActionEvent(e.getSource(), e.getID(), ActionNames.DUPLICATE));
179
        } else if (KeyStrokes.matches(e, KeyStrokes.ALT_LEFT_ARROW)) {
214
            e.consume();
180
            actionName = ActionNames.MOVE_LEFT;
215
        } else if (KeyStrokes.matches(e,KeyStrokes.ALT_UP_ARROW)) {
181
        } else if (KeyStrokes.matches(e, KeyStrokes.ALT_RIGHT_ARROW)) {
216
            ActionRouter actionRouter = ActionRouter.getInstance();
182
            actionName = ActionNames.MOVE_RIGHT;
217
            actionRouter.doActionNow(new ActionEvent(e.getSource(), e.getID(), ActionNames.MOVE_UP));
183
        } else if (KeyStrokes.matches(e, KeyStrokes.SHIFT_F10_CONTEXT_MENU)
218
            e.consume();
184
                || KeyStrokes.matches(e, KeyStrokes.CONTEXT_MENU)) {
219
        } else if (KeyStrokes.matches(e,KeyStrokes.ALT_DOWN_ARROW)) {
185
            // Bug 54784
220
            ActionRouter actionRouter = ActionRouter.getInstance();
186
            displayPopupMenu(e);
221
            actionRouter.doActionNow(new ActionEvent(e.getSource(), e.getID(), ActionNames.MOVE_DOWN));
187
        }
222
            e.consume();
188
        
223
        } else if (KeyStrokes.matches(e,KeyStrokes.ALT_LEFT_ARROW)) {
189
        if (actionName != null) {
224
            ActionRouter actionRouter = ActionRouter.getInstance();
190
            final ActionRouter actionRouter = ActionRouter.getInstance();
225
            actionRouter.doActionNow(new ActionEvent(e.getSource(), e.getID(), ActionNames.MOVE_LEFT));
191
            actionRouter.doActionNow(new ActionEvent(e.getSource(), e.getID(), actionName));
226
            e.consume();
227
        } else if (KeyStrokes.matches(e,KeyStrokes.ALT_RIGHT_ARROW)) {
228
            ActionRouter actionRouter = ActionRouter.getInstance();
229
            actionRouter.doActionNow(new ActionEvent(e.getSource(), e.getID(), ActionNames.MOVE_RIGHT));
230
            e.consume();
192
            e.consume();
231
        }
193
        }
232
    }
194
    }
233
195
196
    private void displayPopupMenu(KeyEvent e) {
197
        Component invoker = e.getComponent();
198
        TreePath path = new TreePath(getCurrentNode().getPath());
199
        Rectangle r = getJTree().getPathBounds(path);
200
        int padding = 5;
201
        Point point = new Point(r.x + padding, r.y + padding);
202
        JPopupMenu popup = getCurrentNode().createPopupMenu();
203
        GuiPackage.getInstance().displayPopUp(invoker, point, popup);
204
    }
205
234
    @Override
206
    @Override
235
    public void keyReleased(KeyEvent e) {
207
    public void keyReleased(KeyEvent e) {
236
    }
208
    }
Lines 240-250 public class JMeterTreeListener implements TreeSelectionListener, MouseListener, Link Here
240
    }
212
    }
241
213
242
    private boolean isRightClick(MouseEvent e) {
214
    private boolean isRightClick(MouseEvent e) {
243
        return e.isPopupTrigger() || (InputEvent.BUTTON2_MASK & e.getModifiers()) > 0 || (InputEvent.BUTTON3_MASK == e.getModifiers());
215
        return e.isPopupTrigger()
216
                || (InputEvent.BUTTON2_MASK & e.getModifiers()) > 0
217
                || (InputEvent.BUTTON3_MASK == e.getModifiers());
244
    }
218
    }
245
219
246
    private void displayPopUp(MouseEvent e) {
220
    private void displayPopUp(MouseEvent e) {
247
        JPopupMenu pop = getCurrentNode().createPopupMenu();
221
        final JPopupMenu pop = getCurrentNode().createPopupMenu();
248
        GuiPackage.getInstance().displayPopUp(e, pop);
222
        GuiPackage.getInstance().displayPopUp(e, pop);
249
    }
223
    }
250
}
224
}
(-)a/src/core/org/apache/jmeter/gui/util/MenuFactory.java (-47 / +44 lines)
Lines 39-45 import javax.swing.JMenuItem; Link Here
39
import javax.swing.JPopupMenu;
39
import javax.swing.JPopupMenu;
40
import javax.swing.KeyStroke;
40
import javax.swing.KeyStroke;
41
import javax.swing.MenuElement;
41
import javax.swing.MenuElement;
42
43
import org.apache.jmeter.control.Controller;
42
import org.apache.jmeter.control.Controller;
44
import org.apache.jmeter.gui.GuiPackage;
43
import org.apache.jmeter.gui.GuiPackage;
45
import org.apache.jmeter.gui.JMeterGUIComponent;
44
import org.apache.jmeter.gui.JMeterGUIComponent;
Lines 68-76 public final class MenuFactory { Link Here
68
     *  Predefined strings for makeMenu().
67
     *  Predefined strings for makeMenu().
69
     *  These are used as menu categories in the menuMap Hashmap,
68
     *  These are used as menu categories in the menuMap Hashmap,
70
     *  and also for resource lookup in messages.properties
69
     *  and also for resource lookup in messages.properties
71
    */
70
     */
72
    public static final String THREADS = "menu_threads"; //$NON-NLS-1$
71
    public static final String THREADS = "menu_threads"; //$NON-NLS-1$
73
    
72
74
    public static final String FRAGMENTS = "menu_fragments"; //$NON-NLS-1$
73
    public static final String FRAGMENTS = "menu_fragments"; //$NON-NLS-1$
75
74
76
    public static final String TIMERS = "menu_timer"; //$NON-NLS-1$
75
    public static final String TIMERS = "menu_timer"; //$NON-NLS-1$
Lines 107-116 public final class MenuFactory { Link Here
107
        MenuFactory.POST_PROCESSORS,
106
        MenuFactory.POST_PROCESSORS,
108
        MenuFactory.ASSERTIONS,
107
        MenuFactory.ASSERTIONS,
109
        MenuFactory.LISTENERS,
108
        MenuFactory.LISTENERS,
110
        };
109
    };
111
110
112
    private static final String[] MENU_PARENT_CONTROLLER = new String[] {
111
    private static final String[] MENU_PARENT_CONTROLLER = new String[] {
113
        MenuFactory.CONTROLLERS };
112
        MenuFactory.CONTROLLERS
113
    };
114
114
115
    private static final String[] MENU_ADD_SAMPLER = new String[] {
115
    private static final String[] MENU_ADD_SAMPLER = new String[] {
116
        MenuFactory.CONFIG_ELEMENTS,
116
        MenuFactory.CONFIG_ELEMENTS,
Lines 119-130 public final class MenuFactory { Link Here
119
        MenuFactory.POST_PROCESSORS,
119
        MenuFactory.POST_PROCESSORS,
120
        MenuFactory.ASSERTIONS,
120
        MenuFactory.ASSERTIONS,
121
        MenuFactory.LISTENERS,
121
        MenuFactory.LISTENERS,
122
        };
122
    };
123
123
124
    private static final String[] MENU_PARENT_SAMPLER = new String[] {
124
    private static final String[] MENU_PARENT_SAMPLER = new String[] {
125
        MenuFactory.CONTROLLERS };
125
        MenuFactory.CONTROLLERS
126
    };
126
127
127
    private static final List<MenuInfo> timers, controllers, samplers, threads, 
128
    private static final List<MenuInfo> timers, controllers, samplers, threads,
128
        fragments,configElements, assertions, listeners, nonTestElements,
129
        fragments,configElements, assertions, listeners, nonTestElements,
129
        postProcessors, preProcessors;
130
        postProcessors, preProcessors;
130
131
Lines 154-161 public final class MenuFactory { Link Here
154
        try {
155
        try {
155
            String[] classesToSkip =
156
            String[] classesToSkip =
156
                JOrphanUtils.split(JMeterUtils.getPropDefault("not_in_menu", ""), ","); //$NON-NLS-1$
157
                JOrphanUtils.split(JMeterUtils.getPropDefault("not_in_menu", ""), ","); //$NON-NLS-1$
157
            for (int i = 0; i < classesToSkip.length; i++) {
158
            for (String classToSkip : classesToSkip) {
158
                elementsToSkip.add(classesToSkip[i].trim());
159
                elementsToSkip.add(classToSkip.trim());
159
            }
160
            }
160
161
161
            initializeMenus();
162
            initializeMenus();
Lines 203-209 public final class MenuFactory { Link Here
203
204
204
    /**
205
    /**
205
     * @param menu JPopupMenu
206
     * @param menu JPopupMenu
206
     * @param addSaveTestFragmentMenu Add Save as Test Fragment menu if true 
207
     * @param addSaveTestFragmentMenu Add Save as Test Fragment menu if true
207
     */
208
     */
208
    public static void addFileMenu(JPopupMenu menu, boolean addSaveTestFragmentMenu) {
209
    public static void addFileMenu(JPopupMenu menu, boolean addSaveTestFragmentMenu) {
209
        // the undo/redo as a standard goes first in Edit menus
210
        // the undo/redo as a standard goes first in Edit menus
Lines 233-250 public final class MenuFactory { Link Here
233
234
234
        addSeparator(menu);
235
        addSeparator(menu);
235
236
236
        JMenuItem disabled = makeMenuItemRes("disable", ActionNames.DISABLE);// $NON-NLS-1$
237
        JMenuItem disable = makeMenuItemRes("disable", ActionNames.DISABLE);// $NON-NLS-1$
237
        JMenuItem enabled = makeMenuItemRes("enable", ActionNames.ENABLE);// $NON-NLS-1$
238
        JMenuItem enable = makeMenuItemRes("enable", ActionNames.ENABLE);// $NON-NLS-1$
238
        boolean isEnabled = GuiPackage.getInstance().getTreeListener().getCurrentNode().isEnabled();
239
        boolean isEnabled = GuiPackage.getInstance().getTreeListener().getCurrentNode().isEnabled();
239
        if (isEnabled) {
240
        disable.setEnabled(isEnabled);
240
            disabled.setEnabled(true);
241
        enable.setEnabled(!isEnabled);
241
            enabled.setEnabled(false);
242
        menu.add(enable);
242
        } else {
243
        menu.add(disable);
243
            disabled.setEnabled(false);
244
            enabled.setEnabled(true);
245
        }
246
        menu.add(enabled);
247
        menu.add(disabled);
248
        JMenuItem toggle = makeMenuItemRes("toggle", ActionNames.TOGGLE, KeyStrokes.TOGGLE);// $NON-NLS-1$
244
        JMenuItem toggle = makeMenuItemRes("toggle", ActionNames.TOGGLE, KeyStrokes.TOGGLE);// $NON-NLS-1$
249
        menu.add(toggle);
245
        menu.add(toggle);
250
        addSeparator(menu);
246
        addSeparator(menu);
Lines 271-278 public final class MenuFactory { Link Here
271
267
272
    public static JMenu makeMenus(String[] categories, String label, String actionCommand) {
268
    public static JMenu makeMenus(String[] categories, String label, String actionCommand) {
273
        JMenu addMenu = new JMenu(label);
269
        JMenu addMenu = new JMenu(label);
274
        for (int i = 0; i < categories.length; i++) {
270
        for (String category : categories) {
275
            addMenu.add(makeMenu(categories[i], actionCommand));
271
            addMenu.add(makeMenu(category, actionCommand));
276
        }
272
        }
277
        GuiUtils.makeScrollableMenu(addMenu);
273
        GuiUtils.makeScrollableMenu(addMenu);
278
        return addMenu;
274
        return addMenu;
Lines 423-429 public final class MenuFactory { Link Here
423
419
424
        return newMenuChoice;
420
        return newMenuChoice;
425
    }
421
    }
426
422
    
427
    /**
423
    /**
428
     * Create a single menu item from a MenuInfo object
424
     * Create a single menu item from a MenuInfo object
429
     *
425
     *
Lines 432-441 public final class MenuFactory { Link Here
432
     *     @see org.apache.jmeter.gui.action.ActionNames
428
     *     @see org.apache.jmeter.gui.action.ActionNames
433
     * @return the menu item
429
     * @return the menu item
434
     */
430
     */
435
    public static Component makeMenuItem(MenuInfo info, String actionCommand) {
431
    public static Component makeMenuItem(MenuInfo info, final String actionCommand) {
436
        JMenuItem newMenuChoice = new JMenuItem(info.getLabel());
432
        final JMenuItem newMenuChoice = new JMenuItem(info.getLabel());
437
        newMenuChoice.setName(info.getClassName());
433
        newMenuChoice.setName(info.getClassName());
438
        newMenuChoice.addActionListener(ActionRouter.getInstance());
434
        newMenuChoice.addActionListener(ActionRouter.getInstance());
435
        newMenuChoice.registerKeyboardAction(ActionRouter.getInstance(), actionCommand,
436
                KeyStrokes.ENTER, JMenuItem.WHEN_IN_FOCUSED_WINDOW); // Bug 54784
437
439
        if (actionCommand != null) {
438
        if (actionCommand != null) {
440
            newMenuChoice.setActionCommand(actionCommand);
439
            newMenuChoice.setActionCommand(actionCommand);
441
        }
440
        }
Lines 599-616 public final class MenuFactory { Link Here
599
        if (null == parentNode) {
598
        if (null == parentNode) {
600
            return false;
599
            return false;
601
        }
600
        }
602
        if (foundClass(nodes, new Class[]{WorkBench.class})){// Can't add a Workbench anywhere
601
        if (foundClass(nodes, new Class[]{WorkBench.class})) {// Can't add a Workbench anywhere
603
            return false;
602
            return false;
604
        }
603
        }
605
        if (foundClass(nodes, new Class[]{TestPlan.class})){// Can't add a TestPlan anywhere
604
        if (foundClass(nodes, new Class[]{TestPlan.class})) {// Can't add a TestPlan anywhere
606
            return false;
605
            return false;
607
        }
606
        }
608
        TestElement parent = parentNode.getTestElement();
607
        TestElement parent = parentNode.getTestElement();
609
608
610
        // Force TestFragment to only be pastable under a Test Plan
609
        // Force TestFragment to only be pastable under a Test Plan
611
        if (foundClass(nodes, new Class[]{org.apache.jmeter.control.TestFragmentController.class})){
610
        if (foundClass(nodes, new Class[]{org.apache.jmeter.control.TestFragmentController.class})){
612
            if (parent instanceof TestPlan)
611
            if (parent instanceof TestPlan) {
613
                return true;
612
                return true;
613
            }
614
            return false;
614
            return false;
615
        }
615
        }
616
616
Lines 621-640 public final class MenuFactory { Link Here
621
            if (foundClass(nodes,
621
            if (foundClass(nodes,
622
                     new Class[]{Sampler.class, Controller.class}, // Samplers and Controllers need not apply ...
622
                     new Class[]{Sampler.class, Controller.class}, // Samplers and Controllers need not apply ...
623
                     org.apache.jmeter.threads.AbstractThreadGroup.class)  // but AbstractThreadGroup (Controller) is OK
623
                     org.apache.jmeter.threads.AbstractThreadGroup.class)  // but AbstractThreadGroup (Controller) is OK
624
                ){
624
                ) {
625
                return false;
625
                return false;
626
            }
626
            }
627
            return true;
627
            return true;
628
        }
628
        }
629
        // AbstractThreadGroup is only allowed under a TestPlan
629
        // AbstractThreadGroup is only allowed under a TestPlan
630
        if (foundClass(nodes, new Class[]{org.apache.jmeter.threads.AbstractThreadGroup.class})){
630
        if (foundClass(nodes, new Class[]{org.apache.jmeter.threads.AbstractThreadGroup.class})) {
631
            return false;
631
            return false;
632
        }
632
        }
633
        if (parent instanceof Controller) {// Includes thread group; anything goes
633
        if (parent instanceof Controller) {// Includes thread group; anything goes
634
            return true;
634
            return true;
635
        }
635
        }
636
        if (parent instanceof Sampler) {// Samplers and Controllers need not apply ...
636
        if (parent instanceof Sampler) {// Samplers and Controllers need not apply ...
637
            if (foundClass(nodes, new Class[]{Sampler.class, Controller.class})){
637
            if (foundClass(nodes, new Class[]{Sampler.class, Controller.class})) {
638
                return false;
638
                return false;
639
            }
639
            }
640
            return true;
640
            return true;
Lines 644-654 public final class MenuFactory { Link Here
644
    }
644
    }
645
645
646
    // Is any node an instance of one of the classes?
646
    // Is any node an instance of one of the classes?
647
    private static boolean foundClass(JMeterTreeNode nodes[],Class<?> classes[]){
647
    private static boolean foundClass(JMeterTreeNode nodes[], Class<?> classes[]) {
648
        for (int i = 0; i < nodes.length; i++) {
648
        for (JMeterTreeNode node : nodes) {
649
            JMeterTreeNode node = nodes[i];
649
            for (Class<?> clazz : classes) {
650
            for (int j=0; j < classes.length; j++) {
650
                if (clazz.isInstance(node.getUserObject())){
651
                if (classes[j].isInstance(node.getUserObject())){
652
                    return true;
651
                    return true;
653
                }
652
                }
654
            }
653
            }
Lines 657-669 public final class MenuFactory { Link Here
657
    }
656
    }
658
657
659
    // Is any node an instance of one of the classes, but not an exception?
658
    // Is any node an instance of one of the classes, but not an exception?
660
    private static boolean foundClass(JMeterTreeNode nodes[],Class<?> classes[], Class<?> except){
659
    private static boolean foundClass(JMeterTreeNode nodes[], Class<?> classes[], Class<?> except) {
661
        for (int i = 0; i < nodes.length; i++) {
660
        for (JMeterTreeNode node : nodes) {
662
            JMeterTreeNode node = nodes[i];
663
            Object userObject = node.getUserObject();
661
            Object userObject = node.getUserObject();
664
            if (!except.isInstance(userObject)) {
662
            if (!except.isInstance(userObject)) {
665
                for (int j=0; j < classes.length; j++) {
663
                for (Class<?> clazz : classes) {
666
                    if (classes[j].isInstance(userObject)){
664
                    if (clazz.isInstance(userObject)){
667
                        return true;
665
                        return true;
668
                    }
666
                    }
669
                }
667
                }
Lines 721-729 public final class MenuFactory { Link Here
721
            String lab1 = o1.getLabel();
719
            String lab1 = o1.getLabel();
722
            String lab2 = o2.getLabel();
720
            String lab2 = o2.getLabel();
723
            if (caseBlind) {
721
            if (caseBlind) {
724
                return lab1.toLowerCase(Locale.ENGLISH).compareTo(lab2.toLowerCase(Locale.ENGLISH));                
722
                return lab1.toLowerCase(Locale.ENGLISH).compareTo(lab2.toLowerCase(Locale.ENGLISH));
725
            }
723
            }
726
            return lab1.compareTo(lab2);                
724
            return lab1.compareTo(lab2);
727
        }
725
        }
728
    }
726
    }
729
727
Lines 732-738 public final class MenuFactory { Link Here
732
     * [This is so Thread Group appears before setUp and tearDown]
730
     * [This is so Thread Group appears before setUp and tearDown]
733
     */
731
     */
734
    private static void sortPluginMenus() {
732
    private static void sortPluginMenus() {
735
        for(Entry<String, List<MenuInfo>> me : menuMap.entrySet()){
733
        for (Entry<String, List<MenuInfo>> me : menuMap.entrySet()) {
736
            Collections.sort(me.getValue(), new MenuInfoComparator(!me.getKey().equals(THREADS)));
734
            Collections.sort(me.getValue(), new MenuInfoComparator(!me.getKey().equals(THREADS)));
737
        }
735
        }
738
    }
736
    }
739
- 

Return to bug 54784