001: /*
002: * Copyright (C) 2005 - 2008 JasperSoft Corporation. All rights reserved.
003: * http://www.jaspersoft.com.
004: *
005: * Unless you have purchased a commercial license agreement from JasperSoft,
006: * the following license terms apply:
007: *
008: * This program is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU General Public License version 2 as published by
010: * the Free Software Foundation.
011: *
012: * This program is distributed WITHOUT ANY WARRANTY; and without the
013: * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
014: * See the GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, see http://www.gnu.org/licenses/gpl.txt
018: * or write to:
019: *
020: * Free Software Foundation, Inc.,
021: * 59 Temple Place - Suite 330,
022: * Boston, MA USA 02111-1307
023: *
024: *
025: *
026: *
027: * ExtendedTabbedPane.java
028: *
029: * Created on March 18, 2006, 8:17 PM
030: *
031: */
032:
033: package it.businesslogic.ireport.gui.docking;
034:
035: import it.businesslogic.ireport.gui.event.TabPaneChangedEvent;
036: import java.awt.Component;
037:
038: import javax.swing.*;
039: import javax.swing.event.ChangeEvent;
040: import javax.swing.event.ChangeListener;
041: import javax.swing.plaf.ColorUIResource;
042: import javax.swing.plaf.basic.BasicTabbedPaneUI;
043: import java.awt.*;
044: import java.awt.event.AWTEventListener;
045: import java.awt.event.MouseEvent;
046: import javax.swing.text.TabExpander;
047:
048: // #21380.
049: /**
050: * Copy of original ExtendedTabbedPane from the NetBeans 3.4 winsys. Old code never dies.
051: *
052: * @author Tran Duc Trung
053: *
054: */
055: class ExtendedTabbedPane extends JTabbedPane implements ChangeListener,
056: Runnable {
057:
058: private final Image closeTabImage = (new javax.swing.ImageIcon(
059: getClass()
060: .getResource(
061: "/it/businesslogic/ireport/icons/docking/tabclose.png")))
062: .getImage();
063: private final Image closeTabInactiveImage = (new javax.swing.ImageIcon(
064: getClass()
065: .getResource(
066: "/it/businesslogic/ireport/icons/docking/tabcloseinactive.png")))
067: .getImage();
068: private final Image closeTabActiveImage = (new javax.swing.ImageIcon(
069: getClass()
070: .getResource(
071: "/it/businesslogic/ireport/icons/docking/tabcloseactive.png")))
072: .getImage();
073:
074: private final Image minimizeTabImage = (new javax.swing.ImageIcon(
075: getClass()
076: .getResource(
077: "/it/businesslogic/ireport/icons/docking/tabminimize.png")))
078: .getImage();
079: private final Image minimizeTabInactiveImage = (new javax.swing.ImageIcon(
080: getClass()
081: .getResource(
082: "/it/businesslogic/ireport/icons/docking/tabminimizeinactive.png")))
083: .getImage();
084: private final Image minimizeTabActiveImage = (new javax.swing.ImageIcon(
085: getClass()
086: .getResource(
087: "/it/businesslogic/ireport/icons/docking/tabminimizeactive.png")))
088: .getImage();
089:
090: // List of index of tabs without the close button...
091: private java.util.List disabledCloseButtons = new java.util.ArrayList();
092:
093: private int orientation = DockingContainer.POSITION_LEFT;
094:
095: ExtendedTabbedPane() {
096: addChangeListener(this );
097:
098: CloseButtonListener.install();
099: MinimizeButtonListener.install();
100:
101: //Bugfix #28263: Disable focus.
102: setFocusable(false);
103: setBorder(javax.swing.BorderFactory.createEmptyBorder());
104: setFocusCycleRoot(true);
105: setFocusTraversalPolicy(new CBTPPolicy());
106: }
107:
108: private Component sel() {
109: Component c = getSelectedComponent();
110: return c == null ? this : c;
111: }
112:
113: private class CBTPPolicy extends FocusTraversalPolicy {
114: public Component getComponentAfter(Container aContainer,
115: Component aComponent) {
116: return sel();
117: }
118:
119: public Component getComponentBefore(Container aContainer,
120: Component aComponent) {
121: return sel();
122: }
123:
124: public Component getFirstComponent(Container aContainer) {
125: return sel();
126: }
127:
128: public Component getLastComponent(Container aContainer) {
129: return sel();
130: }
131:
132: public Component getDefaultComponent(Container aContainer) {
133: return sel();
134: }
135: }
136:
137: public int tabForCoordinate(int x, int y) {
138: return getUI().tabForCoordinate(this , x, y);
139: }
140:
141: private int pressedCloseButtonIndex = -1;
142: private int mouseOverCloseButtonIndex = -1;
143:
144: private int pressedMinimizeButtonIndex = -1;
145: private int mouseOverMinimizeButtonIndex = -1;
146:
147: private boolean draggedOut = false;
148: private boolean draggedOutMinimize = false;
149:
150: public boolean isClosable(int tabIndex) {
151: return !disabledCloseButtons.contains(new Integer(tabIndex));
152: }
153:
154: public void stateChanged(ChangeEvent e) {
155: reset();
156: resetMinimized();
157: //if (getSelectedComponent() instanceof AbstractOutputPane) {
158: // ((AbstractOutputPane) getSelectedComponent()).ensureCaretPosition();
159: //}
160: }
161:
162: public Component add(Component c) {
163: Component result = super .add(c);
164: String s = c.getName();
165: if (s != null) {
166: s += " ";
167: }
168: setTitleAt(getComponentCount() - 1, s);
169: return result;
170: }
171:
172: public Component addTab(String s, Component c, boolean closeable) {
173: Component result = super .add(c);
174: if (!closeable) {
175: disabledCloseButtons.add(new Integer(
176: getComponentCount() - 1));
177: }
178: setTitleAt(getComponentCount() - 1, s);
179:
180: return result;
181: }
182:
183: public void setTitleAt(int idx, String title) {
184:
185: String s = title;
186: if (s == null)
187: s = "";
188: s = s.trim() + " ";
189: if (s != null) {
190: s += " ";
191: }
192:
193: if (isClosable(idx))
194: s += " ";
195:
196: if (!s.equals(getTitleAt(idx))) {
197: super .setTitleAt(idx, s);
198: }
199: }
200:
201: private void reset() {
202: setMouseOverCloseButtonIndex(-1);
203: setPressedCloseButtonIndex(-1);
204:
205: draggedOut = false;
206: }
207:
208: private void resetMinimized() {
209:
210: setMouseOverMinimizeButtonIndex(-1);
211: setPressedMinimizeButtonIndex(-1);
212: draggedOutMinimize = false;
213: }
214:
215: private Rectangle getCloseButtonBoundsAt(int i) {
216: Rectangle b = getBoundsAt(i);
217: if (b == null || disabledCloseButtons.contains(new Integer(i)))
218: return null;
219: else {
220: b = new Rectangle(b);
221: fixGetBoundsAt(b);
222:
223: Dimension tabsz = getSize();
224: if (b.x + b.width >= tabsz.width
225: || b.y + b.height >= tabsz.height)
226: return null;
227:
228: return new Rectangle(b.x + b.width - 14, b.y + b.height / 2
229: - 5, 8, 8);
230: }
231: }
232:
233: private Rectangle getMinimizeButtonBoundsAt(int i) {
234: Rectangle b = getBoundsAt(i);
235: if (b == null)
236: return null;
237: else {
238: b = new Rectangle(b);
239: fixGetBoundsAt(b);
240:
241: Dimension tabsz = getSize();
242: if (b.x + b.width >= tabsz.width
243: || b.y + b.height >= tabsz.height)
244: return null;
245:
246: return new Rectangle(
247: b.x
248: + b.width
249: - ((disabledCloseButtons
250: .contains(new Integer(i))) ? 12
251: : 24), b.y + b.height / 2 - 5, 8, 8);
252: }
253: }
254:
255: /** Checks whether current L&F sets used keys for colors.
256: * If not puts default values. */
257: private static void checkUIColors() {
258: if (UIManager.getColor("Button.shadow") == null) {
259: UIManager.put("Button.shadow", new ColorUIResource(153,
260: 153, 153));
261: }
262: if (UIManager.getColor("Button.darkShadow") == null) {
263: UIManager.put("Button.darkShadow", new ColorUIResource(102,
264: 102, 102));
265: }
266: if (UIManager.getColor("Button.highlight") == null) {
267: UIManager.put("Button.highlight", new ColorUIResource(
268: Color.white));
269: }
270: if (UIManager.getColor("Button.background") == null) {
271: UIManager.put("Button.background", new ColorUIResource(204,
272: 204, 204));
273: }
274: }
275:
276: public void paint(Graphics g) {
277: super .paint(g);
278:
279: // #29181 All L&F doesn't support the colors used.
280: checkUIColors();
281:
282: // Have a look at
283: // http://ui.netbeans.org/docs/ui/closeButton/closeButtonUISpec.html
284: // to see how the buttons are specified to be drawn.
285:
286: int selectedIndex = getSelectedIndex();
287: for (int i = 0, n = getTabCount(); i < n; i++) {
288:
289: drawButton(g, getMinimizeButtonBoundsAt(i),
290: pressedMinimizeButtonIndex,
291: minimizeTabInactiveImage, minimizeTabImage,
292: minimizeTabActiveImage, selectedIndex == i,
293: mouseOverMinimizeButtonIndex, i,
294: draggedOutMinimize, getOrientation() == 0);
295:
296: if (!disabledCloseButtons.contains(new Integer(i))) {
297: drawButton(g, getCloseButtonBoundsAt(i),
298: pressedCloseButtonIndex, closeTabInactiveImage,
299: closeTabImage, closeTabActiveImage,
300: selectedIndex == i, mouseOverCloseButtonIndex,
301: i, draggedOut, false);
302: }
303: }
304: }
305:
306: protected void drawButton(Graphics g, Rectangle r,
307: int pressedButtonIndex, Image tabInactiveImage,
308: Image tabImage, Image tabActiveImage, boolean selected,
309: int mouseOverButtonIndex, int tabIndex,
310: boolean isDraggedOut, boolean flipImage) {
311: if (r == null)
312: return;
313:
314: if (tabIndex == pressedButtonIndex && !isDraggedOut) {
315: g.setColor(UIManager.getColor("Button.shadow")); //NOI18N
316: g.fillRect(r.x, r.y, r.width, r.height);
317: }
318:
319: // img coords
320: int dx1 = (flipImage) ? r.x + r.width : r.x;
321: int dy1 = r.y;
322: int dx2 = (flipImage) ? r.x : r.x + r.width;
323: int dy2 = r.y + r.height;
324:
325: int sx1 = 0;
326: int sy1 = 0;
327: int sx2 = r.width;
328: int sy2 = r.height;
329:
330: if (selected)
331: g.drawImage(tabImage, dx1, dy1, dx2, dy2, sx1, sy1, sx2,
332: sy2, this );
333: else
334: g.drawImage(tabInactiveImage, dx1, dy1, dx2, dy2, sx1, sy1,
335: sx2, sy2, this );
336:
337: if (tabIndex == mouseOverButtonIndex
338: || (tabIndex == pressedButtonIndex && isDraggedOut)) {
339:
340: g.drawImage(tabActiveImage, dx1, dy1, dx2, dy2, sx1, sy1,
341: sx2, sy2, this );
342:
343: //g.setColor(Color.BLACK); //NOI18N
344: //g.drawLine(r.x-1, r.y+8, r.x + r.width+1, r.y+8);
345: //g.setColor(selected
346: // ? UIManager.getColor("Button.highlight") //NOI18N
347: // : UIManager.getColor("Button.background")); //NOI18N
348: //g.drawRect(r.x, r.y, r.width, r.height);
349:
350: // Draw the dots.
351: //g.setColor (UIManager.getColor ("Button.highlight").brighter()); //NOI18N
352: //g.drawLine(r.x + r.width, r.y + 1, r.x + r.width, r.y + 1);
353: //g.drawLine(r.x + 1, r.y + r.height, r.x + 1, r.y + r.height);
354: } else if (tabIndex == pressedButtonIndex) {
355:
356: g.drawImage(tabImage, dx1, dy1, dx2, dy2, sx1, sy1, sx2,
357: sy2, this );
358:
359: /*
360: g.setColor(UIManager.getColor("Button.shadow")); //NOI18N
361: g.drawRect(r.x, r.y, r.width, r.height);
362: g.setColor(selected
363: ? UIManager.getColor("Button.highlight") //NOI18N
364: : UIManager.getColor("Button.background")); //NOI18N
365: g.drawLine(r.x + 1,
366: r.y + r.height + 1,
367: r.x + r.width + 1,
368: r.y + r.height + 1);
369: g.drawLine(r.x + r.width + 1,
370: r.y + 1,
371: r.x + r.width + 1,
372: r.y + r.height + 1);
373:
374: // Draw the lines.
375: g.setColor(UIManager.getColor("Button.background")); //NOI18N
376: g.drawLine(r.x + 1, r.y + 1, r.x + r.width, r.y + 1);
377: g.drawLine(r.x + 1, r.y + 1, r.x + 1, r.y + r.height);
378: */
379: }
380: }
381:
382: private void setPressedCloseButtonIndex(int index) {
383: if (pressedCloseButtonIndex == index)
384: return;
385:
386: if (pressedCloseButtonIndex >= 0
387: && pressedCloseButtonIndex < getTabCount()) {
388: Rectangle r = getCloseButtonBoundsAt(pressedCloseButtonIndex);
389: repaint(r.x, r.y, r.width + 2, r.height + 2);
390:
391: JComponent c = (JComponent) getComponentAt(pressedCloseButtonIndex);
392: setToolTipTextAt(pressedCloseButtonIndex, c
393: .getToolTipText());
394: }
395:
396: pressedCloseButtonIndex = index;
397:
398: if (pressedCloseButtonIndex >= 0
399: && pressedCloseButtonIndex < getTabCount()) {
400: Rectangle r = getCloseButtonBoundsAt(pressedCloseButtonIndex);
401: repaint(r.x, r.y, r.width + 2, r.height + 2);
402: setMouseOverCloseButtonIndex(-1);
403: setToolTipTextAt(pressedCloseButtonIndex, null);
404: }
405: }
406:
407: private void setMouseOverCloseButtonIndex(int index) {
408: if (mouseOverCloseButtonIndex == index)
409: return;
410:
411: if (mouseOverCloseButtonIndex >= 0
412: && mouseOverCloseButtonIndex < getTabCount()) {
413: Rectangle r = getCloseButtonBoundsAt(mouseOverCloseButtonIndex);
414: repaint(r.x, r.y, r.width + 2, r.height + 2);
415: JComponent c = (JComponent) getComponentAt(mouseOverCloseButtonIndex);
416: setToolTipTextAt(mouseOverCloseButtonIndex, c
417: .getToolTipText());
418: }
419:
420: mouseOverCloseButtonIndex = index;
421:
422: if (mouseOverCloseButtonIndex >= 0
423: && mouseOverCloseButtonIndex < getTabCount()) {
424: Rectangle r = getCloseButtonBoundsAt(mouseOverCloseButtonIndex);
425: repaint(r.x, r.y, r.width + 2, r.height + 2);
426: setPressedCloseButtonIndex(-1);
427: setToolTipTextAt(mouseOverCloseButtonIndex, null);
428: }
429: }
430:
431: private void setPressedMinimizeButtonIndex(int index) {
432: if (pressedMinimizeButtonIndex == index)
433: return;
434:
435: if (pressedMinimizeButtonIndex >= 0
436: && pressedMinimizeButtonIndex < getTabCount()) {
437: Rectangle r = getMinimizeButtonBoundsAt(pressedMinimizeButtonIndex);
438: repaint(r.x, r.y, r.width + 2, r.height + 2);
439:
440: JComponent c = (JComponent) getComponentAt(pressedMinimizeButtonIndex);
441: setToolTipTextAt(pressedMinimizeButtonIndex, c
442: .getToolTipText());
443: }
444:
445: pressedMinimizeButtonIndex = index;
446:
447: if (pressedMinimizeButtonIndex >= 0
448: && pressedMinimizeButtonIndex < getTabCount()) {
449: Rectangle r = getMinimizeButtonBoundsAt(pressedMinimizeButtonIndex);
450: repaint(r.x, r.y, r.width + 2, r.height + 2);
451: setMouseOverMinimizeButtonIndex(-1);
452: setToolTipTextAt(pressedMinimizeButtonIndex, null);
453: }
454: }
455:
456: private void setMouseOverMinimizeButtonIndex(int index) {
457: if (mouseOverMinimizeButtonIndex == index)
458: return;
459:
460: if (mouseOverMinimizeButtonIndex >= 0
461: && mouseOverMinimizeButtonIndex < getTabCount()) {
462: Rectangle r = getMinimizeButtonBoundsAt(mouseOverMinimizeButtonIndex);
463: repaint(r.x, r.y, r.width + 2, r.height + 2);
464: JComponent c = (JComponent) getComponentAt(mouseOverMinimizeButtonIndex);
465: setToolTipTextAt(mouseOverMinimizeButtonIndex, c
466: .getToolTipText());
467: }
468:
469: mouseOverMinimizeButtonIndex = index;
470:
471: if (mouseOverMinimizeButtonIndex >= 0
472: && mouseOverMinimizeButtonIndex < getTabCount()) {
473: Rectangle r = getMinimizeButtonBoundsAt(mouseOverMinimizeButtonIndex);
474: repaint(r.x, r.y, r.width + 2, r.height + 2);
475: setPressedMinimizeButtonIndex(-1);
476: setToolTipTextAt(mouseOverMinimizeButtonIndex, null);
477: }
478: }
479:
480: private void fireCloseRequest(Component c) {
481: //firePropertyChange("close", null, c);
482: fireTabPaneChangedListenerTabPaneChanged(new TabPaneChangedEvent(
483: TabPaneChangedEvent.CLOSED, c, indexOfComponent(c)));
484: }
485:
486: private void fireMinimizeRequest(Component c) {
487: fireTabPaneChangedListenerTabPaneChanged(new TabPaneChangedEvent(
488: TabPaneChangedEvent.MINIMIZED, c, indexOfComponent(c)));
489: }
490:
491: public static void fixGetBoundsAt(Rectangle b) {
492: if (b.y < 0)
493: b.y = -b.y;
494: if (b.x < 0)
495: b.x = -b.x;
496: }
497:
498: public static int findTabForCoordinate(JTabbedPane tab, int x, int y) {
499: for (int i = 0; i < tab.getTabCount(); i++) {
500: Rectangle b = tab.getBoundsAt(i);
501: if (b != null) {
502: b = new Rectangle(b);
503: fixGetBoundsAt(b);
504:
505: if (b.contains(x, y)) {
506: return i;
507: }
508: }
509: }
510: return -1;
511: }
512:
513: boolean closingTab = false;
514: boolean minimizingTab = false;
515:
516: public void doLayout() {
517: //JDK 1.5, Win L&F - we cannot do the layout synchronously when we've
518: //just removed a tab - the layout will have out of sync cache data
519: if (closingTab || minimizingTab) {
520: SwingUtilities.invokeLater(this );
521: } else {
522: super .doLayout();
523: }
524: }
525:
526: public void run() {
527: doLayout();
528: closingTab = false;
529: minimizingTab = false;
530: repaint();
531: }
532:
533: protected void processMouseEvent(MouseEvent me) {
534: try {
535: super .processMouseEvent(me);
536: } catch (ArrayIndexOutOfBoundsException aioobe) {
537: //Bug in BasicTabbedPaneUI$Handler: The focusIndex field is not
538: //updated when tabs are removed programmatically, so it will try to
539: //repaint a tab that's not there
540: //ErrorManager.getDefault().annotate(aioobe, "Suppressed " + //NOI18N
541: // "AIOOBE bug in BasicTabbedPaneUI"); //NOI18N
542: //ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, aioobe);
543: }
544: }
545:
546: private static class CloseButtonListener implements
547: AWTEventListener {
548: private static boolean installed = false;
549:
550: private CloseButtonListener() {
551: }
552:
553: private static synchronized void install() {
554: if (installed)
555: return;
556:
557: installed = true;
558: Toolkit.getDefaultToolkit().addAWTEventListener(
559: new CloseButtonListener(),
560: AWTEvent.MOUSE_EVENT_MASK
561: | AWTEvent.MOUSE_MOTION_EVENT_MASK);
562: }
563:
564: public void eventDispatched(AWTEvent ev) {
565: MouseEvent e = (MouseEvent) ev;
566:
567: Component c = (Component) e.getSource();
568: while (c != null && !(c instanceof ExtendedTabbedPane))
569: c = c.getParent();
570: if (c == null)
571: return;
572: final ExtendedTabbedPane tab = (ExtendedTabbedPane) c;
573:
574: Point p = SwingUtilities.convertPoint((Component) e
575: .getSource(), e.getPoint(), tab);
576:
577: if (e.getID() == MouseEvent.MOUSE_CLICKED) {
578: //Not interested in clicked, and it can cause an NPE
579: return;
580: }
581:
582: int index = findTabForCoordinate(tab, p.x, p.y);
583:
584: Rectangle r = null;
585: if (index >= 0)
586: r = tab.getCloseButtonBoundsAt(index);
587: if (r == null)
588: r = new Rectangle(0, 0, 0, 0);
589:
590: switch (e.getID()) {
591: case MouseEvent.MOUSE_PRESSED:
592: if (r.contains(p)) {
593: tab.setPressedCloseButtonIndex(index);
594: tab.draggedOut = false;
595: e.consume();
596: return;
597: }
598: break;
599:
600: case MouseEvent.MOUSE_RELEASED:
601: if (r.contains(p) && tab.pressedCloseButtonIndex >= 0) {
602: tab.closingTab = true;
603: Component tc = tab
604: .getComponentAt(tab.pressedCloseButtonIndex);
605: tab.reset();
606:
607: tab.fireCloseRequest(tc);
608: e.consume();
609: return;
610: } else {
611: tab.reset();
612: }
613: break;
614:
615: case MouseEvent.MOUSE_ENTERED:
616: break;
617:
618: case MouseEvent.MOUSE_EXITED:
619: //tab.reset();
620:
621: // XXX(-ttran) when the user clicks on the close button on
622: // an unfocused (internal) frame the focus is transferred
623: // to the frame and an unexpected MOUSE_EXITED event is
624: // fired. If we call reset() at every MOUSE_EXITED event
625: // then when the mouse button is released the tab is not
626: // closed. See bug #24450
627:
628: break;
629:
630: case MouseEvent.MOUSE_MOVED:
631: if (r.contains(p)) {
632: tab.setMouseOverCloseButtonIndex(index);
633: tab.draggedOut = false;
634: e.consume();
635: return;
636: } else if (tab.mouseOverCloseButtonIndex >= 0) {
637: tab.setMouseOverCloseButtonIndex(-1);
638: tab.draggedOut = false;
639: e.consume();
640: }
641: break;
642:
643: case MouseEvent.MOUSE_DRAGGED:
644: if (tab.pressedCloseButtonIndex >= 0) {
645: if (tab.draggedOut != !r.contains(p)) {
646: tab.draggedOut = !r.contains(p);
647: tab
648: .repaint(r.x, r.y, r.width + 2,
649: r.height + 2);
650: }
651: e.consume();
652: return;
653: }
654: break;
655: }
656: }
657: }
658:
659: private static class MinimizeButtonListener implements
660: AWTEventListener {
661: private static boolean installed = false;
662:
663: private MinimizeButtonListener() {
664: }
665:
666: private static synchronized void install() {
667: if (installed)
668: return;
669:
670: installed = true;
671: Toolkit.getDefaultToolkit().addAWTEventListener(
672: new MinimizeButtonListener(),
673: AWTEvent.MOUSE_EVENT_MASK
674: | AWTEvent.MOUSE_MOTION_EVENT_MASK);
675: }
676:
677: public void eventDispatched(AWTEvent ev) {
678: MouseEvent e = (MouseEvent) ev;
679:
680: Component c = (Component) e.getSource();
681: while (c != null && !(c instanceof ExtendedTabbedPane))
682: c = c.getParent();
683: if (c == null)
684: return;
685: final ExtendedTabbedPane tab = (ExtendedTabbedPane) c;
686:
687: Point p = SwingUtilities.convertPoint((Component) e
688: .getSource(), e.getPoint(), tab);
689:
690: if (e.getID() == MouseEvent.MOUSE_CLICKED) {
691: //Not interested in clicked, and it can cause an NPE
692: return;
693: }
694:
695: int index = findTabForCoordinate(tab, p.x, p.y);
696:
697: Rectangle r = null;
698: if (index >= 0)
699: r = tab.getMinimizeButtonBoundsAt(index);
700: if (r == null)
701: r = new Rectangle(0, 0, 0, 0);
702:
703: switch (e.getID()) {
704: case MouseEvent.MOUSE_PRESSED:
705:
706: if (r.contains(p)) {
707: tab.setPressedMinimizeButtonIndex(index);
708: tab.draggedOutMinimize = false;
709: e.consume();
710: return;
711: }
712: break;
713:
714: case MouseEvent.MOUSE_RELEASED:
715:
716: if (r.contains(p)
717: && tab.pressedMinimizeButtonIndex >= 0) {
718: tab.minimizingTab = true;
719: Component tc = tab
720: .getComponentAt(tab.pressedMinimizeButtonIndex);
721: tab.resetMinimized();
722: tab.fireMinimizeRequest(tc);
723: e.consume();
724: return;
725: } else {
726: tab.resetMinimized();
727: }
728: break;
729:
730: case MouseEvent.MOUSE_ENTERED:
731: break;
732:
733: case MouseEvent.MOUSE_EXITED:
734: //tab.reset();
735:
736: // XXX(-ttran) when the user clicks on the close button on
737: // an unfocused (internal) frame the focus is transferred
738: // to the frame and an unexpected MOUSE_EXITED event is
739: // fired. If we call reset() at every MOUSE_EXITED event
740: // then when the mouse button is released the tab is not
741: // closed. See bug #24450
742:
743: break;
744:
745: case MouseEvent.MOUSE_MOVED:
746: if (r.contains(p)) {
747: tab.setMouseOverMinimizeButtonIndex(index);
748: tab.draggedOutMinimize = false;
749: e.consume();
750: return;
751: } else if (tab.mouseOverMinimizeButtonIndex >= 0) {
752: tab.setMouseOverMinimizeButtonIndex(-1);
753: tab.draggedOutMinimize = false;
754: e.consume();
755: }
756: break;
757:
758: case MouseEvent.MOUSE_DRAGGED:
759: if (tab.pressedMinimizeButtonIndex >= 0) {
760: if (tab.draggedOutMinimize != !r.contains(p)) {
761: tab.draggedOutMinimize = !r.contains(p);
762: tab
763: .repaint(r.x, r.y, r.width + 2,
764: r.height + 2);
765: }
766: e.consume();
767: return;
768: }
769: break;
770: }
771: }
772: }
773:
774: /**
775: * Utility field used by event firing mechanism.
776: */
777: private javax.swing.event.EventListenerList listenerList = null;
778:
779: /**
780: * Registers TabPaneChangedListener to receive events.
781: * @param listener The listener to register.
782: */
783: public synchronized void addTabPaneChangedListener(
784: it.businesslogic.ireport.gui.event.TabPaneChangedListener listener) {
785:
786: if (listenerList == null) {
787: listenerList = new javax.swing.event.EventListenerList();
788: }
789: listenerList
790: .add(
791: it.businesslogic.ireport.gui.event.TabPaneChangedListener.class,
792: listener);
793: }
794:
795: /**
796: * Removes TabPaneChangedListener from the list of listeners.
797: * @param listener The listener to remove.
798: */
799: public synchronized void removeTabPaneChangedListener(
800: it.businesslogic.ireport.gui.event.TabPaneChangedListener listener) {
801:
802: listenerList
803: .remove(
804: it.businesslogic.ireport.gui.event.TabPaneChangedListener.class,
805: listener);
806: }
807:
808: /**
809: * Notifies all registered listeners about the event.
810: *
811: * @param event The event to be fired
812: */
813: private void fireTabPaneChangedListenerTabPaneChanged(
814: it.businesslogic.ireport.gui.event.TabPaneChangedEvent event) {
815:
816: if (listenerList == null)
817: return;
818: Object[] listeners = listenerList.getListenerList();
819: for (int i = listeners.length - 2; i >= 0; i -= 2) {
820: if (listeners[i] == it.businesslogic.ireport.gui.event.TabPaneChangedListener.class) {
821: ((it.businesslogic.ireport.gui.event.TabPaneChangedListener) listeners[i + 1])
822: .tabPaneChanged(event);
823: }
824: }
825: }
826:
827: public int getOrientation() {
828: return orientation;
829: }
830:
831: public void setOrientation(int orientation) {
832: this.orientation = orientation;
833: }
834: }
|