source: src/main/java/genius/gui/panels/tab/CloseTabbedPane.java

Last change on this file was 1, checked in by Wouter Pasman, 6 years ago

Initial import : Genius 9.0.0

File size: 10.7 KB
Line 
1/*
2 * To change this template, choose Tools | Templates
3 * and open the template in the editor.
4 */
5
6package genius.gui.panels.tab;
7
8import java.awt.Window;
9import java.awt.event.MouseEvent;
10import java.awt.event.WindowAdapter;
11import java.awt.event.WindowEvent;
12import java.awt.event.WindowFocusListener;
13import java.io.Serializable;
14import java.util.EventListener;
15
16import javax.swing.Icon;
17import javax.swing.JComponent;
18import javax.swing.JFrame;
19import javax.swing.JTabbedPane;
20import javax.swing.SwingUtilities;
21import javax.swing.border.Border;
22import javax.swing.event.EventListenerList;
23import javax.swing.plaf.TabbedPaneUI;
24
25/**
26 * A JTabbedPane with some added UI functionalities. A close and max/detach
27 * icons are added to every tab, typically to let the user close or detach the
28 * tab by clicking on these icons.
29 *
30 * @version 1.1 06/07/04
31 * @author David Bismut, davidou@mageos.com
32 */
33
34public class CloseTabbedPane extends JTabbedPane implements Serializable {
35
36 private static final long serialVersionUID = -819489825604971110L;
37
38 private int overTabIndex = -1;
39
40 private CloseTabPaneUI paneUI;
41
42 // private CloseTabProxyUI paneUI;
43
44 /**
45 * Creates the <code>CloseAndMaxTabbedPane</code> with an enhanced UI if
46 * <code>enhancedUI</code> parameter is set to <code>true</code>.
47 */
48 public CloseTabbedPane() {
49 super.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
50
51 paneUI = new CloseTabPaneEnhancedUI();
52 // paneUI = (CloseTabProxyUI) CloseTabProxyUI.createUI(this);//new
53 // CloseTabProxyUI((TabbedPaneUI)UIManager.getUI(this));
54
55 super.setUI(paneUI);
56 }
57
58 /**
59 * Returns the index of the last tab on which the mouse did an action.
60 */
61 public int getOverTabIndex() {
62 return overTabIndex;
63 }
64
65 /**
66 * Returns <code>true</code> if the close icon is enabled.
67 */
68 public boolean isCloseEnabled() {
69 return paneUI.isCloseEnabled();
70 }
71
72 /**
73 * Override JTabbedPane method. Does nothing.
74 */
75 public void setTabLayoutPolicy(int tabLayoutPolicy) {
76 }
77
78 /**
79 * Override JTabbedPane method. Does nothing.
80 */
81 public void setTabPlacement(int tabPlacement) {
82 }
83
84 /**
85 * Override JTabbedPane method. Does nothing.
86 */
87 public void setUI(TabbedPaneUI ui) {
88 }
89
90 /**
91 * Sets whether the tabbedPane should have a close icon or not.
92 *
93 * @param b
94 * whether the tabbedPane should have a close icon or not
95 */
96 public void setCloseIcon(boolean b) {
97 paneUI.setCloseIcon(b);
98 }
99
100 /**
101 * Detaches the <code>index</code> tab in a seperate frame. When the frame
102 * is closed, the tab is automatically reinserted into the tabbedPane.
103 *
104 * @param index
105 * index of the tabbedPane to be detached
106 */
107 public void detachTab(int index) {
108
109 if (index < 0 || index >= getTabCount())
110 return;
111
112 final JFrame frame = new JFrame();
113
114 Window parentWindow = SwingUtilities.windowForComponent(this);
115
116 final int tabIndex = index;
117 final JComponent c = (JComponent) getComponentAt(tabIndex);
118
119 final Icon icon = getIconAt(tabIndex);
120 final String title = getTitleAt(tabIndex);
121 final String toolTip = getToolTipTextAt(tabIndex);
122 final Border border = c.getBorder();
123
124 removeTabAt(index);
125
126 c.setPreferredSize(c.getSize());
127
128 frame.setTitle(title);
129 frame.getContentPane().add(c);
130 frame.setLocation(parentWindow.getLocation());
131 frame.pack();
132
133 frame.addWindowListener(new WindowAdapter() {
134 public void windowClosing(WindowEvent event) {
135 frame.dispose();
136
137 insertTab(title, icon, c, toolTip,
138 Math.min(tabIndex, getTabCount()));
139
140 c.setBorder(border);
141 setSelectedComponent(c);
142 }
143
144 });
145
146 WindowFocusListener windowFocusListener = new WindowFocusListener() {
147 long start;
148
149 long end;
150
151 public void windowGainedFocus(WindowEvent e) {
152 start = System.currentTimeMillis();
153 }
154
155 public void windowLostFocus(WindowEvent e) {
156 end = System.currentTimeMillis();
157 long elapsed = end - start;
158 // System.out.println(elapsed);
159 if (elapsed < 100)
160 frame.toFront();
161
162 frame.removeWindowFocusListener(this);
163 }
164 };
165
166 /*
167 * This is a small hack to avoid Windows GUI bug, that prevent a new
168 * window from stealing focus (without this windowFocusListener, most of
169 * the time the new frame would just blink from foreground to
170 * background). A windowFocusListener is added to the frame, and if the
171 * time between the frame beeing in foreground and the frame beeing in
172 * background is less that 100ms, it just brings the windows to the
173 * front once again. Then it removes the windowFocusListener. Note that
174 * this hack would not be required on Linux or UNIX based systems.
175 */
176
177 frame.addWindowFocusListener(windowFocusListener);
178
179 frame.setVisible(true);
180 frame.toFront();
181
182 }
183
184 /**
185 * Adds a <code>CloseListener</code> to the tabbedPane.
186 *
187 * @param l
188 * the <code>CloseListener</code> to add
189 * @see #fireCloseTabEvent
190 * @see #removeCloseListener
191 */
192 public synchronized void addCloseListener(CloseListener l) {
193 listenerList.add(CloseListener.class, l);
194 }
195
196 /**
197 * Adds a <code>MaxListener</code> to the tabbedPane.
198 *
199 * @param l
200 * the <code>MaxListener</code> to add
201 * @see #fireMaxTabEvent
202 * @see #removeMaxListener
203 */
204 public synchronized void addMaxListener(MaxListener l) {
205 listenerList.add(MaxListener.class, l);
206 }
207
208 /**
209 * Adds a <code>DoubleClickListener</code> to the tabbedPane.
210 *
211 * @param l
212 * the <code>DoubleClickListener</code> to add
213 * @see #fireDoubleClickTabEvent
214 * @see #removeDoubleClickListener
215 */
216 public synchronized void addDoubleClickListener(DoubleClickListener l) {
217 listenerList.add(DoubleClickListener.class, l);
218 }
219
220 /**
221 * Adds a <code>PopupOutsideListener</code> to the tabbedPane.
222 *
223 * @param l
224 * the <code>PopupOutsideListener</code> to add
225 * @see #firePopupOutsideTabEvent
226 * @see #removePopupOutsideListener
227 */
228 public synchronized void addPopupOutsideListener(PopupOutsideListener l) {
229 listenerList.add(PopupOutsideListener.class, l);
230 }
231
232 /**
233 * Removes a <code>CloseListener</code> from this tabbedPane.
234 *
235 * @param l
236 * the <code>CloseListener</code> to remove
237 * @see #fireCloseTabEvent
238 * @see #addCloseListener
239 */
240 public synchronized void removeCloseListener(CloseListener l) {
241 listenerList.remove(CloseListener.class, l);
242 }
243
244 /**
245 * Removes a <code>MaxListener</code> from this tabbedPane.
246 *
247 * @param l
248 * the <code>MaxListener</code> to remove
249 * @see #fireMaxTabEvent
250 * @see #addMaxListener
251 */
252 public synchronized void removeMaxListener(MaxListener l) {
253 listenerList.remove(MaxListener.class, l);
254 }
255
256 /**
257 * Removes a <code>DoubleClickListener</code> from this tabbedPane.
258 *
259 * @param l
260 * the <code>DoubleClickListener</code> to remove
261 * @see #fireDoubleClickTabEvent
262 * @see #addDoubleClickListener
263 */
264 public synchronized void removeDoubleClickListener(DoubleClickListener l) {
265 listenerList.remove(DoubleClickListener.class, l);
266 }
267
268 /**
269 * Removes a <code>PopupOutsideListener</code> from this tabbedPane.
270 *
271 * @param l
272 * the <code>PopupOutsideListener</code> to remove
273 * @see #firePopupOutsideTabEvent
274 * @see #addPopupOutsideListener
275 */
276 public synchronized void removePopupOutsideListener(PopupOutsideListener l) {
277 listenerList.remove(PopupOutsideListener.class, l);
278 }
279
280 /**
281 * Sends a <code>MouseEvent</code>, whose source is this tabbedpane, to
282 * every <code>CloseListener</code>. The method also updates the
283 * <code>overTabIndex</code> of the tabbedPane with a value coming from the
284 * UI. This method method is called each time a <code>MouseEvent</code> is
285 * received from the UI when the user clicks on the close icon of the tab
286 * which index is <code>overTabIndex</code>.
287 *
288 * @param e
289 * the <code>MouseEvent</code> to be sent
290 * @param overTabIndex
291 * the index of a tab, usually the tab over which the mouse is
292 *
293 * @see #addCloseListener
294 * @see EventListenerList
295 */
296 public void fireCloseTabEvent(MouseEvent e, int overTabIndex) {
297 this.overTabIndex = overTabIndex;
298
299 EventListener closeListeners[] = getListeners(CloseListener.class);
300 for (int i = 0; i < closeListeners.length; i++) {
301 ((CloseListener) closeListeners[i]).closeOperation(e, overTabIndex);
302 }
303 }
304
305 /**
306 * Sends a <code>MouseEvent</code>, whose source is this tabbedpane, to
307 * every <code>MaxListener</code>. The method also updates the
308 * <code>overTabIndex</code> of the tabbedPane with a value coming from the
309 * UI. This method method is called each time a <code>MouseEvent</code> is
310 * received from the UI when the user clicks on the max icon of the tab
311 * which index is <code>overTabIndex</code>.
312 *
313 * @param e
314 * the <code>MouseEvent</code> to be sent
315 * @param overTabIndex
316 * the index of a tab, usually the tab over which the mouse is
317 *
318 * @see #addMaxListener
319 * @see EventListenerList
320 */
321 public void fireMaxTabEvent(MouseEvent e, int overTabIndex) {
322 this.overTabIndex = overTabIndex;
323
324 EventListener maxListeners[] = getListeners(MaxListener.class);
325 for (int i = 0; i < maxListeners.length; i++) {
326 ((MaxListener) maxListeners[i]).maxOperation(e);
327 }
328 }
329
330 /**
331 * Sends a <code>MouseEvent</code>, whose source is this tabbedpane, to
332 * every <code>DoubleClickListener</code>. The method also updates the
333 * <code>overTabIndex</code> of the tabbedPane with a value coming from the
334 * UI. This method method is called each time a <code>MouseEvent</code> is
335 * received from the UI when the user double-clicks on the tab which index
336 * is <code>overTabIndex</code>.
337 *
338 * @param e
339 * the <code>MouseEvent</code> to be sent
340 * @param overTabIndex
341 * the index of a tab, usually the tab over which the mouse is
342 *
343 * @see #addDoubleClickListener
344 * @see EventListenerList
345 */
346 public void fireDoubleClickTabEvent(MouseEvent e, int overTabIndex) {
347 this.overTabIndex = overTabIndex;
348
349 EventListener dClickListeners[] = getListeners(DoubleClickListener.class);
350 for (int i = 0; i < dClickListeners.length; i++) {
351 ((DoubleClickListener) dClickListeners[i]).doubleClickOperation(e);
352 }
353 }
354
355 /**
356 * Sends a <code>MouseEvent</code>, whose source is this tabbedpane, to
357 * every <code>PopupOutsideListener</code>. The method also sets the
358 * <code>overTabIndex</code> to -1. This method method is called each time a
359 * <code>MouseEvent</code> is received from the UI when the user
360 * right-clicks on the inactive part of a tabbedPane.
361 *
362 * @param e
363 * the <code>MouseEvent</code> to be sent
364 *
365 * @see #addPopupOutsideListener
366 * @see EventListenerList
367 */
368 public void firePopupOutsideTabEvent(MouseEvent e) {
369 this.overTabIndex = -1;
370
371 EventListener popupListeners[] = getListeners(PopupOutsideListener.class);
372 for (int i = 0; i < popupListeners.length; i++) {
373 ((PopupOutsideListener) popupListeners[i]).popupOutsideOperation(e);
374 }
375 }
376
377}
Note: See TracBrowser for help on using the repository browser.