ソースを参照

Right click menus for Buttons in buttonBar.

Fixes issue 4063

Change-Id: I2b7c705f572784e23dadc5b6e65a007d0ca9b4b2
Reviewed-on: http://gerrit.dmdirc.com/1191
Reviewed-by: Gregory Holmes <greg@dmdirc.com>
Automatic-Compile: DMDirc Local Commits <dmdirc@googlemail.com>
tags/0.6.4
Simon Mott 14年前
コミット
2306638331

+ 119
- 42
src/com/dmdirc/addons/ui_swing/framemanager/buttonbar/ButtonBar.java ファイルの表示

@@ -1,5 +1,6 @@
1 1
 /*
2
- * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes,
3
+ * Simon Mott
3 4
  *
4 5
  * Permission is hereby granted, free of charge, to any person obtaining a copy
5 6
  * of this software and associated documentation files (the "Software"), to deal
@@ -22,10 +23,10 @@
22 23
 package com.dmdirc.addons.ui_swing.framemanager.buttonbar;
23 24
 
24 25
 import com.dmdirc.FrameContainer;
25
-import com.dmdirc.FrameContainerComparator;
26 26
 import com.dmdirc.addons.ui_swing.SwingController;
27 27
 import com.dmdirc.addons.ui_swing.SwingWindowFactory;
28 28
 import com.dmdirc.addons.ui_swing.UIUtilities;
29
+import com.dmdirc.addons.ui_swing.actions.CloseFrameContainerAction;
29 30
 import com.dmdirc.addons.ui_swing.components.frames.TextFrame;
30 31
 import com.dmdirc.config.IdentityManager;
31 32
 import com.dmdirc.interfaces.FrameInfoListener;
@@ -45,15 +46,18 @@ import java.awt.event.ActionEvent;
45 46
 import java.awt.event.ActionListener;
46 47
 import java.awt.event.ComponentEvent;
47 48
 import java.awt.event.ComponentListener;
49
+import java.awt.event.MouseEvent;
50
+import java.awt.event.MouseListener;
48 51
 import java.io.Serializable;
49 52
 import java.util.Collection;
50 53
 import java.util.Collections;
51
-import java.util.Map;
52
-import java.util.TreeMap;
53 54
 
55
+import java.util.HashMap;
56
+import java.util.Map;
54 57
 import javax.swing.JComponent;
58
+import javax.swing.JMenuItem;
59
+import javax.swing.JPopupMenu;
55 60
 import javax.swing.JScrollPane;
56
-import javax.swing.JToggleButton;
57 61
 import javax.swing.ScrollPaneConstants;
58 62
 import javax.swing.SwingConstants;
59 63
 
@@ -68,7 +72,7 @@ import net.miginfocom.swing.MigLayout;
68 72
  */
69 73
 public final class ButtonBar implements FrameManager, ActionListener,
70 74
         ComponentListener, Serializable, NotificationListener,
71
-        SelectionListener, FrameInfoListener {
75
+        SelectionListener, FrameInfoListener, MouseListener {
72 76
 
73 77
     /**
74 78
      * A version number for this class. It should be changed whenever the class
@@ -76,8 +80,8 @@ public final class ButtonBar implements FrameManager, ActionListener,
76 80
      * objects being unserialized with the new class).
77 81
      */
78 82
     private static final long serialVersionUID = 3;
79
-    /** A map of containers to the buttons we're using for them. */
80
-    private final Map<FrameContainer<?>, JToggleButton> buttons;
83
+    /** A map of windows to the buttons we're using for them. */
84
+    private final Map<Window, FrameToggleButton> buttons;
81 85
     /** The position of this frame manager. */
82 86
     private final FramemanagerPosition position;
83 87
     /** The parent for the manager. */
@@ -112,8 +116,7 @@ public final class ButtonBar implements FrameManager, ActionListener,
112 116
         scrollPane.setMinimumSize(new Dimension(0,buttonHeight
113 117
                 + ((int) PlatformDefaults.getUnitValueX("related").getValue()) * 2));
114 118
 
115
-        buttons = Collections.synchronizedMap(new TreeMap<FrameContainer<?>,
116
-                JToggleButton>(new FrameContainerComparator()));
119
+        buttons = Collections.synchronizedMap(new HashMap<Window, FrameToggleButton>());
117 120
         position = FramemanagerPosition.getPosition(
118 121
                 IdentityManager.getGlobalConfig().getOption("ui",
119 122
                 "framemanagerPosition"));
@@ -157,12 +160,27 @@ public final class ButtonBar implements FrameManager, ActionListener,
157 160
         });
