File Source: ButtonBar.java
/*
P/P * Method: com.dmdirc.addons.ui_swing.framemanager.buttonbar.ButtonBar__static_init
*/
1 /*
2 * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22 package com.dmdirc.addons.ui_swing.framemanager.buttonbar;
23
24 import com.dmdirc.FrameContainer;
25 import com.dmdirc.FrameContainerComparator;
26 import com.dmdirc.config.IdentityManager;
27 import com.dmdirc.interfaces.IconChangeListener;
28 import com.dmdirc.interfaces.NotificationListener;
29 import com.dmdirc.interfaces.SelectionListener;
30 import com.dmdirc.ui.interfaces.FrameManager;
31 import com.dmdirc.ui.interfaces.FramemanagerPosition;
32 import com.dmdirc.ui.interfaces.Window;
33 import com.dmdirc.addons.ui_swing.UIUtilities;
34 import com.dmdirc.util.MapList;
35
36 import java.awt.Color;
37 import java.awt.Dimension;
38 import java.awt.Insets;
39 import java.awt.event.ActionEvent;
40 import java.awt.event.ActionListener;
41 import java.awt.event.ComponentEvent;
42 import java.awt.event.ComponentListener;
43 import java.io.Serializable;
44 import java.util.Collections;
45 import java.util.HashMap;
46 import java.util.List;
47 import java.util.Map;
48
49 import javax.swing.Icon;
50 import javax.swing.JComponent;
51 import javax.swing.JPanel;
52 import javax.swing.JToggleButton;
53 import javax.swing.SwingConstants;
54
55 import net.miginfocom.swing.MigLayout;
56
57 /**
58 * The button bar manager is a grid of buttons that presents a manager similar
59 * to that used by mIRC.
60 *
61 * @author chris
62 */
63 public final class ButtonBar implements FrameManager, ActionListener,
64 ComponentListener, Serializable, NotificationListener,
65 SelectionListener, IconChangeListener {
66
67 /**
68 * A version number for this class. It should be changed whenever the class
69 * structure is changed (or anything else that would prevent serialized
70 * objects being unserialized with the new class).
71 */
72 private static final long serialVersionUID = 3;
73 /** A map of parent containers to their respective windows. */
74 private final MapList<FrameContainer, FrameContainer> windows;
75 /** A map of containers to the buttons we're using for them. */
76 private final Map<FrameContainer, JToggleButton> buttons;
77 /** The position of this frame manager. */
78 private final FramemanagerPosition position;
79 /** The parent for the manager. */
80 private JComponent parent;
81 /** The panel used for our buttons. */
82 private final JPanel panel;
83 /** The currently selected window. */
84 private transient FrameContainer selected;
85 /** Selected window. */
86 private Window activeWindow;
87 /** The number of buttons per row or column. */
88 private int cells = 1;
89 /** The number of buttons to render per {cell,row}. */
90 private int maxButtons = Integer.MAX_VALUE;
91 /** The width of buttons. */
92 private int buttonWidth;
93
94 /** Creates a new instance of DummyFrameManager. */
/*
P/P * Method: void com.dmdirc.addons.ui_swing.framemanager.buttonbar.ButtonBar()
*
* Preconditions:
* init'ed(com/dmdirc/config/IdentityManager.globalconfig)
* (soft) init'ed(com.dmdirc.config.ConfigManager$1__static_init.new int[](ConfigManager$1__static_init#1)[...])
*
* Presumptions:
* com.dmdirc.ui.interfaces.FramemanagerPosition:getPosition(...)@98 != null
* getGlobalConfig(...).sources != null
*
* Postconditions:
* com/dmdirc/config/IdentityManager.globalconfig == One-of{old com/dmdirc/config/IdentityManager.globalconfig, &new ConfigManager(getGlobalConfig#1)}
* com/dmdirc/config/IdentityManager.globalconfig != null
* java.lang.StringBuilder:toString(...)._tainted == 0
* this.buttons == &new HashMap(ButtonBar#2)
* this.cells == 1
* new HashMap(ButtonBar#2) num objects == 1
* new MapList(ButtonBar#1) num objects == 1
* this.maxButtons == 231-1
* this.panel in Addr_Set{&new JPanel(ButtonBar#5),&new JPanel(ButtonBar#3)}
* this.position != null
* ...
*
* Test Vectors:
* com.dmdirc.ui.interfaces.FramemanagerPosition:isHorizontal(...)@101: {0}, {1}
*/
95 public ButtonBar() {
96 windows = new MapList<FrameContainer, FrameContainer>();
97 buttons = new HashMap<FrameContainer, JToggleButton>();
98 position = FramemanagerPosition.getPosition(
99 IdentityManager.getGlobalConfig().getOption("ui", "framemanagerPosition"));
100
101 if (position.isHorizontal()) {
102 panel = new JPanel(new MigLayout("ins 0, fill, flowx"));
103 } else {
104 panel = new JPanel(new MigLayout("ins 0, fill, flowy"));
105 }
106 }
107
108 /** {@inheritDoc} */
109 @Override
110 public void setParent(final JComponent parent) {
/*
P/P * Method: void setParent(JComponent)
*
* Preconditions:
* parent != null
* this.position != null
* (soft) this.cells != 0
*
* Presumptions:
* (javax.swing.JComponent:getWidth(...)@116 - 15)/this.cells in {-231..-11, -9..4_294_967_280}
* javax.swing.JComponent:getWidth(...)@119/(150 + 10) in {-231..232-1}
*
* Postconditions:
* this.buttonWidth in {-231..-11, -9..4_294_967_280}
* possibly_updated(this.maxButtons)
* this.parent == parent
* this.parent != null
*
* Test Vectors:
* com.dmdirc.ui.interfaces.FramemanagerPosition:isHorizontal(...)@118: {0}, {1}
*/
111 this.parent = parent;
112
113 parent.setLayout(new MigLayout());
114 parent.add(panel);
115
116 buttonWidth = position.isHorizontal() ? 150 : (parent.getWidth() - UIUtilities.SMALL_BORDER * 3) / cells;
117
118 if (position.isHorizontal()) {
119 maxButtons = parent.getWidth() / (buttonWidth + UIUtilities.SMALL_BORDER * 2);
120 }
121
122 parent.addComponentListener(this);
123 }
124
125 /**
126 * Removes all buttons from the bar and readds them.
127 */
128 private void relayout() {
/*
P/P * Method: void relayout()
*
* Preconditions:
* this.panel != null
* this.windows != null
* (soft) init'ed(this.buttonWidth)
* (soft) this.buttons != null
*
* Presumptions:
* com.dmdirc.util.MapList:entrySet(...)@131 != null
* java.util.Iterator:next(...)@131 != null
* java.util.Map:get(...)@132 != null
* java.util.Map:get(...)@133 != null
* java.util.Map:get(...)@139 != null
* ...
*
* Test Vectors:
* java.util.Iterator:hasNext(...)@131: {0}, {1}
* java.util.Iterator:hasNext(...)@138: {0}, {1}
*/
129 panel.removeAll();
130
131 for (Map.Entry<FrameContainer, List<FrameContainer>> entry : windows.entrySet()) {
132 buttons.get(entry.getKey()).setPreferredSize(new Dimension(buttonWidth, 25));
133 buttons.get(entry.getKey()).setMinimumSize(new Dimension(buttonWidth, 25));
134 panel.add(buttons.get(entry.getKey()));
135
136 Collections.sort(entry.getValue(), new FrameContainerComparator());
137
138 for (FrameContainer child : entry.getValue()) {
139 buttons.get(child).setPreferredSize(new Dimension(buttonWidth, 25));
140 buttons.get(child).setMinimumSize(new Dimension(buttonWidth, 25));
141 panel.add(buttons.get(child));
142 }
143 }
144 panel.validate();
145 }
146
147 /**
148 * Adds a button to the button array with the details from the specified
149 * container.
150 *
151 * @param source The Container to get title/icon info from
152 */
153 private void addButton(final FrameContainer source) {
/*
P/P * Method: void addButton(FrameContainer)
*
* Preconditions:
* source != null
* this.buttons != null
*/
154 final JToggleButton button = new JToggleButton(source.toString(), source.getIcon());
155
156 button.addActionListener(this);
157 button.setHorizontalAlignment(SwingConstants.LEFT);
158 button.setMargin(new Insets(0, 0, 0, 0));
159
160 buttons.put(source, button);
161 }
162
163 /** {@inheritDoc} */
164 @Override
165 public boolean canPositionVertically() {
/*
P/P * Method: bool canPositionVertically()
*
* Postconditions:
* return_value == 1
*/
166 return true;
167 }
168
169 /** {@inheritDoc} */
170 @Override
171 public boolean canPositionHorizontally() {
/*
P/P * Method: bool canPositionHorizontally()
*
* Postconditions:
* return_value == 1
*/
172 return true;
173 }
174
175 /** {@inheritDoc} */
176 @Override
177 public void addWindow(final FrameContainer window) {
/*
P/P * Method: void addWindow(FrameContainer)
*
* Preconditions:
* this.buttons != null
* this.panel != null
* this.windows != null
* window != null
* (soft) init'ed(this.buttonWidth)
*/
178 windows.add(window);
179 addButton(window);
180
181 relayout();
182 window.addNotificationListener(this);
183 window.addSelectionListener(this);
184 window.addIconChangeListener(this);
185 }
186
187 /** {@inheritDoc} */
188 @Override
189 public void delWindow(final FrameContainer window) {
/*
P/P * Method: void delWindow(FrameContainer)
*
* Preconditions:
* this.panel != null
* this.windows != null
* window != null
* (soft) init'ed(this.buttonWidth)
* (soft) this.buttons != null
*/
190 windows.remove(window);
191
192 relayout();
193 window.removeNotificationListener(this);
194 window.removeIconChangeListener(this);
195 window.removeSelectionListener(this);
196 }
197
198 /** {@inheritDoc} */
199 @Override
200 public void addWindow(final FrameContainer parent, final FrameContainer window) {
/*
P/P * Method: void addWindow(FrameContainer, FrameContainer)
*
* Preconditions:
* this.buttons != null
* this.panel != null
* this.windows != null
* window != null
* (soft) init'ed(this.buttonWidth)
*/
201 windows.add(parent, window);
202 addButton(window);
203
204 relayout();
205 window.addNotificationListener(this);
206 window.addSelectionListener(this);
207 window.addIconChangeListener(this);
208 }
209
210 /** {@inheritDoc} */
211 @Override
212 public void delWindow(final FrameContainer parent, final FrameContainer window) {
/*
P/P * Method: void delWindow(FrameContainer, FrameContainer)
*
* Preconditions:
* this.panel != null
* this.windows != null
* window != null
* (soft) init'ed(this.buttonWidth)
* (soft) this.buttons != null
*/
213 windows.remove(parent, window);
214
215 relayout();
216 window.removeNotificationListener(this);
217 window.removeIconChangeListener(this);
218 window.removeSelectionListener(this);
219 }
220
221 /**
222 * Called when the user clicks on one of the buttons.
223 *
224 * @param e The action event associated with this action
225 */
226 @Override
227 public void actionPerformed(final ActionEvent e) {
/*
P/P * Method: void actionPerformed(ActionEvent)
*
* Preconditions:
* this.buttons != null
* (soft) e != null
* (soft) init'ed(this.activeWindow)
*
* Presumptions:
* com.dmdirc.FrameContainer:getFrame(...)@230 != null
* java.util.Iterator:next(...)@228 != null
* java.util.Map:entrySet(...)@228 != null
* java.util.Map_Entry:getKey(...)@230 != null
* java.util.Map_Entry:getKey(...)@234 != null
* ...
*
* Test Vectors:
* java.lang.Object:equals(...)@229: {0}, {1}
* java.lang.Object:equals(...)@230: {0}, {1}
* java.util.Iterator:hasNext(...)@228: {0}, {1}
*/
228 for (Map.Entry<FrameContainer, JToggleButton> entry : buttons.entrySet()) {
229 if (entry.getValue().equals(e.getSource())) {
230 if (entry.getKey().getFrame().equals(activeWindow)) {
231 entry.getValue().setSelected(true);
232 }
233
234 entry.getKey().activateFrame();
235 }
236 }
237 }
238
239 /**
240 * Called when the parent component is resized.
241 *
242 * @param e A ComponentEvent corresponding to this event.
243 */
244 @Override
245 public void componentResized(final ComponentEvent e) {
/*
P/P * Method: void componentResized(ComponentEvent)
*
* Preconditions:
* this.panel != null
* this.position != null
* this.windows != null
* (soft) this.buttons != null
* (soft) this.cells != 0
* (soft) this.parent != null
*
* Presumptions:
* (javax.swing.JComponent:getWidth(...)@246 - 15)/this.cells in {-231..-11, -9..4_294_967_280}
* javax.swing.JComponent:getWidth(...)@249/(150 + 10) in {-231..232-1}
*
* Postconditions:
* this.buttonWidth in {-231..-11, -9..4_294_967_280}
* possibly_updated(this.maxButtons)
*
* Test Vectors:
* com.dmdirc.ui.interfaces.FramemanagerPosition:isHorizontal(...)@248: {0}, {1}
*/
246 buttonWidth = position.isHorizontal() ? 150 : (parent.getWidth() - UIUtilities.SMALL_BORDER * 3) / cells;
247
248 if (position.isHorizontal()) {
249 maxButtons = parent.getWidth() / (buttonWidth + UIUtilities.SMALL_BORDER * 2);
250 }
251
252 relayout();
253 }
254
255 /**
256 * Called when the parent component is moved.
257 *
258 * @param e A ComponentEvent corresponding to this event.
259 */
260 @Override
261 public void componentMoved(final ComponentEvent e) {
262 // Do nothing
/*
P/P * Method: void componentMoved(ComponentEvent)
*/
263 }
264
265 /**
266 * Called when the parent component is made visible.
267 *
268 * @param e A ComponentEvent corresponding to this event.
269 */
270 @Override
271 public void componentShown(final ComponentEvent e) {
272 // Do nothing
/*
P/P * Method: void componentShown(ComponentEvent)
*/
273 }
274
275 /**
276 * Called when the parent component is made invisible.
277 *
278 * @param e A ComponentEvent corresponding to this event.
279 */
280 @Override
281 public void componentHidden(final ComponentEvent e) {
282 // Do nothing
/*
P/P * Method: void componentHidden(ComponentEvent)
*/
283 }
284
285 /** {@inheritDoc} */
286 @Override
287 public void notificationSet(final Window window, final Color colour) {
/*
P/P * Method: void notificationSet(Window, Color)
*
* Preconditions:
* this.buttons != null
* window != null
*
* Presumptions:
* java.util.Map:get(...)@289 != null
*
* Test Vectors:
* java.util.Map:containsKey(...)@288: {0}, {1}
*/
288 if (buttons.containsKey(window.getContainer())) {
289 buttons.get(window.getContainer()).setForeground(colour);
290 }
291 }
292
293 /** {@inheritDoc} */
294 @Override
295 public void notificationCleared(final Window window) {
/*
P/P * Method: void notificationCleared(Window)
*
* Preconditions:
* this.buttons != null
* window != null
*
* Presumptions:
* com.dmdirc.ui.interfaces.Window:getContainer(...)@296 != null
*/
296 notificationSet(window, window.getContainer().getNotification());
297 }
298
299 /** {@inheritDoc} */
300 @Override
301 public void selectionChanged(final Window window) {
/*
P/P * Method: void selectionChanged(Window)
*
* Preconditions:
* init'ed(this.selected)
* this.buttons != null
* window != null
*
* Presumptions:
* java.util.Map:get(...)@304 != null
* java.util.Map:get(...)@310 != null
*
* Postconditions:
* this.activeWindow == window
* this.activeWindow != null
* init'ed(this.selected)
*
* Test Vectors:
* this.selected: Addr_Set{null}, Inverse{null}
* java.util.Map:containsKey(...)@303: {0}, {1}
* java.util.Map:containsKey(...)@309: {0}, {1}
*/
302 activeWindow = window;
303 if (selected != null && buttons.containsKey(selected)) {
304 buttons.get(selected).setSelected(false);
305 }
306
307 selected = window.getContainer();
308
309 if (buttons.containsKey(window.getContainer())) {
310 buttons.get(window.getContainer()).setSelected(true);
311 }
312 }
313
314 /** {@inheritDoc} */
315 @Override
316 public void iconChanged(final Window window, final Icon icon) {
/*
P/P * Method: void iconChanged(Window, Icon)
*
* Preconditions:
* this.buttons != null
* window != null
*
* Presumptions:
* java.util.Map:get(...)@317 != null
*/
317 buttons.get(window.getContainer()).setIcon(icon);
318 }
319 }
SofCheck Inspector Build Version : 2.17854
| ButtonBar.java |
2009-Jun-25 01:54:24 |
| ButtonBar.class |
2009-Sep-02 17:04:16 |