001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.swing.tabcontrol.plaf;
043:
044: import java.awt.Component;
045: import java.awt.Dimension;
046: import java.awt.Font;
047: import java.awt.FontMetrics;
048: import java.awt.Graphics;
049: import java.awt.Graphics2D;
050: import java.awt.GraphicsConfiguration;
051: import java.awt.GraphicsEnvironment;
052: import java.awt.Image;
053: import java.awt.KeyboardFocusManager;
054: import java.awt.Point;
055: import java.awt.Polygon;
056: import java.awt.Rectangle;
057: import javax.swing.AbstractAction;
058: import javax.swing.Action;
059: import javax.swing.JPanel;
060: import javax.swing.event.ListDataEvent;
061: import org.netbeans.swing.tabcontrol.TabData;
062: import org.netbeans.swing.tabcontrol.TabDataModel;
063: import org.netbeans.swing.tabcontrol.TabDisplayer;
064: import org.netbeans.swing.tabcontrol.TabDisplayerUI;
065:
066: import javax.swing.event.ChangeEvent;
067: import javax.swing.event.ChangeListener;
068: import java.awt.event.ActionEvent;
069: import java.awt.event.InputEvent;
070: import java.awt.event.KeyEvent;
071: import java.awt.event.MouseAdapter;
072: import java.awt.event.MouseEvent;
073: import java.awt.event.MouseMotionListener;
074: import java.awt.image.BufferedImage;
075: import java.beans.PropertyChangeEvent;
076: import java.beans.PropertyChangeListener;
077: import javax.swing.Icon;
078: import javax.swing.JComponent;
079: import javax.swing.JLabel;
080: import javax.swing.KeyStroke;
081: import javax.swing.SingleSelectionModel;
082: import javax.swing.SwingUtilities;
083: import javax.swing.ToolTipManager;
084: import javax.swing.UIManager;
085: import org.netbeans.swing.tabcontrol.TabbedContainer;
086: import org.netbeans.swing.tabcontrol.event.ComplexListDataEvent;
087: import org.netbeans.swing.tabcontrol.event.ComplexListDataListener;
088: import org.openide.windows.TopComponent;
089:
090: /**
091: * Basic UI class for view tabs - non scrollable tabbed displayer, which shows all
092: * tabs equally sized, proportionally. This class is independent on specific
093: * L&F, acts as base class for specific L&F descendants.
094: * <p>
095: * XXX eventually this class should be deleted and a subclass of BasicTabDisplayer can be used;
096: * currently this is simply a port of the original code to the new API. Do not introduce any new
097: * subclasses of this.
098: *
099: * @author Dafe Simonek
100: *
101: */
102: public abstract class AbstractViewTabDisplayerUI extends TabDisplayerUI {
103:
104: private TabDataModel dataModel;
105:
106: private TabLayoutModel layoutModel;
107:
108: private FontMetrics fm;
109:
110: private Font txtFont;
111:
112: private Component controlButtons;
113:
114: protected Controller controller;
115:
116: private TabControlButton btnClose;
117: private TabControlButton btnAutoHidePin;
118: private TabControlButton btnMaximizeRestore;
119:
120: /** Pin action */
121: private final Action pinAction = new PinAction();
122: private static final String PIN_ACTION = "pinAction";
123: //toggle transparency action
124: private static final String TRANSPARENCY_ACTION = "transparencyAction";
125:
126: public AbstractViewTabDisplayerUI(TabDisplayer displayer) {
127: super (displayer);
128: displayer.setLayout(null);
129: }
130:
131: @Override
132: public void installUI(JComponent c) {
133: super .installUI(c);
134: ToolTipManager.sharedInstance().registerComponent(displayer);
135: controller = createController();
136: dataModel = displayer.getModel();
137: if (Boolean.getBoolean("winsys.non_stretching_view_tabs")) {
138: ViewTabLayoutModel2.PaddingInfo padding = new ViewTabLayoutModel2.PaddingInfo();
139: padding.iconsXPad = 5;
140: padding.txtIconsXPad = 10;
141: padding.txtPad = new Dimension(5, 2);
142: layoutModel = new ViewTabLayoutModel2(displayer, padding);
143: } else {
144: layoutModel = new ViewTabLayoutModel(dataModel, c);
145: }
146: dataModel.addChangeListener(controller);
147: dataModel.addComplexListDataListener(controller);
148: displayer.addPropertyChangeListener(controller);
149: selectionModel.addChangeListener(controller);
150: displayer.addMouseListener(controller);
151: displayer.addMouseMotionListener(controller);
152: installControlButtons();
153: dataModel.addChangeListener(new ChangeListener() {
154: public void stateChanged(ChangeEvent e) {
155: showHidePinButton();
156: if (null != dataModel)
157: dataModel.removeChangeListener(this );
158: }
159: });
160: }
161:
162: void showHidePinButton() {
163: Component tabComponent = null;
164: int selIndex = Math.max(0, displayer.getSelectionModel()
165: .getSelectedIndex());
166: if (selIndex >= 0 && selIndex < displayer.getModel().size()) {
167: TabData tab = displayer.getModel().getTab(selIndex);
168: tabComponent = tab.getComponent();
169: }
170: btnAutoHidePin.setVisible(tabComponent != null
171: && !TabDisplayer.ORIENTATION_INVISIBLE.equals(displayer
172: .getWinsysInfo().getOrientation(tabComponent)));
173: }
174:
175: protected void installControlButtons() {
176: if (null != getControlButtons())
177: displayer.add(getControlButtons());
178: }
179:
180: private static final int ICON_X_PAD = 1;
181:
182: /**
183: * @return A component that holds all control buttons (maximize/restor,
184: * slide/pin, close) that are displayed in the active tab or null if
185: * control buttons are not supported.
186: */
187: protected Component getControlButtons() {
188: if (null == controlButtons) {
189: JPanel buttonsPanel = new JPanel(null);
190: buttonsPanel.setOpaque(false);
191:
192: int width = 0;
193: int height = 0;
194: //create maximize/restore button
195: // if( null != displayer.getWinsysInfo() ) {
196: // btnMaximizeRestore = TabControlButtonFactory.createMaximizeRestoreButton( displayer );
197: // buttonsPanel.add( btnMaximizeRestore );
198: // Icon icon = btnMaximizeRestore.getIcon();
199: // btnMaximizeRestore.setBounds( 0, 0, icon.getIconWidth(), icon.getIconHeight() );
200: // width += icon.getIconWidth();
201: // }
202:
203: //create autohide/pin button
204: if (null != displayer.getWinsysInfo()) {
205: btnAutoHidePin = TabControlButtonFactory
206: .createSlidePinButton(displayer);
207: buttonsPanel.add(btnAutoHidePin);
208:
209: Icon icon = btnAutoHidePin.getIcon();
210: if (0 != width)
211: width += ICON_X_PAD;
212: btnAutoHidePin.setBounds(width, 0, icon.getIconWidth(),
213: icon.getIconHeight());
214: width += icon.getIconWidth();
215: }
216:
217: //create close button
218: btnClose = TabControlButtonFactory
219: .createCloseButton(displayer);
220: buttonsPanel.add(btnClose);
221:
222: Icon icon = btnClose.getIcon();
223: if (0 != width)
224: width += ICON_X_PAD;
225: btnClose.setBounds(width, 0, icon.getIconWidth(), icon
226: .getIconHeight());
227: width += icon.getIconWidth();
228: height = icon.getIconHeight();
229:
230: Dimension size = new Dimension(width, height);
231: buttonsPanel.setMinimumSize(size);
232: buttonsPanel.setSize(size);
233: buttonsPanel.setPreferredSize(size);
234: buttonsPanel.setMaximumSize(size);
235:
236: controlButtons = buttonsPanel;
237: }
238: return controlButtons;
239: }
240:
241: @Override
242: public void uninstallUI(JComponent c) {
243: super .uninstallUI(c);
244: ToolTipManager.sharedInstance().unregisterComponent(displayer);
245: displayer.removePropertyChangeListener(controller);
246: dataModel.removeChangeListener(controller);
247: dataModel.removeComplexListDataListener(controller);
248: selectionModel.removeChangeListener(controller);
249: displayer.removeMouseListener(controller);
250: displayer.removeMouseMotionListener(controller);
251: if (controlButtons != null) {
252: displayer.remove(controlButtons);
253: controlButtons = null;
254: }
255: layoutModel = null;
256: selectionModel = null;
257: dataModel = null;
258: controller = null;
259: }
260:
261: protected Controller createController() {
262: return new Controller();
263: }
264:
265: @Override
266: public void paint(Graphics g, JComponent c) {
267:
268: ColorUtil.setupAntialiasing(g);
269:
270: TabData tabData;
271: int x, y, width, height;
272: String text;
273:
274: for (int i = 0; i < dataModel.size(); i++) {
275: // gather data
276: tabData = dataModel.getTab(i);
277: x = layoutModel.getX(i);
278: y = layoutModel.getY(i);
279: width = layoutModel.getW(i);
280: height = layoutModel.getH(i);
281: text = tabData.getText();
282: // perform paint
283: if (g.hitClip(x, y, width, height)) {
284: paintTabBackground(g, i, x, y, width, height);
285: paintTabContent(g, i, text, x, y, width, height);
286: paintTabBorder(g, i, x, y, width, height);
287: }
288: }
289: }
290:
291: protected final TabDataModel getDataModel() {
292: return dataModel;
293: }
294:
295: public final TabLayoutModel getLayoutModel() {
296: return layoutModel;
297: }
298:
299: protected final TabDisplayer getDisplayer() {
300: return displayer;
301: }
302:
303: protected final SingleSelectionModel getSelectionModel() {
304: return selectionModel;
305: }
306:
307: public Controller getController() {
308: return controller;
309: }
310:
311: protected final boolean isSelected(int index) {
312: return selectionModel.getSelectedIndex() == index;
313: }
314:
315: protected final boolean isActive() {
316: return displayer.isActive();
317: }
318:
319: protected final boolean isFocused(int index) {
320: return isSelected(index) && isActive();
321: }
322:
323: protected final SingleSelectionModel createSelectionModel() {
324: return new DefaultTabSelectionModel(displayer.getModel());
325: }
326:
327: public int dropIndexOfPoint(Point p) {
328: int result = 0;
329: for (int i = 0; i < displayer.getModel().size(); i++) {
330: int x = getLayoutModel().getX(i);
331: int w = getLayoutModel().getW(i);
332: if (p.x >= x && p.x <= x + w) {
333: if (i == displayer.getModel().size() - 1) {
334: if (p.x > x + (w / 2)) {
335: result = displayer.getModel().size();
336: break;
337: } else {
338: result = i;
339: break;
340: }
341: } else {
342: result = i;
343: break;
344: }
345: }
346: }
347: return result;
348: }
349:
350: /**
351: * Specifies font to use for text and font metrics. Subclasses may override
352: * to specify their own text font
353: */
354: protected Font getTxtFont() {
355: if (txtFont == null) {
356: txtFont = (Font) UIManager.get("windowTitleFont");
357: if (txtFont == null) {
358: txtFont = new Font("Dialog", Font.PLAIN, 11);
359: } else if (txtFont.isBold()) {
360: // don't use deriveFont() - see #49973 for details
361: txtFont = new Font(txtFont.getName(), Font.PLAIN,
362: txtFont.getSize());
363: }
364: }
365: return txtFont;
366: }
367:
368: protected final FontMetrics getTxtFontMetrics() {
369: if (fm == null) {
370: JComponent control = getDisplayer();
371: fm = control.getFontMetrics(getTxtFont());
372: }
373: return fm;
374: }
375:
376: protected abstract void paintTabContent(Graphics g, int index,
377: String text, int x, int y, int width, int height);
378:
379: protected abstract void paintTabBorder(Graphics g, int index,
380: int x, int y, int width, int height);
381:
382: protected abstract void paintTabBackground(Graphics g, int index,
383: int x, int y, int width, int height);
384:
385: /** Registers shortcut for enable/ disable auto-hide functionality */
386: public void unregisterShortcuts(JComponent comp) {
387: comp.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
388: .remove(
389: KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE,
390: InputEvent.CTRL_DOWN_MASK));
391: comp.getActionMap().remove(PIN_ACTION);
392:
393: comp.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
394: .remove(
395: KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD0,
396: InputEvent.CTRL_DOWN_MASK));
397: comp.getActionMap().remove(TRANSPARENCY_ACTION);
398: }
399:
400: /** Registers shortcut for enable/ disable auto-hide functionality */
401: public void registerShortcuts(JComponent comp) {
402: comp.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
403: .put(
404: KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE,
405: InputEvent.CTRL_DOWN_MASK), PIN_ACTION);
406: comp.getActionMap().put(PIN_ACTION, pinAction);
407:
408: //TODO make shortcut configurable
409: comp.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
410: .put(
411: KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD0,
412: InputEvent.CTRL_DOWN_MASK),
413: TRANSPARENCY_ACTION);
414: comp.getActionMap().put(TRANSPARENCY_ACTION,
415: new AbstractAction() {
416: public void actionPerformed(ActionEvent e) {
417: shouldPerformAction(
418: TabbedContainer.COMMAND_TOGGLE_TRANSPARENCY,
419: getSelectionModel().getSelectedIndex(),
420: null);
421: }
422: });
423: }
424:
425: public Polygon getExactTabIndication(int index) {
426: // TBD - the same code is copied in ScrollableTabsUI, should be shared
427: // if will not differ
428: // GeneralPath indication = new GeneralPath();
429: JComponent control = getDisplayer();
430: int height = control.getHeight();
431:
432: TabLayoutModel tlm = getLayoutModel();
433:
434: int tabXStart = tlm.getX(index);
435:
436: int tabXEnd = tabXStart + tlm.getW(index);
437:
438: int[] xpoints = new int[4];
439: int[] ypoints = new int[4];
440: xpoints[0] = tabXStart;
441: ypoints[0] = 0;
442: xpoints[1] = tabXEnd;
443: ypoints[1] = 0;
444: xpoints[2] = tabXEnd;
445: ypoints[2] = height - 1;
446: xpoints[3] = tabXStart;
447: ypoints[3] = height - 1;
448:
449: return new EqualPolygon(xpoints, ypoints);
450: }
451:
452: public Polygon getInsertTabIndication(int index) {
453: EqualPolygon indication = new EqualPolygon();
454: JComponent control = getDisplayer();
455: int height = control.getHeight();
456: int width = control.getWidth();
457: TabLayoutModel tlm = getLayoutModel();
458:
459: int tabXStart;
460: int tabXEnd;
461: if (index == 0) {
462: tabXStart = 0;
463: tabXEnd = tlm.getW(0) / 2;
464: } else if (index >= getDataModel().size()) {
465: tabXStart = tlm.getX(index - 1) + tlm.getW(index - 1) / 2;
466: tabXEnd = tabXStart + tlm.getW(index - 1);
467: if (tabXEnd > width) {
468: tabXEnd = width;
469: }
470: } else {
471: tabXStart = tlm.getX(index - 1) + tlm.getW(index - 1) / 2;
472: tabXEnd = tlm.getX(index) + tlm.getW(index) / 2;
473: }
474:
475: indication.moveTo(tabXStart, 0);
476: indication.lineTo(tabXEnd, 0);
477: indication.lineTo(tabXEnd, height - 1);
478: indication.lineTo(tabXStart, height - 1);
479: return indication;
480: }
481:
482: /** Paints the rectangle occupied by a tab into an image and returns the result */
483: @Override
484: public Image createImageOfTab(int index) {
485: TabData td = displayer.getModel().getTab(index);
486:
487: JLabel lbl = new JLabel(td.getText());
488: int width = lbl.getFontMetrics(lbl.getFont()).stringWidth(
489: td.getText());
490: int height = lbl.getFontMetrics(lbl.getFont()).getHeight();
491: width = width + td.getIcon().getIconWidth() + 6;
492: height = Math.max(height, td.getIcon().getIconHeight()) + 5;
493:
494: BufferedImage image = new BufferedImage(width, height,
495: BufferedImage.TYPE_INT_ARGB);
496: Graphics2D g = image.createGraphics();
497: g.setColor(lbl.getForeground());
498: g.setFont(lbl.getFont());
499: td.getIcon().paintIcon(lbl, g, 0, 0);
500: g.drawString(td.getText(), 18, height / 2);
501:
502: return image;
503: }
504:
505: public Rectangle getTabRect(int index, Rectangle destination) {
506: if (destination == null) {
507: destination = new Rectangle();
508: }
509: if (index < 0 || index > displayer.getModel().size()) {
510: destination.setBounds(0, 0, 0, 0);
511: return destination;
512: }
513: destination.x = layoutModel.getX(index);
514: destination.width = layoutModel.getW(index);
515: destination.height = layoutModel.getH(index);
516: destination.y = Math.min(0, displayer.getHeight()
517: - destination.height);
518: return destination;
519: }
520:
521: public int tabForCoordinate(Point p) {
522: int max = displayer.getModel().size();
523: if (max == 0 || p.y > displayer.getHeight() || p.y < 0
524: || p.x < 0 || p.x > displayer.getWidth()) {
525:
526: return -1;
527: }
528:
529: for (int i = 0; i < max; i++) {
530: int left = layoutModel.getX(i);
531: int right = left + layoutModel.getW(i);
532: if (p.x > left && p.x < right) {
533: return i;
534: }
535: }
536:
537: return -1;
538: }
539:
540: protected int createRepaintPolicy() {
541: return TabState.REPAINT_SELECTION_ON_ACTIVATION_CHANGE
542: | TabState.REPAINT_ON_SELECTION_CHANGE
543: | TabState.REPAINT_ON_MOUSE_ENTER_TAB
544: | TabState.REPAINT_ON_MOUSE_ENTER_CLOSE_BUTTON
545: | TabState.REPAINT_ON_MOUSE_PRESSED;
546: }
547:
548: protected final TabState tabState = new ViewTabState();
549:
550: private class ViewTabState extends TabState {
551: public ViewTabState() {
552: }
553:
554: public int getRepaintPolicy(int tab) {
555: return createRepaintPolicy();
556: }
557:
558: public void repaintAllTabs() {
559: displayer.repaint();
560: }
561:
562: public void repaintTab(int tab) {
563: if (tab < 0 || tab >= displayer.getModel().size()) {
564: //This can happen because we can be notified
565: //of a change on a tab that has just been removed
566: //from the model
567: return;
568: }
569: Rectangle r = getTabRect(tab, null);
570: displayer.repaint(r);
571: }
572: }
573:
574: /**
575: * Determine if the tab should be flashing
576: */
577: protected boolean isAttention(int tab) {
578: return (tabState.getState(tab) & TabState.ATTENTION) != 0;
579: }
580:
581: protected void requestAttention(int tab) {
582: tabState.addAlarmTab(tab);
583: }
584:
585: protected void cancelRequestAttention(int tab) {
586: tabState.removeAlarmTab(tab);
587: }
588:
589: /**
590: * Listen to mouse events and handles selection behaviour and close icon
591: * button behaviour.
592: */
593: protected class Controller extends MouseAdapter implements
594: MouseMotionListener, ChangeListener,
595: PropertyChangeListener, ComplexListDataListener {
596:
597: /**
598: * true when selection is changed as a result of mouse press
599: */
600: private boolean selectionChanged;
601:
602: protected boolean shouldReact(MouseEvent e) {
603: boolean isLeft = SwingUtilities.isLeftMouseButton(e);
604: return isLeft;
605: }
606:
607: public void stateChanged(ChangeEvent ce) {
608: displayer.repaint();
609: }
610:
611: public void propertyChange(PropertyChangeEvent pce) {
612: if (TabDisplayer.PROP_ACTIVE.equals(pce.getPropertyName())) {
613: displayer.repaint();
614: }
615: }
616:
617: /**
618: * @param p Mouse point location
619: * @return True if the point is in the control buttons panel.
620: */
621: public boolean inControlButtonsRect(Point p) {
622: if (null != controlButtons) {
623: Point p2 = SwingUtilities.convertPoint(displayer, p,
624: controlButtons);
625: return controlButtons.contains(p2);
626: }
627: return false;
628: }
629:
630: @Override
631: public void mousePressed(MouseEvent e) {
632: Point p = e.getPoint();
633: int i = getLayoutModel().indexOfPoint(p.x, p.y);
634: tabState.setPressed(i);
635: SingleSelectionModel sel = getSelectionModel();
636: selectionChanged = i != sel.getSelectedIndex();
637: // invoke possible selection change
638: if ((i != -1) || !selectionChanged) {
639: boolean change = shouldPerformAction(
640: TabDisplayer.COMMAND_SELECT, i, e);
641: if (change) {
642: getSelectionModel().setSelectedIndex(i);
643: tabState.setSelected(i);
644: Component tc = getDataModel().getTab(i)
645: .getComponent();
646: if (null != tc
647: && tc instanceof TopComponent
648: && !((TopComponent) tc)
649: .isAncestorOf(KeyboardFocusManager
650: .getCurrentKeyboardFocusManager()
651: .getPermanentFocusOwner())) {
652: ((TopComponent) tc).requestActive();
653: }
654: }
655: }
656: if ((i != -1) && e.isPopupTrigger()) {
657: //Post a popup menu show request
658: shouldPerformAction(TabDisplayer.COMMAND_POPUP_REQUEST,
659: i, e);
660: }
661: }
662:
663: @Override
664: public void mouseClicked(MouseEvent e) {
665: if (e.getClickCount() >= 2 && !e.isPopupTrigger()) {
666: Point p = e.getPoint();
667: int i = getLayoutModel().indexOfPoint(p.x, p.y);
668: SingleSelectionModel sel = getSelectionModel();
669: selectionChanged = i != sel.getSelectedIndex();
670: // invoke possible selection change
671: if ((i != -1) || !selectionChanged) {
672: boolean change = shouldPerformAction(
673: TabDisplayer.COMMAND_SELECT, i, e);
674: if (change) {
675: getSelectionModel().setSelectedIndex(i);
676: }
677: }
678: if (i != -1) {
679: //Post a maximize request
680: shouldPerformAction(TabDisplayer.COMMAND_MAXIMIZE,
681: i, e);
682: }
683: }
684: }
685:
686: @Override
687: public void mouseReleased(MouseEvent e) {
688: // close button must not be active when selection change was
689: // triggered by mouse press
690: tabState.setPressed(-1);
691: Point p = e.getPoint();
692: int i = getLayoutModel().indexOfPoint(p.x, p.y);
693: if ((i != -1) && e.isPopupTrigger()) {
694: //Post a popup menu show request
695: shouldPerformAction(TabDisplayer.COMMAND_POPUP_REQUEST,
696: i, e);
697: }
698: }
699:
700: public void indicesAdded(ComplexListDataEvent e) {
701: tabState.indicesAdded(e);
702: }
703:
704: /**
705: * Elements have been removed at the indices specified by the event's
706: * getIndices() value
707: *
708: * @param e The event
709: */
710: public void indicesRemoved(ComplexListDataEvent e) {
711: tabState.indicesRemoved(e);
712: }
713:
714: /**
715: * Elements have been changed at the indices specified by the event's
716: * getIndices() value. If the changed data can affect display width (such
717: * as a text change or a change in icon size), the event's
718: * <code>isTextChanged()</code> method will return true.
719: *
720: * @param e The event
721: */
722: public void indicesChanged(ComplexListDataEvent e) {
723: tabState.indicesChanged(e);
724: }
725:
726: public void intervalAdded(ListDataEvent evt) {
727: tabState.intervalAdded(evt);
728: }
729:
730: public void intervalRemoved(ListDataEvent evt) {
731: tabState.intervalRemoved(evt);
732: }
733:
734: public void contentsChanged(ListDataEvent evt) {
735: tabState.contentsChanged(evt);
736: }
737:
738: public void mouseDragged(MouseEvent e) {
739: }
740:
741: public void mouseMoved(MouseEvent e) {
742: }
743: } // end of Controller
744:
745: private class PinAction extends AbstractAction {
746: public void actionPerformed(ActionEvent e) {
747: if (null != btnAutoHidePin) {
748: btnAutoHidePin.performAction(null);
749: }
750: }
751: }
752: }
|