158 161
     }
159 162
 
163
+    /**
164
+     * Retreives the button object associated with {@link FrameContainer}.
165
+     *
166
+     * @param frame FrameContainer to find associated button for
167
+     * @return {@link FrameToggleButton} object asociated with this FrameContainer.
168
+     * Returns null if none exist
169
+     */
170
+    public FrameToggleButton getButton(final FrameContainer<?> frame) {
171
+        final Window window = controller.getSwingWindow(frame);
172
+        if (buttons.containsKey(window)) {
173
+            return buttons.get(window);
174
+        }
175
+        return null;
176
+    }
177
+
160 178
     /** {@inheritDoc} */
161 179
     @Override
162 180
     public void setController(final UIController controller) {
163 181
         if (!(controller instanceof SwingController)) {
164
-            throw new IllegalArgumentException("Controller must be an instance "
165
-                    + "of SwingController");
182
+            throw new IllegalArgumentException("Controller must be an instance" +
183
+                    " of SwingController");
166 184
         }
167 185
         this.controller = ((SwingController) controller).getWindowFactory();
168 186
     }
@@ -180,12 +198,14 @@ public final class ButtonBar implements FrameManager, ActionListener,
180 198
      * @author Simon Mott
181 199
      * @since 0.6.4
182 200
      */
183
-    private void insertButtons(Collection<FrameContainer<?>> windowCollection) {
201
+    private void insertButtons(final Collection<FrameContainer<?>> windowCollection) {
202
+        FrameToggleButton button;
184 203
         for (FrameContainer<?> window : windowCollection) {
185
-            if (buttons.get(window) != null) {
186
-                buttons.get(window).setPreferredSize(new Dimension(
204
+            button = getButton(window);
205
+            if (button != null) {
206
+                button.setPreferredSize(new Dimension(
187 207
                             buttonWidth, buttonHeight));
188
-                buttonPanel.add(buttons.get(window));
208
+                buttonPanel.add(button);
189 209
                 if (!window.getChildren().isEmpty()) {
190 210
                     insertButtons(window.getChildren());
191 211
                 }
@@ -208,10 +228,12 @@ public final class ButtonBar implements FrameManager, ActionListener,
208 228
      *
209 229
      * @param source The Container to get title/icon info from
210 230
      */
211
-    private void addButton(final FrameContainer<?> source) {
212
-        final JToggleButton button = new JToggleButton(source.toString(),
213
-                IconManager.getIconManager().getIcon(source.getIcon()));
231
+    private void addButton(final Window source) {
232
+        final FrameToggleButton button = new FrameToggleButton(source.getContainer()
233
+                .toString(), IconManager.getIconManager().getIcon(
234
+                source.getContainer().getIcon()), source);
214 235
         button.addActionListener(this);
236
+        button.addMouseListener(this);
215 237
         button.setHorizontalAlignment(SwingConstants.LEFT);
216 238
         button.setMinimumSize(new Dimension(0,buttonHeight));
217 239
         button.setMargin(new Insets(0, 0, 0, 0));
@@ -238,7 +260,7 @@ public final class ButtonBar implements FrameManager, ActionListener,
238 260
             /** {@inheritDoc} */
239 261
             @Override
240 262
             public void run() {
241
-                addButton(window.getContainer());
263
+                addButton(window);
242 264
                 relayout();
243 265
                 window.getContainer().addNotificationListener(ButtonBar.this);
244 266
                 window.getContainer().addSelectionListener(ButtonBar.this);
@@ -259,7 +281,9 @@ public final class ButtonBar implements FrameManager, ActionListener,
259 281
                 window.getContainer().removeNotificationListener(ButtonBar.this);
260 282
                 window.getContainer().removeFrameInfoListener(ButtonBar.this);
261 283
                 window.getContainer().removeSelectionListener(ButtonBar.this);
262
-                buttons.remove(window.getContainer());
284
+                if (buttons.containsKey(window)) {
285
+                    buttons.remove(window);
286
+                }
263 287
                 relayout();
264 288
             }
265 289
         });
@@ -272,16 +296,13 @@ public final class ButtonBar implements FrameManager, ActionListener,
272 296
      */
273 297
     @Override
274 298
     public void actionPerformed(final ActionEvent e) {
275
-        for (Map.Entry<FrameContainer<?>, JToggleButton> entry : buttons.entrySet()) {
276
-            if (entry.getValue().equals(e.getSource())) {
277
-                final TextFrame frame = (TextFrame) controller.getSwingWindow(
278
-                        entry.getKey());
279
-                if (frame != null && frame.equals(activeWindow)) {
280
-                    entry.getValue().setSelected(true);
281
-                }
282
-                entry.getKey().activateFrame();
283
-            }
299
+        final FrameToggleButton button = (FrameToggleButton) e.getSource();
300
+        final FrameContainer<?> window =  button.getFrameContainer();
301
+        final TextFrame frame = (TextFrame) button.getWindow();
302
+        if (frame != null && window.equals(activeWindow.getContainer())) {
303
+            button.setSelected(true);
284 304
         }
305
+        window.activateFrame();
285 306
     }
286 307
 
287 308
     /**
@@ -333,8 +354,9 @@ public final class ButtonBar implements FrameManager, ActionListener,
333 354
             /** {@inheritDoc} */
334 355
             @Override
335 356
             public void run() {
336
-                if (buttons.containsKey(window)) {
337
-                    buttons.get(window).setForeground(colour);
357
+                final FrameToggleButton button = getButton(window);
358
+                if (button != null) {
359
+                    button.setForeground(colour);
338 360
                 }
339 361
             }
340 362
         });
@@ -361,15 +383,17 @@ public final class ButtonBar implements FrameManager, ActionListener,
361 383
             /** {@inheritDoc} */
362 384
             @Override
363 385
             public void run() {
364
-                activeWindow = (TextFrame) controller.getSwingWindow(window);
365
-                if (selected != null && buttons.containsKey(selected)) {
366
-                    buttons.get(selected).setSelected(false);
386
+                activeWindow = (TextFrame) (getButton(window)).getWindow();
387
+                FrameToggleButton button;
388
+                button = getButton(selected);
389
+                if (selected != null && button != null) {
390
+                    button.setSelected(false);
367 391
                 }
368 392
 
369 393
                 selected = window;
370
-
371
-                if (buttons.containsKey(window)) {
372
-                    buttons.get(window).setSelected(true);
394
+                button = getButton(window);
395
+                if (button != null) {
396
+                    button.setSelected(true);
373 397
                 }
374 398
             }
375 399
         });
@@ -383,8 +407,9 @@ public final class ButtonBar implements FrameManager, ActionListener,
383 407
             /** {@inheritDoc} */
384 408
             @Override
385 409
             public void run() {
386
-                if (buttons.containsKey(window)) {
387
-                    buttons.get(window).setIcon(IconManager.getIconManager().getIcon(icon));
410
+                final FrameToggleButton button = getButton(window);
411
+                if (button != null) {
412
+                    button.setIcon(IconManager.getIconManager().getIcon(icon));
388 413
                 }
389 414
             }
390 415
         });
@@ -398,8 +423,9 @@ public final class ButtonBar implements FrameManager, ActionListener,
398 423
             /** {@inheritDoc} */
399 424
             @Override
400 425
             public void run() {
401
-                if (buttons.containsKey(window)) {
402
-                    buttons.get(window).setText(name);
426
+                final FrameToggleButton button = getButton(window);
427
+                if (button != null) {
428
+                    button.setText(name);
403 429
                 }
404 430
             }
405 431
         });
@@ -410,4 +436,55 @@ public final class ButtonBar implements FrameManager, ActionListener,
410 436
     public void titleChanged(final FrameContainer<?> window, final String title) {
411 437
         // Do nothing
412 438
     }
439
+
440
+    /**
441
+     * Creates and displays a Popup menu for the button that was clicked.
442
+     *
443
+     * @param e MouseEvent for this event
444
+     */
445
+    public void processMouseEvents(MouseEvent e) {
446
+        if (e.isPopupTrigger()) {
447
+            final FrameToggleButton button = (FrameToggleButton) e.getSource();
448
+
449
+            TextFrame frame = (TextFrame) button.getWindow();
450
+            if (frame == null) {
451
+                return;
452
+            }
453
+            final JPopupMenu popupMenu = frame.getPopupMenu(null, "");
454
+            frame.addCustomPopupItems(popupMenu);
455
+            popupMenu.add(new JMenuItem(new CloseFrameContainerAction(frame.
456
+                        getContainer())));
457
+            popupMenu.show(button, e.getX(), e.getY());
458
+        }
459
+    }
460
+
461
+    /** {@inheritDoc} */
462
+    @Override
463
+    public void mouseClicked(MouseEvent e) {
464
+        processMouseEvents(e);
465
+    }
466
+
467
+    /** {@inheritDoc} */
468
+    @Override
469
+    public void mousePressed(MouseEvent e) {
470
+        processMouseEvents(e);
471
+    }
472
+
473
+    /** {@inheritDoc} */
474
+    @Override
475
+    public void mouseReleased(MouseEvent e) {
476
+        processMouseEvents(e);
477
+    }
478
+
479
+    /** {@inheritDoc} */
480
+    @Override
481
+    public void mouseEntered(MouseEvent e) {
482
+        //Do nothing
483
+    }
484
+
485
+    /** {@inheritDoc} */
486
+    @Override
487
+    public void mouseExited(MouseEvent e) {
488
+        //Do nothing
489
+    }
413 490
 }

+ 65
- 0
src/com/dmdirc/addons/ui_swing/framemanager/buttonbar/FrameToggleButton.java ファイルの表示

@@ -0,0 +1,65 @@
1
+/*
2
+ * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes,
3
+ * Simon Mott
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in
13
+ * all copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ */
23
+package com.dmdirc.addons.ui_swing.framemanager.buttonbar;
24
+
25
+import com.dmdirc.FrameContainer;
26
+import com.dmdirc.ui.interfaces.Window;
27
+import javax.swing.Icon;
28
+import javax.swing.JToggleButton;
29
+
30
+/**
31
+ * Custom toggle button that contains Window information for this button.
32
+ *
33
+ * @author Simon Mott
34
+ * @since 0.6.4
35
+ */
36
+public class FrameToggleButton extends JToggleButton {
37
+
38
+    /** Contains the window associated with this button. */
39
+    private final Window window;
40
+
41
+    /** Create a new instance of FrameToggleButton. */
42
+    public FrameToggleButton(final String text, final Icon icon, final Window window) {
43
+        super(text, icon);
44
+        this.window = window;
45
+    }
46
+
47
+    /**
48
+     * Returns the window associated with this button.
49
+     *
50
+     * @return Window associated with this button
51
+     */
52
+    public Window getWindow() {
53
+        return window;
54
+    }
55
+
56
+    /**
57
+     * Returns the FrameContainer associated with this button.
58
+     *
59
+     * @return FrameContainer associated with this button
60
+     */
61
+    public FrameContainer<?> getFrameContainer() {
62
+        return window.getContainer();
63
+    }
64
+
65
+}

読み込み中…
キャンセル
保存