# This patch file was generated by NetBeans IDE # Following Index: paths are relative to: D:\projects\substance-netbeans\src\org\jvnet\substance\netbeans # This patch can be applied using context Tools: Patch action on respective folder. # It uses platform neutral UTF-8 encoding and \n newlines. # Above lines and this line are ignored by the patching process. Index: AbstractViewTabDisplayerUI.java *** D:\projects\substance-netbeans\src\org\jvnet\substance\netbeans\AbstractViewTabDisplayerUI.java Base (1.3) --- D:\projects\substance-netbeans\src\org\jvnet\substance\netbeans\AbstractViewTabDisplayerUI.java Locally Deleted *************** *** 1,904 **** - /* - * Sun Public License Notice - * - * The contents of this file are subject to the Sun Public License - * Version 1.0 (the "License"). You may not use this file except in - * compliance with the License. A copy of the License is available at - * http://www.sun.com/ - * - * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun - * Microsystems, Inc. All Rights Reserved. - */ - - package org.jvnet.substance.netbeans; - - import javax.swing.event.ListDataEvent; - import org.jvnet.substance.SubstanceLookAndFeel; - import org.netbeans.swing.tabcontrol.TabData; - import org.netbeans.swing.tabcontrol.TabDataModel; - import org.netbeans.swing.tabcontrol.TabDisplayer; - import org.netbeans.swing.tabcontrol.TabDisplayerUI; - import javax.swing.*; - import javax.swing.event.ChangeEvent; - import javax.swing.event.ChangeListener; - import java.awt.*; - import java.awt.event.ActionEvent; - import java.awt.event.ActionListener; - import java.awt.event.InputEvent; - import java.awt.event.KeyEvent; - import java.awt.event.MouseAdapter; - import java.awt.event.MouseEvent; - import java.awt.event.MouseMotionListener; - import java.awt.image.BufferedImage; - import java.beans.PropertyChangeEvent; - import java.beans.PropertyChangeListener; - import java.net.URL; - import java.util.HashMap; - import java.util.Map; - import org.netbeans.swing.tabcontrol.LocationInformer; - import org.netbeans.swing.tabcontrol.event.ComplexListDataEvent; - import org.netbeans.swing.tabcontrol.event.ComplexListDataListener; - import org.netbeans.swing.tabcontrol.plaf.EqualPolygon; - import org.openide.util.NbBundle; - - /** - * Basic UI class for view tabs - non scrollable tabbed displayer, which shows all - * tabs equally sized, proportionally. This class is independent on specific - * L&F, acts as base class for specific L&F descendants. - *

- * XXX eventually this class should be deleted and a subclass of BasicTabDisplayer can be used; - * currently this is simply a port of the original code to the new API. Do not introduce any new - * subclasses of this. - * - * @author Dafe Simonek - * - */ - public abstract class AbstractViewTabDisplayerUI extends TabDisplayerUI { - - private TabDataModel dataModel; - - private ViewTabLayoutModel layoutModel; - - private FontMetrics fm; - - private Font txtFont; - - protected Controller controller; - - protected static IconLoader iconCache = new IconLoader(); - - protected PinButton pinButton; - - /** Pin action */ - private final Action pinAction = new PinAction(); - private static final String PIN_ACTION = "pinAction"; - - public AbstractViewTabDisplayerUI(TabDisplayer displayer) { - super(displayer); - displayer.setLayout(null); - } - - public void installUI(JComponent c) { - super.installUI(c); - ToolTipManager.sharedInstance().registerComponent(displayer); - controller = createController(); - dataModel = displayer.getModel(); - layoutModel = new ViewTabLayoutModel(dataModel, displayer); - dataModel.addChangeListener(controller); - dataModel.addComplexListDataListener(controller); - displayer.addPropertyChangeListener(controller); - selectionModel.addChangeListener(controller); - displayer.addMouseListener(controller); - displayer.addMouseMotionListener(controller); - LocationInformer locInfo = displayer.getLocationInformer(); - if (locInfo != null) { - pinButton = createPinButton(); - } - installPinButton(); - } - - protected void installPinButton() { - if (pinButton != null) { - displayer.add(pinButton); - pinButton.addActionListener(controller); - } - } - - public void uninstallUI(JComponent c) { - super.uninstallUI(c); - ToolTipManager.sharedInstance().unregisterComponent(displayer); - displayer.removePropertyChangeListener(controller); - dataModel.removeChangeListener(controller); - dataModel.removeComplexListDataListener(controller); - selectionModel.removeChangeListener(controller); - displayer.removeMouseListener(controller); - displayer.removeMouseMotionListener(controller); - if (pinButton != null) { - displayer.remove(pinButton); - pinButton.removeActionListener(controller); - pinButton = null; - } - layoutModel = null; - selectionModel = null; - dataModel = null; - controller = null; - } - - protected abstract Controller createController(); - - public void paint(Graphics g, JComponent c) { - - TabData tabData; - int x, y, width, height; - String text; - - for (int i = 0; i < dataModel.size(); i++) { - // gather data - tabData = dataModel.getTab(i); - x = layoutModel.getX(i); - y = layoutModel.getY(i); - width = layoutModel.getW(i); - height = layoutModel.getH(i); - text = tabData.getText(); - // perform paint - if (g.hitClip(x, y, width, height)) { - paintTabBackground(g, i, x, y, width, height); - paintTabContent(g, i, text, x, y, width, height); - paintTabBorder(g, i, x, y, width, height); - } - } - } - - protected final TabDataModel getDataModel() { - return dataModel; - } - - public final TabLayoutModel getLayoutModel() { - return layoutModel; - } - - protected final TabDisplayer getDisplayer() { - return displayer; - } - - protected final SingleSelectionModel getSelectionModel() { - return selectionModel; - } - - public Controller getController() { - return controller; - } - - protected final boolean isSelected(int index) { - return selectionModel.getSelectedIndex() == index; - } - - protected final boolean isActive() { - return displayer.isActive(); - } - - protected final boolean isFocused(int index) { - return isSelected(index) && isActive(); - } - - protected final SingleSelectionModel createSelectionModel() { - return new DefaultTabSelectionModel(displayer.getModel()); - } - - public String getCommandAtPoint(Point p) { - return controller.inCloseIconRect(p) != -1 ? TabDisplayer.COMMAND_CLOSE : - TabDisplayer.COMMAND_SELECT; - } - - public int dropIndexOfPoint(Point p) { - int result = 0; - for (int i=0; i < displayer.getModel().size(); i++) { - int x = getLayoutModel().getX(i); - int w = getLayoutModel().getW(i); - if (p.x >= x && p.x <= x + w) { - if (i == displayer.getModel().size() - 1) { - if (p.x > x + (w / 2)) { - result = displayer.getModel().size(); - break; - } else { - result = i; - break; - } - } else { - result = i; - break; - } - } - } - return result; - } - - /** - * Specifies font to use for text and font metrics. Subclasses may override - * to specify their own text font - */ - protected Font getTxtFont() { - if (txtFont == null) { - txtFont = SubstanceLookAndFeel.getFontPolicy().getFontSet("Substance", null).getControlFont(); - if (txtFont == null) { - txtFont = new Font("Dialog", Font.PLAIN, 11); - } else if (txtFont.isBold()) { - // don't use deriveFont() - see #49973 for details - txtFont = new Font(txtFont.getName(), Font.PLAIN, txtFont.getSize()); - } - } - return txtFont; - } - - protected final FontMetrics getTxtFontMetrics() { - if (fm == null) { - JComponent control = getDisplayer(); - fm = control.getFontMetrics(getTxtFont()); - } - return fm; - } - - protected abstract void paintTabContent(Graphics g, int index, String text, - int x, int y, int width, - int height); - - protected abstract void paintTabBorder(Graphics g, int index, int x, int y, - int width, int height); - - protected abstract void paintTabBackground(Graphics g, int index, int x, - int y, int width, int height); - - - - /** - * Utility to return y-axis centered icon position in given tab - */ - protected final int getCenteredIconY(Icon icon, int index) { - TabLayoutModel tlm = getLayoutModel(); - int y = tlm.getY(index); - int h = tlm.getH(index); - int iconHeight = icon.getIconHeight(); - return y + (Math.max(0, h / 2 - iconHeight / 2)); - } - - - /** Utility method to access pin button instance conveniently */ - protected final PinButton configurePinButton(int index) { - if (pinButton == null) { - return null; - } - LocationInformer locInfo = getDisplayer().getLocationInformer(); - if (locInfo == null) { - return null; - } - Object orientation = locInfo.getOrientation(getDisplayer().getModel().getTab(index).getComponent()); - pinButton.setOrientation(orientation); - return pinButton; - } - - /** Subclasses should create and return pin button instance, parametrized - * to given orientation - * @see PinButton - */ - // XXX - change back to abstract after implementing in all LFs - protected /*abstract*/ PinButton createPinButton() { - Map normalIcons = new HashMap(6); - normalIcons.put(TabDisplayer.ORIENTATION_EAST, "org/netbeans/swing/tabcontrol/resources/win-pin-normal-east.gif"); - normalIcons.put(TabDisplayer.ORIENTATION_WEST, "org/netbeans/swing/tabcontrol/resources/win-pin-normal-west.gif"); - normalIcons.put(TabDisplayer.ORIENTATION_SOUTH, "org/netbeans/swing/tabcontrol/resources/win-pin-normal-south.gif"); - normalIcons.put(TabDisplayer.ORIENTATION_CENTER, "org/netbeans/swing/tabcontrol/resources/win-pin-normal-center.gif"); - Map pressedIcons = new HashMap(6); - pressedIcons.put(TabDisplayer.ORIENTATION_EAST, "org/netbeans/swing/tabcontrol/resources/win-pin-pressed-east.gif"); - pressedIcons.put(TabDisplayer.ORIENTATION_WEST, "org/netbeans/swing/tabcontrol/resources/win-pin-pressed-west.gif"); - pressedIcons.put(TabDisplayer.ORIENTATION_SOUTH, "org/netbeans/swing/tabcontrol/resources/win-pin-pressed-south.gif"); - pressedIcons.put(TabDisplayer.ORIENTATION_CENTER, "org/netbeans/swing/tabcontrol/resources/win-pin-pressed-center.gif"); - Map rolloverIcons = new HashMap(6); - rolloverIcons.put(TabDisplayer.ORIENTATION_EAST, "org/netbeans/swing/tabcontrol/resources/win-pin-rollover-east.gif"); - rolloverIcons.put(TabDisplayer.ORIENTATION_WEST, "org/netbeans/swing/tabcontrol/resources/win-pin-rollover-west.gif"); - rolloverIcons.put(TabDisplayer.ORIENTATION_SOUTH, "org/netbeans/swing/tabcontrol/resources/win-pin-rollover-south.gif"); - rolloverIcons.put(TabDisplayer.ORIENTATION_CENTER, "org/netbeans/swing/tabcontrol/resources/win-pin-rollover-center.gif"); - return new PinButton(normalIcons, pressedIcons, rolloverIcons); - } - - /** Reaction to pin button / pin shortcut toggle. Does nothing itself,but - * produces event for outer window system. - */ - protected void performPinAction() { - // pin button only active on selected index, so this is safe here - if (getSelectionModel() == null) - return; - int index = getSelectionModel().getSelectedIndex(); - PinButton pinB = configurePinButton(index); - if (pinB != null) { - if (TabDisplayer.ORIENTATION_CENTER.equals(pinB.getOrientation())) { - shouldPerformAction(TabDisplayer.COMMAND_DISABLE_AUTO_HIDE, index, null); - } else { - shouldPerformAction(TabDisplayer.COMMAND_ENABLE_AUTO_HIDE, index, null); - } - // XXX - what to do if action was not consumed? nothing? - } - } - - /** Registers shortcut for enable/ disable auto-hide functionality */ - public void unregisterShortcuts(JComponent comp) { - comp.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT). - remove(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, - InputEvent.CTRL_DOWN_MASK)); - comp.getActionMap().remove(PIN_ACTION); - } - - /** Registers shortcut for enable/ disable auto-hide functionality */ - public void registerShortcuts(JComponent comp) { - comp.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT). - put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, - InputEvent.CTRL_DOWN_MASK), PIN_ACTION); - comp.getActionMap().put(PIN_ACTION, pinAction); - } - - public Polygon getExactTabIndication(int index) { - // TBD - the same code is copied in ScrollableTabsUI, should be shared - // if will not differ - // GeneralPath indication = new GeneralPath(); - JComponent control = getDisplayer(); - int height = control.getHeight(); - - TabLayoutModel tlm = getLayoutModel(); - - int tabXStart = tlm.getX(index); - - int tabXEnd = tabXStart + tlm.getW(index); - - int[] xpoints = new int[4]; - int[] ypoints = new int[4]; - xpoints[0] = tabXStart; - ypoints[0] = 0; - xpoints[1] = tabXEnd; - ypoints[1] = 0; - xpoints[2] = tabXEnd; - ypoints[2] = height - 1; - xpoints[3] = tabXStart; - ypoints[3] = height - 1; - - return new EqualPolygon(xpoints, ypoints); - } - - public Polygon getInsertTabIndication(int index) { - EqualPolygon indication = new EqualPolygon(); - JComponent control = getDisplayer(); - int height = control.getHeight(); - int width = control.getWidth(); - TabLayoutModel tlm = getLayoutModel(); - - int tabXStart; - int tabXEnd; - if (index == 0) { - tabXStart = 0; - tabXEnd = tlm.getW(0) / 2; - } else if (index >= getDataModel().size()) { - tabXStart = tlm.getX(index - 1) + tlm.getW(index - 1) / 2; - tabXEnd = tabXStart + tlm.getW(index - 1); - if (tabXEnd > width) { - tabXEnd = width; - } - } else { - tabXStart = tlm.getX(index - 1) + tlm.getW(index - 1) / 2; - tabXEnd = tlm.getX(index) + tlm.getW(index) / 2; - } - - indication.moveTo(tabXStart, 0); - indication.lineTo(tabXEnd, 0); - indication.lineTo(tabXEnd, height - 1); - indication.lineTo(tabXStart, height - 1); - return indication; - } - - /** - * Loader for icons. Caches loaded icons using hash map. - */ - final static class IconLoader { - /* mapping from resource paths to icon objects, used as cache */ - private Map paths2Icons; - - /** - * Finds and returns icon instance from cache, if present. Otherwise - * loads icon using given resource path and stores icon into cache for - * next access. - * - * @return icon image - */ - public Icon obtainIcon(String iconPath) { - if (paths2Icons == null) { - paths2Icons = new HashMap(6); - } - Icon icon = (Icon) paths2Icons.get(iconPath); - if (icon == null) { - // not yet in cache, load and store - Image image = loadImage(iconPath); - if (image == null) { - throw new IllegalArgumentException("Icon with resource path: " - + iconPath - + " can't be loaded, probably wrong path."); - } - icon = new ImageIcon(image); - paths2Icons.put(iconPath, icon); - } - return icon; - } - - } // end of IconLoader - - private static Image loadImage(String path) { - try { - URL url = org.netbeans.swing.tabcontrol.plaf.AbstractViewTabDisplayerUI.class.getResource("/"+path); - //Apple Bug ID# 3737894 - some transparent gifs incorrectly loaded - //with ImageIO - - //return ImageIO.read(url); - return Toolkit.getDefaultToolkit().createImage(url); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - /** Paints the rectangle occupied by a tab into an image and returns the result */ - public Image createImageOfTab(int index) { - TabData td = displayer.getModel().getTab(index); - - JLabel lbl = new JLabel(td.getText()); - int width = lbl.getFontMetrics(lbl.getFont()).stringWidth(td.getText()); - int height = lbl.getFontMetrics(lbl.getFont()).getHeight(); - width = width + td.getIcon().getIconWidth() + 6; - height = Math.max(height, td.getIcon().getIconHeight()) + 5; - - GraphicsConfiguration config = GraphicsEnvironment.getLocalGraphicsEnvironment() - .getDefaultScreenDevice().getDefaultConfiguration(); - - BufferedImage image = config.createCompatibleImage(width, height); - Graphics2D g = image.createGraphics(); - g.setColor(lbl.getForeground()); - g.setFont(lbl.getFont()); - td.getIcon().paintIcon(lbl, g, 0, 0); - g.drawString(td.getText(), 18, height / 2); - - - return image; - } - - public Rectangle getTabRect(int index, Rectangle destination) { - if (destination == null) { - destination = new Rectangle(); - } - if (index < 0 || index > displayer.getModel().size()) { - destination.setBounds(0,0,0,0); - return destination; - } - destination.x = layoutModel.getX(index); - destination.width = layoutModel.getW(index); - destination.height = layoutModel.getH(index); - destination.y = Math.min(0, displayer.getHeight() - destination.height); - return destination; - } - - public int tabForCoordinate(Point p) { - int max = displayer.getModel().size(); - if (max == 0 || p.y > displayer.getHeight() || p.y < 0 || p.x < 0 || - p.x > displayer.getWidth()) { - - return -1; - } - - for (int i=0; i < max; i++) { - int left = layoutModel.getX(i); - int right = left + layoutModel.getW(i); - if (p.x > left && p.x < right) { - return i; - } - } - - return -1; - } - - protected int createRepaintPolicy() { - return TabState.REPAINT_SELECTION_ON_ACTIVATION_CHANGE - | TabState.REPAINT_ON_SELECTION_CHANGE - | TabState.REPAINT_ON_MOUSE_ENTER_TAB - | TabState.REPAINT_ON_MOUSE_ENTER_CLOSE_BUTTON - | TabState.REPAINT_ON_MOUSE_PRESSED; - } - - protected final TabState tabState = new ViewTabState(); - - private class ViewTabState extends TabState { - public int getRepaintPolicy(int tab) { - return createRepaintPolicy(); - } - - public void repaintAllTabs() { - displayer.repaint(); - } - - public void repaintTab(int tab) { - if (tab < 0 || tab >= displayer.getModel().size()) { - //This can happen because we can be notified - //of a change on a tab that has just been removed - //from the model - return; - } - Rectangle r = getTabRect(tab, null); - displayer.repaint(r); - } - } - - /** - * Determine if the tab should be flashing - */ - protected boolean isAttention(int tab) { - return (tabState.getState(tab) & TabState.ATTENTION) != 0; - } - - - protected void requestAttention(int tab) { - tabState.addAlarmTab(tab); - } - - protected void cancelRequestAttention(int tab) { - tabState.removeAlarmTab(tab); - } - - public String getTooltipForButtons(Point point) { - if (getController().inPinButtonRect(point)) { - if (pinButton != null) { - return pinButton.getPinToolTipText(); - } - return null; - } - if (getController().inCloseIconRect(point) != -1) { - return NbBundle.getMessage(org.netbeans.swing.tabcontrol.plaf.AbstractViewTabDisplayerUI.class, "CloseButton.tooltip"); - } - return null; - } - - /** - * Listen to mouse events and handles selection behaviour and close icon - * button behaviour. - */ - abstract class Controller extends MouseAdapter - implements MouseMotionListener, ChangeListener, PropertyChangeListener, ActionListener, ComplexListDataListener { - - //XXX should be able to replace most of this class with - //tabState - we're already using it to manage the blinking state - - /** - * index of tab whose close icon currently pressed, -1 otherwise - */ - // TBD - should be part of model, not controller - private int closePressed = -1; - /** - * index of tab whose close icon active area contains current mouse - * pointer, false otherwise - */ - // TBD - should be part of model, not controller - private int mouseInCloseButton = -1; - /** - * true when selection is changed as a result of mouse press - */ - private boolean selectionChanged; - - /** - * Subclasses should override this method by detecting if given point is - * contained in close icon. - * - * @return index of tab which close icon area contains given point, -1 - * if point is outside any close icon area. - */ - protected abstract int inCloseIconRect(Point point); - - protected abstract boolean inPinButtonRect(Point point); - - protected boolean shouldReact(MouseEvent e) { - boolean isLeft = SwingUtilities.isLeftMouseButton(e); - return isLeft; - } - - public void stateChanged(ChangeEvent ce) { - displayer.repaint(); - } - - public void propertyChange(PropertyChangeEvent pce) { - if (TabDisplayer.PROP_ACTIVE.equals(pce.getPropertyName())) { - displayer.repaint(); - } - } - - /** - * Performs button action, default impl removes the tab. Subclasses can - * alter this by overriding. - */ - protected void performAction(MouseEvent e) { - if (shouldPerformAction(TabDisplayer.COMMAND_CLOSE, mouseInCloseButton, e)) { - //In NetBeans winsys, this should never be called - TabbedHandler will - //consume the event when it is re-propagated from the TabbedContainer - getDataModel().removeTab(mouseInCloseButton); - } - } - - - public void mousePressed(MouseEvent e) { - Point p = e.getPoint(); - int i = getLayoutModel().indexOfPoint(p.x, p.y); - tabState.setPressed(i); - SingleSelectionModel sel = getSelectionModel(); - selectionChanged = i != sel.getSelectedIndex(); - // invoke possible selection change - if ((i != -1) || !selectionChanged) { - boolean change = shouldPerformAction(TabDisplayer.COMMAND_SELECT, - i, e); - if (change) { - getSelectionModel().setSelectedIndex(i); - tabState.setSelected(i); - } - } - // update pressed state - if (shouldReact(e) && !selectionChanged) { - setClosePressed(inCloseIconRect(e.getPoint())); - } - if ((i != -1) && e.isPopupTrigger()) { - //Post a popup menu show request - shouldPerformAction(TabDisplayer.COMMAND_POPUP_REQUEST, i, e); - } - } - - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() >= 2 && !e.isPopupTrigger()) { - Point p = e.getPoint(); - int i = getLayoutModel().indexOfPoint(p.x, p.y); - SingleSelectionModel sel = getSelectionModel(); - selectionChanged = i != sel.getSelectedIndex(); - // invoke possible selection change - if ((i != -1) || !selectionChanged) { - boolean change = shouldPerformAction(TabDisplayer.COMMAND_SELECT, - i, e); - if (change) { - getSelectionModel().setSelectedIndex(i); - } - } - if (i != -1) { - //Post a maximize request - shouldPerformAction(TabDisplayer.COMMAND_MAXIMIZE, i, e); - } - } - } - - public void mouseReleased(MouseEvent e) { - // close button must not be active when selection change was - // triggered by mouse press - tabState.setPressed(-1); - if (shouldReact(e) && !selectionChanged) { - setClosePressed(-1); - Point point = e.getPoint(); - if ((mouseInCloseButton = inCloseIconRect(point)) >= 0) { - performAction(e); - // reset rollover effect after action is complete - setMouseInCloseButton(point); - } - } - Point p = e.getPoint(); - int i = getLayoutModel().indexOfPoint(p.x, p.y); - if ((i != -1) && e.isPopupTrigger()) { - //Post a popup menu show request - shouldPerformAction(TabDisplayer.COMMAND_POPUP_REQUEST, i, e); - } - } - - public void mouseMoved(MouseEvent e) { - setMouseInCloseButton(e.getPoint()); - } - - public void mouseDragged(MouseEvent e) { - setClosePressed(inCloseIconRect(e.getPoint())); - setMouseInCloseButton(e.getPoint()); - } - - public void mouseExited(MouseEvent e) { - setMouseInCloseButton(e.getPoint()); - } - - /** - * @return true if close icon is pressed at the time of calling this - * method, false otherwise - */ - public int isClosePressed() { - return closePressed; - } - - /** - * @return true if mouse pointer is in close icon active area at the - * time of calling this method, false otherwise - */ - public int isMouseInCloseButton() { - return mouseInCloseButton; - } - - - /** - * Sets state of close button to pressed or released. Updates visual - * state properly. - */ - protected void setClosePressed(int pressed) { - if (closePressed == pressed) { - return; - } - int oldValue = closePressed; - closePressed = pressed; - if (closePressed == -1) { - // press ended - TabLayoutModel tlm = getLayoutModel(); - getDisplayer().repaint(tlm.getX(oldValue), - tlm.getY(oldValue), - tlm.getW(oldValue), - tlm.getH(oldValue)); - - } else if (oldValue == -1) { - // press started - TabLayoutModel tlm = getLayoutModel(); - getDisplayer().repaint(tlm.getX(closePressed), - tlm.getY(closePressed), - tlm.getW(closePressed), - tlm.getH(closePressed)); - } else { - // rare situation, two tabs need repaint, so repaint all - getDisplayer().repaint(); - } - } - - /** - * Sets state of mouse in close button value. Requests repaint of visual - * state properly. - */ - protected void setMouseInCloseButton(Point location) { - int isNow = inCloseIconRect(location); - if (mouseInCloseButton == isNow || dataModel.size() == 0) { - return; - } - // sync of indexes - int oldValue = mouseInCloseButton; - mouseInCloseButton = isNow; - tabState.setCloseButtonContainsMouse(isNow); - if (isNow == -1) { - // exit from close area - TabLayoutModel tlm = getLayoutModel(); - getDisplayer().repaint(tlm.getX(oldValue), - tlm.getY(oldValue), - tlm.getW(oldValue), - tlm.getH(oldValue)); - - } else if (oldValue == -1) { - // enter into close area - TabLayoutModel tlm = getLayoutModel(); - getDisplayer().repaint(tlm.getX(isNow), tlm.getY(isNow), - tlm.getW(isNow), tlm.getH(isNow)); - } else { - // rare situation, two tabs need repaint, so repaint all - getDisplayer().repaint(); - } - } - - /** Implementation of ActionListener. Reacts to pin button clicks - */ - public void actionPerformed(ActionEvent e) { - performPinAction(); - } - - public void indicesAdded(ComplexListDataEvent e) { - tabState.indicesAdded(e); - } - - /** - * Elements have been removed at the indices specified by the event's - * getIndices() value - * - * @param e The event - */ - public void indicesRemoved(ComplexListDataEvent e) { - tabState.indicesRemoved(e); - } - - /** - * Elements have been changed at the indices specified by the event's - * getIndices() value. If the changed data can affect display width (such - * as a text change or a change in icon size), the event's - * isTextChanged() method will return true. - * - * @param e The event - */ - public void indicesChanged(ComplexListDataEvent e) { - tabState.indicesChanged(e); - } - - public void intervalAdded(ListDataEvent evt) { - tabState.intervalAdded(evt); - } - - public void intervalRemoved(ListDataEvent evt) { - tabState.intervalRemoved(evt); - } - - public void contentsChanged(ListDataEvent evt) { - tabState.contentsChanged(evt); - } - } // end of Controller - - - /** Implementation of Pin button, its look is dependent on orientation - * and can be set using setOrientation method. - */ - protected static class PinButton extends JButton { - - private Map pressedIcons, rolloverIcons, regularIcons; - - private Object orientation; - - public PinButton(Map regularIcons, Map pressedIcons, Map rolloverIcons) { - super(); - this.regularIcons = regularIcons; - this.pressedIcons = pressedIcons; - this.rolloverIcons = rolloverIcons; - setFocusable(false); - setContentAreaFilled(false); - setRolloverEnabled(rolloverIcons != null); - setOrientation(TabDisplayer.ORIENTATION_CENTER); - } - - public void updateUI() { - super.updateUI(); - setFocusable(false); - setContentAreaFilled(false); - setBorder(BorderFactory.createEmptyBorder()); - } - - public Object getOrientation() { - return orientation; - } - - public void setOrientation(Object orientation) { - this.orientation = orientation; - if (orientation != TabDisplayer.ORIENTATION_INVISIBLE) { - Icon icon = iconCache.obtainIcon((String)regularIcons.get(orientation)); - setIcon(icon); - setSize(icon.getIconWidth(), icon.getIconHeight()); - if (pressedIcons != null) { - setPressedIcon(iconCache.obtainIcon((String)regularIcons.get(orientation))); - } - if (rolloverIcons != null) { - setRolloverIcon(iconCache.obtainIcon((String)rolloverIcons.get(orientation))); - } - setToolTipText(getPinToolTipText()); - } else { - setIcon(null); - setPressedIcon(null); - setSize(0,0); - setRolloverIcon(null); - setToolTipText(null); - } - } - - private String getPinToolTipText() { - if (orientation != TabDisplayer.ORIENTATION_CENTER) { - return NbBundle.getMessage(org.netbeans.swing.tabcontrol.plaf.AbstractViewTabDisplayerUI.class, "AutoHideButton.tooltip"); //NOI18N - } - return NbBundle.getMessage(org.netbeans.swing.tabcontrol.plaf.AbstractViewTabDisplayerUI.class, "AutoHideButton.restore.tooltip"); //NOI18N - } - - } // end of PinButton - - /** Executes enable / disable auto-hide mode */ - private final class PinAction extends AbstractAction { - public void actionPerformed(ActionEvent e) { - performPinAction(); - } - } // end of PinAction - - - } --- 1,0 ---- Index: DefaultTabSelectionModel.java *** D:\projects\substance-netbeans\src\org\jvnet\substance\netbeans\DefaultTabSelectionModel.java Base (1.1) --- D:\projects\substance-netbeans\src\org\jvnet\substance\netbeans\DefaultTabSelectionModel.java Locally Deleted *************** *** 1,288 **** - /* - * Sun Public License Notice - * - * The contents of this file are subject to the Sun Public License - * Version 1.0 (the "License"). You may not use this file except in - * compliance with the License. A copy of the License is available at - * http://www.sun.com/ - * - * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun - * Microsystems, Inc. All Rights Reserved. - *//* - * DefaultTabSelectionModel.java - * - * Created on May 26, 2003, 5:37 PM - */ - - package org.jvnet.substance.netbeans; - - import org.netbeans.swing.tabcontrol.TabDataModel; - import org.netbeans.swing.tabcontrol.event.ArrayDiff; - import org.netbeans.swing.tabcontrol.event.ComplexListDataEvent; - import org.netbeans.swing.tabcontrol.event.ComplexListDataListener; - import org.netbeans.swing.tabcontrol.event.VeryComplexListDataEvent; - - import javax.swing.*; - import javax.swing.event.ChangeEvent; - import javax.swing.event.ListDataEvent; - import java.util.Iterator; - import java.util.Set; - - /** - * Default implementation of tab selection model. Listens to the supplied data - * model and updates the selection appropriately on all add/remove events so that - * the actual selection does not change if items are inserted into the model ahead - * of the current selection, etc. - * - * @author Tim Boudreau - */ - final class DefaultTabSelectionModel implements SingleSelectionModel, - ComplexListDataListener { - TabDataModel dataModel; - int sel = -1; - /** - * Utility field holding list of ChangeListeners. - */ - private transient java.util.ArrayList changeListenerList; - - /** - * Creates a new instance of DefaultTabSelectionModel - */ - public DefaultTabSelectionModel(TabDataModel tdm) { - dataModel = tdm; - attach(); - } - - public void attach() { - dataModel.addComplexListDataListener(this); - } - - public void detach() { - dataModel.removeComplexListDataListener(this); - } - - public void clearSelection() { - sel = -1; - fireStateChanged(); - } - - public int getSelectedIndex() { - return sel; - } - - public boolean isSelected() { - return sel != -1; - } - - public void setSelectedIndex(int index) { - if (index != sel) { - int oldIndex = sel; - if ((index < -1) || (index >= dataModel.size())) { - throw new IllegalArgumentException("Selected index set to " - + index - + " but model size is only " + dataModel.size()); - } - sel = index; - fireStateChanged(); - } - } - - private void adjustSelectionForEvent(ListDataEvent e) { - if (e.getType() == e.CONTENTS_CHANGED || sel == -1) { - return; - } - int start = e.getIndex0(); - int end = e.getIndex1() + 1; - if (e.getType() == e.INTERVAL_REMOVED) { - if (sel < start) { - return; - } else { - if (sel >= start) { - if (sel > end) { - sel -= end - start; - } else { - sel = start; - if (sel >= dataModel.size()) { - sel = dataModel.size() - 1; - } - } - fireStateChanged(); - } - } - } else { - if (sel < start) { - //not affected, do nothing - return; - } - if (sel >= start) { - if (end - 1 == start) { - sel++; - } else if (sel < end) { - sel = (end + (sel - start)) - 1; - } else { - sel += (end - start) - 1; - } - fireStateChanged(); - } - } - } - - public void contentsChanged(ListDataEvent e) { - adjustSelectionForEvent(e); - } - - public void intervalAdded(ListDataEvent e) { - adjustSelectionForEvent(e); - } - - public void intervalRemoved(ListDataEvent e) { - adjustSelectionForEvent(e); - } - - public void indicesAdded(ComplexListDataEvent e) { - if (sel < 0) return; - int[] indices = e.getIndices(); - java.util.Arrays.sort(indices); - int offset = 0; - for (int i = 0; i < indices.length; i++) { - if (sel >= indices[i]) { - offset++; - } else { - break; - } - } - if (offset > 0) { - sel += offset; - fireStateChanged(); - } - } - - public void indicesRemoved(ComplexListDataEvent e) { - if (sel < 0) return; - int[] indices = e.getIndices(); - java.util.Arrays.sort(indices); - int offset = -1; - for (int i = 0; i < indices.length; i++) { - if (sel > indices[i]) { - offset--; - } else { - break; - } - } - if (sel == dataModel.size()) { - sel -= 1; - fireStateChanged(); - return; - } - if (dataModel.size() == 0) { - sel = -1; - fireStateChanged(); - } else if (offset != 0) { - sel = Math.max( -1, Math.min (sel + offset, -1)); - fireStateChanged(); - } - } - - public void indicesChanged(ComplexListDataEvent e) { - if (sel < 0) return; - if (e instanceof VeryComplexListDataEvent) { //it always will be - - ArrayDiff dif = ((VeryComplexListDataEvent) e).getDiff(); - - boolean changed = false; - - if (dif == null) { - //no differences - return; - } - - //Get the deleted and added indices - Set deleted = dif.getDeletedIndices(); - Set added = dif.getAddedIndices(); - - //create an Integer to compare - Integer idx = new Integer(getSelectedIndex()); - - //Don't iterate if everything was closed, we know what to do - if (dataModel.size() == 0) { - sel = -1; - fireStateChanged(); - return; - } - - //Iterate all of the deleted items, and count how many were - //removed at indices lower than the selection, so we can subtract - //that from the selected index to keep selection on the same tab - Iterator i = deleted.iterator(); - int offset = 0; - Integer curr; - while (i.hasNext()) { - curr = (Integer) i.next(); - if (curr.compareTo(idx) <= 0) { - offset++; - } - } - - //Iterate all of the added items, and count how many were added at - //indices below the selected index, so we can add that to the selected - //index - i = added.iterator(); - while (i.hasNext()) { - curr = (Integer) i.next(); - if (curr.compareTo(idx) >= 0) { - offset--; - } - } - - sel -= offset; - if (sel < 0) { - //The tab at index 0 was closed, but we always want to show - //something if we can, so change it to 0 if possible - sel = dataModel.size() > 0 ? 0 : -1; - } - - //Make sure we're not off the end of the array - we could be if the - //selection was the last and it and others were removed - if (sel >= dataModel.size()) { - sel = dataModel.size() - 1; - } - - if (offset != 0) { - fireStateChanged(); - } - } - //do nothing - } - - public synchronized void addChangeListener( - javax.swing.event.ChangeListener listener) { - if (changeListenerList == null) { - changeListenerList = new java.util.ArrayList(); - } - changeListenerList.add(listener); - } - - public synchronized void removeChangeListener( - javax.swing.event.ChangeListener listener) { - if (changeListenerList != null) { - changeListenerList.remove(listener); - } - } - - ChangeEvent ce = new ChangeEvent(this); - - private void fireStateChanged() { - java.util.ArrayList list; - synchronized (this) { - if (changeListenerList == null) { - return; - } - list = (java.util.ArrayList) changeListenerList.clone(); - } - for (int i = 0; i < list.size(); i++) { - ((javax.swing.event.ChangeListener) list.get(i)).stateChanged(ce); - } - } - - } --- 1,0 ---- Index: TabState.java *** D:\projects\substance-netbeans\src\org\jvnet\substance\netbeans\TabState.java Base (1.1) --- D:\projects\substance-netbeans\src\org\jvnet\substance\netbeans\TabState.java Locally Deleted *************** *** 1,962 **** - /* - * Sun Public License Notice - * - * The contents of this file are subject to the Sun Public License - * Version 1.0 (the "License"). You may not use this file except in - * compliance with the License. A copy of the License is available at - * http://www.sun.com/ - * - * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun - * Microsystems, Inc. All Rights Reserved. - */ - package org.jvnet.substance.netbeans; - - import java.awt.event.ActionEvent; - import java.awt.event.ActionListener; - import java.util.ArrayList; - import java.util.Arrays; - import java.util.HashSet; - import java.util.Iterator; - import java.util.List; - import java.util.Set; - import javax.swing.Timer; - import javax.swing.event.ListDataEvent; - import org.netbeans.swing.tabcontrol.TabData; - import org.netbeans.swing.tabcontrol.event.ArrayDiff; - import org.netbeans.swing.tabcontrol.event.ComplexListDataEvent; - import org.netbeans.swing.tabcontrol.event.VeryComplexListDataEvent; - import org.openide.util.Utilities; - - /** - * Used by BasicTabDisplayerUI and its subclasses. - * Tracks and manages the state of tabs, mainly which one currently contains the - * mouse, if the mouse is in the close button, if the tab is adjacent to a - * selected tab, if it is leftmost, rightmost, active, etc. This class hides - * most of the complexity of deciding what mouse events should trigger a repaint - * of what areas in an optimized way. It provides setters which a mouse - * listener can call to indicate that the mouse has, say, moved into a tab, or - * from one tab to another, or the selection has changed, etc. - *

- * Essentially, this class is fed indices of tabs that have various states (selected, - * contains mouse, etc.), figures out if this affects one tab, two tabs (a different - * tab had the state, such as the mouse moving from one tab to another) or all tabs (activated). It determines - * a change type, and consults a repaint policy (an integer bitmask) to decide - * if one, both, all or no tabs should be repainted. - *

- * The typical use case is to implement a subclass, and override getState() to - * mix in bitmasks for things like whether a tab is clipped, etc. - things the - * base implementation can't know about. - * - *

- * Subclasses implement the repaintTab() method to do the actual - * repainting, and implement getRepaintPolicy(). The repainting will be - * called if an event happens that changes the state in a way that the repaint policy - * bitmask indicates should cause a repaint. - *

- * BasicTabDisplayerUI implements a mouse listener which will call the appropriate - * methods when the mouse enters/exits tabs, etc. - *

Details

- *

- * State is composed as an integer bitmask which covers all of the supported - * states of a tab that may affect the way they paint. These are also the values that - * are passed to the methods of a TabCellRenderer to tell it how to - * paint itself. Two other integer - * bitmasks are used: The changeType, which indicates whether a - * change was from one tab to another tab, one tab to no tab (i.e. selection set - * to -1), one tab to the same tab (i.e. the mouse moved out of the tab control, - * and so the tab with the mouse in it is now no tab). RepaintPolicy is an integer - * bitmask composed of conditions under which the control should repaint one or all - * tabs, and determines what types of changes actually trigger repaints. - *

- * Subclasses are expected to override getState() to provide - * information about non-mouse-or-focus related states, such as clipping of - * scrollable tabs. Predefined states for tabs are: CLIP_RIGHT, CLIP_LEFT, - * ARMED, PRESSED, SELECTED, ACTIVE, NOT_ONSCREEN, LEFTMOST, RIGHTMOST, - * CLOSE_BUTTON_ARMED, BEFORE_SELECTED, AFTER_SELECTED, MOUSE_IN_TABS_AREA, - * MOUSE_PRESSED_IN_CLOSE_BUTTON. Subclasses must handle returning the following - * states if they wish to, which are not handled directly in TabState: LEFTMOST, - * RIGHTMOST, CLIP_LEFT, CLIP_RIGHT, NOT_ONSCREEN. - *

- * Most of the states are fairly self-explanatory; NOT_ONSCREEN is useful as an - * optimization so that no work is done for events that would try to produce a - * repaint for something not visible; CLIP_* refers to the case in scrollable - * tab UIs, in which a tab may only be partially visible; - * MOUSE_PRESSED_IN_CLOSE_BUTTON is distinct because the CLOSE_BUTTON_ARMED - * state will be reset if the mouse moves out of the close button area, but UIs - * should perform a close action if the mouse was pressed over the close button, - * moved away from the close button and then back to it, so this state preserves - * the information that the originating location of a mouse press was in the - * close button. - */ - public abstract class TabState { - - /** - * Bitmask for state of tabs clipped on the right side - that is, partially - * displayed - */ - public static final int CLIP_RIGHT = 1; - /** - * Bitmask for state of tabs clipped on the right side - that is, partially - * displayed - */ - public static final int CLIP_LEFT = 2; - /** - * Bitmask indicating the tab contains the mouse - */ - public static final int ARMED = 4; - /** - * Bitmask indicating the tab contains the mouse and the mouse button has - * been pressed - */ - public static final int PRESSED = 8; - /** - * Bitmask indicating the tab is selected - */ - public static final int SELECTED = 16; - /** - * Bitmask indicating the tab is activated - */ - public static final int ACTIVE = 32; - /** - * State bitmask indicating a tab is not displayed at all and shouldn't be - * painted. Implementations may more simply avoid not painting a tab by not - * including it in the range returned by getFirstVisibleTab()/getLastVisibleTab(). - * This state exists so that implementations have the option of returning - * the entire range of tabs as visible and determining if one is truly - * visble or not in getTabState() - sometimes doing it this way will be less - * expensive. - */ - public static final int NOT_ONSCREEN = 64; - /** - * Bitmask indicating the tab is at the extreme left and - * not clipped - */ - public static final int LEFTMOST = 128; - /** - * Bitmask indicating the tab is at the extreme right and - * not clipped - */ - public static final int RIGHTMOST = 256; - /** - * Bitmask indicating that the tab contains the mouse and the mouse is in - * the close button - */ - public static final int CLOSE_BUTTON_ARMED = 512; - /** - * Bitmask indicating that the tab's index is that of the selected index - * less one - */ - public static final int BEFORE_SELECTED = 1024; - /** - * Bitmask indicating that the tab's index is that of the selected index - * plus one - */ - public static final int AFTER_SELECTED = 2048; - /** - * Bitmask indicating that the mouse is in the tabs area - */ - public static final int MOUSE_IN_TABS_AREA = 4096; - - /** - * Bitmask indicating that the mouse is inside the close button and has - * been pressed. - */ - public static final int MOUSE_PRESSED_IN_CLOSE_BUTTON = 8192; - - /** - * Bitmask indicating that the tab is in "attention" mode - blinking or - * flashing to get the user's attention. - */ - public static final int ATTENTION = 16384; - - /** - * Indicates the last constant defined - renderers that wish to add their - * own bitmasks should use multiples of this number - */ - public static int STATE_LAST = MOUSE_PRESSED_IN_CLOSE_BUTTON; - - - private int pressedIndex = -1; - private int containsMouseIndex = -1; - private int closeButtonContainsMouseIndex = -1; - private int mousePressedInCloseButtonIndex = -1; - private boolean mouseInTabsArea = false; - private boolean active = false; - private int selectedIndex = -1; - - private int prev = -1; - private int curr = -1; - private int lastChangeType = NO_CHANGE; - private int lastAffected = 0; - private int lastChange = 0; - - /** Repaint policy bitmask indicating that a tab should be repainted whenever the mouse enters or exits it */ - public static final int REPAINT_ON_MOUSE_ENTER_TAB = 1; - /** Repaint policy bitmask indicating that all tabs should be repainted whenever the mouse enters or leaves the - * area in which tabs are painted */ - public static final int REPAINT_ALL_ON_MOUSE_ENTER_TABS_AREA = 3; - /** Repaint policy bitmask indicating that the tab should be repainted when the mouse enters or exits the close - * button region */ - public static final int REPAINT_ON_MOUSE_ENTER_CLOSE_BUTTON = 4; - /** Repaint policy bitmask indicating that the tab should be repainted on mouse pressed events */ - public static final int REPAINT_ON_MOUSE_PRESSED = 8; - /** Repaint policy bitmask indicating that the selected tab should be repainted when the activated state changes */ - public static final int REPAINT_SELECTION_ON_ACTIVATION_CHANGE = 16; - /** Repaint policy bitmask indicating that all tabs should be repainted when the activated state changes */ - public static final int REPAINT_ALL_TABS_ON_ACTIVATION_CHANGE = 32; //includes selection - /** Repaint policy bitmask indicating that a tab should be repainted when it becomes selected/unselected */ - public static final int REPAINT_ON_SELECTION_CHANGE = 64; - /** Repaint policy bitmask indicating that all tabs should be repainted whenever the selection changes */ - public static final int REPAINT_ALL_TABS_ON_SELECTION_CHANGE = 128; - /** Repaint policy bitmask indicating that the tab should be repainted when the close button is pressed */ - public static final int REPAINT_ON_CLOSE_BUTTON_PRESSED = 256; - - /** - * Get the state of a given tab. Subclasses are expected to override this - * to provide information about states such as clipping which can only be - * found out via layout information, such as LEFTMOST, RIGHTMOST, CLIP_LEFT - * and CLIP_RIGHT. The state is used by tab renderers to determine how they - * should paint themselves. - * - * @param tab The index of the tab - * @return The state - */ - public int getState(int tab) { - int result = 0; - if (tab == pressedIndex) { - result |= PRESSED; - } - if (tab == containsMouseIndex) { - result |= ARMED; - } - if (tab == closeButtonContainsMouseIndex) { - result |= CLOSE_BUTTON_ARMED; - } - if (tab == mousePressedInCloseButtonIndex) { - result |= MOUSE_PRESSED_IN_CLOSE_BUTTON; - } - if (mouseInTabsArea) { - result |= MOUSE_IN_TABS_AREA; - } - if (active) { - result |= ACTIVE; - } - if (tab == selectedIndex) { - result |= SELECTED; - } - if (tab != 0 && tab == selectedIndex + 1) { - result |= AFTER_SELECTED; - } - if (tab == selectedIndex - 1) { - result |= BEFORE_SELECTED; - } - if (isAlarmTab(tab)) { - result |= ATTENTION; - } - return result; - } - - /** For debugging, enables fetching tab state as a string */ - String getStateString (int tab) { - return stateToString (getState(tab)); - } - - /** - * Clear all mouse position related state information. This should be done - * following events in the model that alter the state sufficiently that the - * cached information is probably wrong. - */ - public void clearTransientStates() { - pressedIndex = -1; - containsMouseIndex = -1; - closeButtonContainsMouseIndex = -1; - mousePressedInCloseButtonIndex = -1; - mouseInTabsArea = false; - lastChangeType = NO_CHANGE; - lastChange = 0; - prev = -1; - curr = -1; - } - - /** - * Set the index of the tab over which a mouse button has been pressed. - * - * @param i The tab which is pressed, or -1 to clear PRESSED from the state - * of the previously pressed tab - * @return Index of the tab which previously had the state PRESSED, or -1 - */ - public final int setPressed(int i) { - prev = pressedIndex; - pressedIndex = i; - curr = i; - possibleChange(prev, curr, PRESSED); - return prev; - } - - /** - * Set the index of the tab which currently contains the mouse cursor. - * - * @param i The tab which contains the mouse cursor, or -1 to clear ARMED - * from the state of the tab - * @return Index of the tab which previously had the state ARMED, or -1 - */ - public final int setContainsMouse(int i) { - prev = containsMouseIndex; - containsMouseIndex = i; - curr = i; - possibleChange(prev, curr, ARMED); - return prev; - } - - /** - * Set the index of the tab whose close button contains the mouse cursor. - * - * @param i The index of the tab whose close button contains the mouse - * cursor, or -1 to clear CLOSE_BUTTON_CONTAINS_MOUSE from the - * state of the tab which previously had it - * @return Index of the tab which formerly had the state - * CLOSE_BUTTON_CONTAINS_MOUSE, or -1 - */ - public final int setCloseButtonContainsMouse(int i) { - prev = closeButtonContainsMouseIndex; - closeButtonContainsMouseIndex = i; - curr = i; - possibleChange(prev, curr, CLOSE_BUTTON_ARMED); - return prev; - } - - /** - * Set the index of the tab in which the mouse button has been pressed in - * the close button. This is distinct from the combination of - * CLOSE_BUTTON_ARMED and PRESSED, since the user may press the close button - * and then drag away from the close button (clearing the CLOSE_BUTTON_ARMED - * state) to abort closing a tab. - * - * @param i The tab in which the mouse was pressed while over the close - * button - * @return Index of the tab which previously had the state - * MOUSE_PRESSED_IN_CLOSE_BUTTON, or -1 - */ - public final int setMousePressedInCloseButton(int i) { - prev = mousePressedInCloseButtonIndex; - mousePressedInCloseButtonIndex = i; - curr = i; - possibleChange(prev, curr, MOUSE_PRESSED_IN_CLOSE_BUTTON); - return prev; - } - - /** - * Set the index of the tab which is currently selected. Note that users of - * this class must ensure that this value stays up to date when changes - * occur in the model such as inserting tabs before the selected one. - * - * @param i The tab index which is selected - * @return Index of the tab which previously was selected, or -1 if none - */ - public final int setSelected(int i) { - prev = selectedIndex; - selectedIndex = i; - curr = i; - removeAlarmTab(i); - possibleChange(prev, curr, SELECTED); - return prev; - } - - /** - * Set the condition for all tabs of the mouse being in the tabs area. - * - * @param b Whether the mouse is in the tabs area or not - * @return The previous state with regard to the mouse being in the tabs - * area - */ - public final boolean setMouseInTabsArea(boolean b) { - boolean prev = mouseInTabsArea; - mouseInTabsArea = b; - possibleChange(prev, b, MOUSE_IN_TABS_AREA); - return prev; - } - - /** - * Set the condition for all tabs of the component being activated. - * - * @param b Whether or not the component is activated - * @return The previous state with regard to the component being activated - */ - public final boolean setActive(boolean b) { - boolean prev = active; - active = b; - possibleChange(prev, b, ACTIVE); - removeAlarmTab(selectedIndex); - return prev; - } - - private boolean isAlarmTab (int tab) { - return attentionToggle && alarmTabs.contains(new Integer(tab)); - } - - private final HashSet alarmTabs = new HashSet(6); - - /** Add a tab to the list of those which should "flash" or otherwise give - * some notification to the user to get their attention */ - public final void addAlarmTab (int alarmTab) { - Integer in = new Integer(alarmTab); - boolean added = alarmTabs.contains(in); - boolean wasEmpty = alarmTabs.isEmpty(); - if (!added) { - alarmTabs.add (new Integer(alarmTab)); - repaintTab (alarmTab); - } - if (wasEmpty) { - startAlarmTimer(); - attentionToggle = true; - repaintTab (alarmTab); - } - } - - /** Remove a tab to the list of those which should "flash" or otherwise give - * some notification to the user to get their attention */ - public final void removeAlarmTab (int alarmTab) { - Integer in = new Integer(alarmTab); - boolean contained = alarmTabs.contains(in); - if (contained) { - alarmTabs.remove(in); - boolean empty = alarmTabs.isEmpty(); - boolean wasAttentionToggled = attentionToggle; - if (alarmTabs.isEmpty()) { - stopAlarmTimer(); - } - if (wasAttentionToggled) { - repaintTab(alarmTab); - } - } - } - - private Timer alarmTimer = null; - private boolean attentionToggle = false; - private final void startAlarmTimer() { - if (alarmTimer == null) { - ActionListener al = new ActionListener() { - public void actionPerformed (ActionEvent ae) { - attentionToggle = !attentionToggle; - Timer timer = (Timer) ae.getSource(); - for (Iterator i=alarmTabs.iterator(); i.hasNext();) { - repaintTab (((Integer) i.next()).intValue()); - } - } - }; - alarmTimer = new Timer (700, al); - alarmTimer.setRepeats(true); - } - alarmTimer.start(); - } - - private final void stopAlarmTimer() { - if (alarmTimer != null && alarmTimer.isRunning()) { - alarmTimer.stop(); - attentionToggle = false; - repaintAllTabs(); //XXX optimize - } - } - - boolean hasAlarmTabs() { - return alarmTabs != null && !alarmTabs.isEmpty(); - } - - void pruneAlarmTabs(int max) { - if (!hasAlarmTabs()) { - return; - } - for (Iterator i=alarmTabs.iterator(); i.hasNext();) { - if (((Integer) i.next()).intValue() >= max) { - i.remove(); - } - } - if (alarmTabs.isEmpty()) { - stopAlarmTimer(); - } - } - - int[] getAlarmTabs() { - int[] alarms = (int[]) Utilities.toPrimitiveArray((Integer[]) alarmTabs.toArray(new Integer[0])); - Arrays.sort(alarms); - return alarms; - } - - //Handling of insertions/deletions where we'll need to update the - //list of blinking tabs here. - void intervalAdded (ListDataEvent evt) { - if (!hasAlarmTabs()) return; - int start = evt.getIndex0(); - int end = evt.getIndex1(); - int[] alarms = (int[]) Utilities.toPrimitiveArray((Integer[]) alarmTabs.toArray(new Integer[0])); - boolean changed = false; - for (int i=0; i < alarms.length; i++) { - if (alarms[i] >= start) { - alarms[i] += (end - start) + 1; - changed = true; - } - } - if (changed) { - alarmTabs.clear(); - for (int i=0; i < alarms.length; i++) { - addAlarmTab(alarms[i]); - } - } - } - - void intervalRemoved (ListDataEvent evt) { - if (!hasAlarmTabs()) return; - int start = evt.getIndex0(); - int end = evt.getIndex1(); - - int[] alarms = (int[]) Utilities.toPrimitiveArray((Integer[]) alarmTabs.toArray(new Integer[0])); - Arrays.sort(alarms); - - if (end == start) { - //Faster to handle this case separately - boolean changed = true; - for (int i=0; i < alarms.length; i++) { - if (alarms[i] > end) { - alarms[i]--; - } else if (alarms[i] == end) { - alarms[i] = -1; - } - } - if (changed) { - alarmTabs.clear(); - boolean added = false; - for (int i=0; i < alarms.length; i++) { - if (alarms[i] != -1) { - addAlarmTab(alarms[i]); - added = true; - } - } - if (!added) { - stopAlarmTimer(); - } - } - return; - } - - boolean changed = false; - for (int i=0; i < alarms.length; i++) { - if (alarms[i] >= start && alarms[i] <= end) { - alarms[i] = -1; - changed = true; - } - } - for (int i=0; i < alarms.length; i++) { - if (alarms[i] > end) { - alarms[i] -= (end - start) + 1; - changed = true; - } - } - if (changed) { - alarmTabs.clear(); - boolean added = false; - for (int i=0; i < alarms.length; i++) { - if (alarms[i] != -1) { - addAlarmTab(alarms[i]); - added = true; - } - } - if (!added) { - stopAlarmTimer(); - } - } - } - - void indicesAdded (ComplexListDataEvent e) { - if (!hasAlarmTabs()) return; - int[] alarms = (int[]) Utilities.toPrimitiveArray((Integer[]) alarmTabs.toArray(new Integer[0])); - java.util.Arrays.sort(alarms); - - int[] indices = e.getIndices(); - java.util.Arrays.sort(indices); - - boolean changed = false; - for (int i=0; i < indices.length; i++) { - for (int j=0; j < alarms.length; j++) { - if (alarms[j] >= indices[i]) { - alarms[j]++; - changed = true; - } - } - } - if (changed) { - alarmTabs.clear(); - for (int i=0; i < alarms.length; i++) { - if (alarms[i] != -1) { - addAlarmTab(alarms[i]); - } - } - } - } - - void indicesRemoved (ComplexListDataEvent e) { - if (!hasAlarmTabs()) return; - int[] indices = e.getIndices(); - java.util.Arrays.sort(indices); - - int[] alarms = (int[]) Utilities.toPrimitiveArray((Integer[]) alarmTabs.toArray(new Integer[0])); - java.util.Arrays.sort(alarms); - - if (alarms[alarms.length -1] < indices[0]) { - //Some tab removed after the last blinking tab, don't care - return; - } - - boolean changed = false; - for (int i=0; i < alarms.length; i++) { - //First weed out all deleted alarm tabs - for (int j=0; j < indices.length; j++) { - if (alarms[i] == indices[j]) { - alarms[i] = -1; - changed = true; - } - } - } - for (int i=0; i < alarms.length; i++) { - //Now decrement those that remain that are affected - int alarm = alarms[i]; - for (int j=0; j < indices.length; j++) { - if (alarm > indices[j]) { - alarms[i]--; - changed = true; - } - } - } - - if (changed) { - alarmTabs.clear(); - boolean addedSome = false; - for (int i=0; i < alarms.length; i++) { - if (alarms[i] >= 0) { - addAlarmTab(alarms[i]); - addedSome = true; - } - } - if (!addedSome) { - stopAlarmTimer(); - } - } - - repaintAllTabs(); - } - - void indicesChanged (ComplexListDataEvent e) { - if (!hasAlarmTabs()) return; - if (e instanceof VeryComplexListDataEvent) { //it always will be - VeryComplexListDataEvent ve = (VeryComplexListDataEvent) e; - - ArrayDiff dif = ((VeryComplexListDataEvent) e).getDiff(); - - List old = Arrays.asList(dif.getOldData()); - List nue = Arrays.asList(dif.getNewData()); - - int[] alarms = (int[]) Utilities.toPrimitiveArray((Integer[]) alarmTabs.toArray(new Integer[0])); - - boolean changed = false; - for (int i=0; i < alarms.length; i++) { - Object o = old.get(alarms[i]); - int idx = nue.indexOf(o); - changed |= idx != alarms[i]; - alarms[i] = nue.indexOf(o); - } - if (changed) { - alarmTabs.clear(); - boolean addedSome = false; - for (int i=0; i < alarms.length; i++) { - if (alarms[i] >= 0) { - addAlarmTab(alarms[i]); - addedSome = true; - } - } - if (!addedSome) { - stopAlarmTimer(); - } - } - } - } - - - void contentsChanged(ListDataEvent evt) { - if (!hasAlarmTabs()) return; - //Do nothing, just means some text or icons changed - } - - //Change types - /** Change type indicating no change happened (i.e. calling setSelected() with the same value it was previously - * called with). - */ - public static final int NO_CHANGE = 0; - /** Change type indicating a change of state for two tabs */ - public static final int CHANGE_TAB_TO_TAB = 1; - /** Change type indicating a change happened (such as the mouse leaving a tab) such that now no tab has the - * state previously held by the affected tab */ - public static final int CHANGE_TAB_TO_NONE = 2; - /** Change type indicating that a state was added that no tab previously had */ - public static final int CHANGE_NONE_TO_TAB = 3; - public static final int CHANGE_TAB_TO_SELF = 4; - /** Change type indicating one of the boolean state changes, such as STATE_ACTIVE */ - public static final int ALL_TABS = Integer.MAX_VALUE; - - protected void possibleChange(boolean prevVal, boolean currVal, int type) { - if (prevVal == currVal) { - lastChangeType = NO_CHANGE; - } else { - lastChangeType = ALL_TABS; - } - if (lastChangeType != NO_CHANGE) { - lastAffected = ALL_TABS; - change(ALL_TABS, ALL_TABS, type, lastChangeType); - } - } - - protected void possibleChange(int lastTab, int currTab, int type) { - if (lastTab == currTab) { - lastChangeType = NO_CHANGE; - } else { - if (currTab == -1) { - lastChangeType = CHANGE_TAB_TO_NONE; - } else if (lastTab == -1) { - lastChangeType = CHANGE_NONE_TO_TAB; - } else { - lastChangeType = CHANGE_TAB_TO_TAB; - } - } - if (lastChangeType != NO_CHANGE) { - lastAffected = currTab; - change(lastTab, currTab, type, lastChangeType); - } - } - - public String toString() { - StringBuffer sb = new StringBuffer(50); - sb.append("TabState [lastTab="); - sb.append(tabToString(prev)); - sb.append(" currTab="); - sb.append(tabToString(curr)); - sb.append(" lastAffected="); - sb.append(tabToString(lastAffected)); - sb.append(" lastChangeType="); - sb.append(changeToString(lastChangeType)); - sb.append(" lastChange="); - sb.append(stateToString(lastChange)); - sb.append(" ]"); - return sb.toString(); - } - - /** - * Called when a setter for a tab index has produced a change in a - * state-affecting property, such as which tab contains the mouse. Fetches - * the repaint policies, and if the change is one that the policy says - * should produce a repaint, calls repaintTab for the appropriate tabs. - * - * @param lastTab The tab previously holding the state which has changed, - * or -1 - * @param currTab The tab currently holding the state which has changed, - * or -1 - * @param type The thing that changed. This will be one of the state - * constants. - * @param changeType This is one of the defined change types such as - * ALL_TABS, TAB_TO_TAB, etc. - */ - protected void change(int lastTab, int currTab, int type, int changeType) { - lastChange = type; - // System.err.println("Change-type: " + stateToString(type) + " - " + changeToString (changeType) + " from " + tabToString (lastTab) + " to " + tabToString (currTab)); - if (changeType == CHANGE_TAB_TO_TAB) { - maybeRepaint(lastTab, type); - } else if (changeType == CHANGE_TAB_TO_NONE) { - maybeRepaint (lastTab, type); - return; - } else if (changeType == ALL_TABS && (getRepaintPolicy(currTab) & REPAINT_ALL_ON_MOUSE_ENTER_TABS_AREA) != 0) { - repaintAllTabs(); - return; - } - maybeRepaint(currTab, type); - } - - protected void maybeRepaint(int tab, int type) { - int rpol = getRepaintPolicy (tab); - boolean go = false; - switch (type) { - case ACTIVE: - go = (rpol - & REPAINT_SELECTION_ON_ACTIVATION_CHANGE) - != 0; - if ((rpol - & REPAINT_ALL_TABS_ON_ACTIVATION_CHANGE) - != 0) { - type = ALL_TABS; - go = true; - } - break; - case ARMED: - go = (rpol & REPAINT_ON_MOUSE_ENTER_TAB) != 0 || - tab == closeButtonContainsMouseIndex; - closeButtonContainsMouseIndex = -1; - break; - case CLOSE_BUTTON_ARMED: - go = (rpol & REPAINT_ON_MOUSE_ENTER_CLOSE_BUTTON) - != 0; - break; - case MOUSE_IN_TABS_AREA: - go = (rpol - & REPAINT_ALL_ON_MOUSE_ENTER_TABS_AREA) - != 0; - break; - case MOUSE_PRESSED_IN_CLOSE_BUTTON: - go = (rpol & REPAINT_ON_CLOSE_BUTTON_PRESSED) - != 0; - break; - case PRESSED: - go = (rpol & REPAINT_ON_MOUSE_PRESSED) != 0; - break; - case SELECTED: - go = (rpol & REPAINT_ON_SELECTION_CHANGE) != 0; - if ((rpol & REPAINT_ALL_TABS_ON_SELECTION_CHANGE) - != 0) { - type = ALL_TABS; - go = true; - } - break; - case ATTENTION: - go = true; - } - if (go) { - if (type == ALL_TABS) { - repaintAllTabs(); - } else { - repaintTab(tab); - } - } - } - - protected abstract void repaintTab(int tab); - - protected abstract void repaintAllTabs(); - - static final String changeToString(int change) { - switch (change) { - case NO_CHANGE: - return "no change"; //NOI18N - case CHANGE_TAB_TO_TAB: - return "tab to tab"; //NOI18N - case CHANGE_TAB_TO_NONE: - return "tab to none"; //NOI18N - case CHANGE_NONE_TO_TAB: - return "none to tab"; //NOI18N - case CHANGE_TAB_TO_SELF: - return "tab to self"; //NOI18N - case ALL_TABS: - return "all tabs"; //NOI18N - default : - return "??? " + change; //NOI18N - } - } - - static final String tabToString(int tab) { - if (tab == ALL_TABS) { - return "all tabs"; //NOI18N - } else if (tab == -1) { - return "none"; //NOI18N - } else { - return Integer.toString(tab); - } - } - - /** - * Static utility method to get a string representation of a state - */ - static final String stateToString(int st) { - String[] states = new String[]{ - "clip right", "clip left", "armed", "pressed", "selected", "active", "not onscreen", "leftmost", //NOI18N - "rightmost", "in closebutton", "before selected", "after selected", "mouse in tabs area", //NOI18N - "mouse pressed in close button" //NOI18N - }; //NOI18N - int[] vals = new int[]{ - CLIP_RIGHT, CLIP_LEFT, ARMED, PRESSED, SELECTED, ACTIVE, - NOT_ONSCREEN, LEFTMOST, RIGHTMOST, CLOSE_BUTTON_ARMED, - BEFORE_SELECTED, AFTER_SELECTED, MOUSE_IN_TABS_AREA, - MOUSE_PRESSED_IN_CLOSE_BUTTON}; - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < vals.length; i++) { - if ((st & vals[i]) != 0) { - if (sb.length() > 0) { - sb.append(','); - } - sb.append(states[i]); - } - } - if (sb.length() == 0) { - sb.append("no flags set"); //NOI18N - } - sb.append("="); - sb.append(st); - return sb.toString(); - } - - static String repaintPolicyToString (int policy) { - if (policy == 0) { - return "repaint nothing"; - } - String[] names = new String[] { - "REPAINT_ON_MOUSE_ENTER_TAB", - "REPAINT_ALL_ON_MOUSE_ENTER_TABS_AREA", - "REPAINT_ON_MOUSE_ENTER_CLOSE_BUTTON", - "REPAINT_ON_MOUSE_PRESSED", - "REPAINT_SELECTION_ON_ACTIVATION_CHANGE", - "REPAINT_ALL_TABS_ON_ACTIVATION_CHANGE", - "REPAINT_ON_SELECTION_CHANGE", - "REPAINT_ALL_TABS_ON_SELECTION_CHANGE", - "REPAINT_ON_CLOSE_BUTTON_PRESSED", - }; - int[] vals = new int[] { - REPAINT_ON_MOUSE_ENTER_TAB, - REPAINT_ALL_ON_MOUSE_ENTER_TABS_AREA, - REPAINT_ON_MOUSE_ENTER_CLOSE_BUTTON, - REPAINT_ON_MOUSE_PRESSED, - REPAINT_SELECTION_ON_ACTIVATION_CHANGE, - REPAINT_ALL_TABS_ON_ACTIVATION_CHANGE, - REPAINT_ON_SELECTION_CHANGE, - REPAINT_ALL_TABS_ON_SELECTION_CHANGE, - REPAINT_ON_CLOSE_BUTTON_PRESSED, - }; - StringBuffer sb = new StringBuffer(); - for (int i=0; i < vals.length; i++) { - if ((policy & vals[i]) != 0) { - sb.append (names[i]); - if (i != vals.length-1) { - sb.append ('+'); - } - } - } - return sb.toString(); - } - - /** - * Get the repaint policy that will be used to determine what tabs to repaint, based on state changes. - * The default implementation in BasicTabDisplayerUI simply ignores the tab argument and returns a - * single policy for all tabs created in BasicTabDisplayerUI.createRepaintPolicy() - * - * @param tab Index of tab in question - * @return Type of repaint policy for given tab - */ - public abstract int getRepaintPolicy(int tab); - } --- 1,0 ---- Index: SubstanceEditorTabDisplayerUI.java *** D:\projects\substance-netbeans\src\org\jvnet\substance\netbeans\SubstanceEditorTabDisplayerUI.java Base (1.10) --- D:\projects\substance-netbeans\src\org\jvnet\substance\netbeans\SubstanceEditorTabDisplayerUI.java Locally Modified (Based On 1.10) *************** *** 26,138 **** public class SubstanceEditorTabDisplayerUI extends BasicScrollingTabDisplayerUI { private Rectangle scratch = new Rectangle(); - /** - * A convenience button class which will continue re-firing its action on a - * timer for as long as the button is depressed. Used for left-right scroll - * buttons. - */ - protected static class TimerButton extends JButton implements - ActionListener { - Timer timer = null; - Image disabledImage = null; - - Image enabledImage = null; - - public TimerButton(Action a) { - super(a); - } - - private Timer getTimer() { - if (timer == null) { - timer = new Timer(400, this); - timer.setRepeats(true); - } - return timer; - } - - int count = 0; - - public void actionPerformed(java.awt.event.ActionEvent e) { - count++; - if (count > 2) { - if (count > 5) { - timer.setDelay(75); - } else { - timer.setDelay(200); - } - } - performAction(); - } - - private void performAction() { - if (!isEnabled()) { - stopTimer(); - return; - } - getAction().actionPerformed( - new ActionEvent(this, ActionEvent.ACTION_PERFORMED, - getActionCommand())); - } - - private void startTimer() { - performAction(); - Timer t = getTimer(); - if (t.isRunning()) { - return; - } - repaint(); - t.setDelay(400); - t.start(); - } - - private void stopTimer() { - if (timer != null) { - timer.stop(); - } - repaint(); - count = 0; - } - - protected void processMouseEvent(MouseEvent me) { - if (isEnabled() && me.getID() == MouseEvent.MOUSE_PRESSED) { - startTimer(); - } else if (me.getID() == MouseEvent.MOUSE_RELEASED) { - stopTimer(); - } else { - super.processMouseEvent(me); - } - } - - protected void processFocusEvent(FocusEvent fe) { - super.processFocusEvent(fe); - if (fe.getID() == FocusEvent.FOCUS_LOST) { - stopTimer(); - } - } - } - /** - * A convenience button class which fires its action event on mouse pressed, - * not mouse released. Used to enable press-and-drag behavior on the tab - * list popup. - */ - protected static class OnPressButton extends JButton { - public OnPressButton(Action a) { - super(a); - } - - protected void processMouseEvent(MouseEvent me) { - super.processMouseEvent(me); - if (isEnabled() && me.getID() == MouseEvent.MOUSE_PRESSED) { - getAction().actionPerformed( - new ActionEvent(this, ActionEvent.ACTION_PERFORMED, - "pressed")); - } - } - } - - /** * Simple constructor. */ public SubstanceEditorTabDisplayerUI(TabDisplayer displayer) { --- 26,33 ---- *************** *** 228,274 **** return new SubstanceTabLayout(); } - /* (non-Javadoc) - * @see org.netbeans.swing.tabcontrol.plaf.BasicScrollingTabDisplayerUI#createControlButtons() - */ - protected AbstractButton[] createControlButtons() { - JButton[] result = new JButton[3]; - result[0] = new TimerButton(scroll().getBackwardAction()); - result[1] = new TimerButton(scroll().getForwardAction()); - result[2] = new OnPressButton(new TabListPopupAction(displayer)); - configureButton(result[0], SubstanceImageCreator.getArrowIcon(SubstanceSizeUtils.getArrowIconWidth(), - SubstanceSizeUtils.getArrowIconHeight(), SubstanceSizeUtils.getArrowStrokeWidth(), - SwingConstants.WEST, SubstanceCoreUtilities.getActiveTheme(null, true))); - result[0].putClientProperty(SubstanceLookAndFeel.BUTTON_SIDE_PROPERTY, - SubstanceConstants.Side.RIGHT.name()); - - configureButton(result[1], SubstanceImageCreator.getArrowIcon(SubstanceSizeUtils.getArrowIconWidth(), - SubstanceSizeUtils.getArrowIconHeight(), SubstanceSizeUtils.getArrowStrokeWidth(), - SwingConstants.EAST, SubstanceCoreUtilities.getActiveTheme(null, true))); - result[1].putClientProperty(SubstanceLookAndFeel.BUTTON_SIDE_PROPERTY, - SubstanceConstants.Side.LEFT.name()); - - configureButton(result[2], SubstanceImageCreator.getArrowIcon(SubstanceSizeUtils.getArrowIconWidth(), - SubstanceSizeUtils.getArrowIconHeight(), SubstanceSizeUtils.getArrowStrokeWidth(), - SwingConstants.SOUTH, SubstanceCoreUtilities.getActiveTheme(null, true))); - result[0].setPreferredSize(new Dimension(17, 17)); - result[1].setPreferredSize(new Dimension(17, 17)); - result[2].setPreferredSize(new Dimension(17, 17)); - scroll().getBackwardAction().putValue("control", displayer); // NOI18N - scroll().getForwardAction().putValue("control", displayer); // NOI18N - - return result; - } - - private static void configureButton(JButton button, Icon icon) { - button.setIcon(icon); - button.setMargin(null); - button.setText(null); - // undocumented (?) call to hide action text - see JButton line 234 - button.putClientProperty("hideActionText", Boolean.TRUE); // NOI18N - button.setFocusable(false); - } - public Rectangle getTabRect(int idx, Rectangle rect) { Rectangle retValue; --- 123,128 ---- Index: SubstanceModule.java *** D:\projects\substance-netbeans\src\org\jvnet\substance\netbeans\SubstanceModule.java Base (1.10) --- D:\projects\substance-netbeans\src\org\jvnet\substance\netbeans\SubstanceModule.java Locally Modified (Based On 1.10) *************** *** 1,5 **** --- 1,6 ---- package org.jvnet.substance.netbeans; + import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import org.jvnet.lafwidget.utils.FadeConfigurationManager; *************** *** 21,26 **** --- 22,30 ---- */ public class SubstanceModule extends ModuleInstall { public void restored() { + // SwingUtilities.invokeLater( new Runnable() { + // + // public void run() { try { SubstanceLookAndFeel slf = new SubstanceLookAndFeel(); UIManager.setLookAndFeel(slf); *************** *** 48,53 **** --- 52,60 ---- ErrorManager.getDefault().notify(ulafe); throw new RuntimeException(ulafe); } + // } + + // }); } public void uninstalled() { Index: ViewTabLayoutModel.java *** D:\projects\substance-netbeans\src\org\jvnet\substance\netbeans\ViewTabLayoutModel.java Base (1.1) --- D:\projects\substance-netbeans\src\org\jvnet\substance\netbeans\ViewTabLayoutModel.java Locally Deleted *************** *** 1,142 **** - /* - * Sun Public License Notice - * - * The contents of this file are subject to the Sun Public License - * Version 1.0 (the "License"). You may not use this file except in - * compliance with the License. A copy of the License is available at - * http://www.sun.com/ - * - * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun - * Microsystems, Inc. All Rights Reserved. - */ - - package org.jvnet.substance.netbeans; - - import org.netbeans.swing.tabcontrol.TabDataModel; - - import javax.swing.*; - import java.awt.*; - - /** - * Implementation of layout model for View-type tabs, which are not scrollable - * and are shrinking and extending their size to always cover whole tabs area. - * - * @author Dafe Simonek - */ - public class ViewTabLayoutModel implements TabLayoutModel { - - private TabDataModel model; - - private JComponent renderTarget; - - /** - * Creates a new instance of ViewTabLayoutModel - */ - public ViewTabLayoutModel(TabDataModel model, - JComponent renderTarget) { - this.model = model; - this.renderTarget = renderTarget; - } - - public int getH(int index) { - checkIndex(index); - Insets insets = renderTarget.getInsets(); - return renderTarget.getHeight() - (insets.bottom + insets.top); - } - - public int getW(int index) { - checkIndex(index); - int x = computeX(index); - int nextX; - if (index < model.size() - 1) { - nextX = computeX(index + 1); - } else { - // last tab, special case - Insets insets = renderTarget.getInsets(); - nextX = renderTarget.getWidth() - insets.right; - } - // substract from next tab to get width - return nextX - x; - } - - public int getX(int index) { - checkIndex(index); - return computeX(index); - } - - public int getY(int index) { - checkIndex(index); - return renderTarget.getInsets().top; - } - - public int indexOfPoint(int x, int y) { - Insets insets = renderTarget.getInsets(); - int contentWidth = renderTarget.getWidth() - - (insets.left + insets.right); - int contentHeight = renderTarget.getHeight() - - (insets.bottom + insets.top); - if (y < insets.top || y > contentHeight || x < insets.left - || x > contentWidth) { - return -1; - } - int size = model.size(); - int diff; - for (int i = 0; i < size; i++) { - diff = x - computeX(i); - if ((diff >= 0) && (diff < getW(i))) { - return i; - } - } - return -1; - } - - public int dropIndexOfPoint(int x, int y) { - Insets insets = renderTarget.getInsets(); - int contentWidth = renderTarget.getWidth() - - (insets.left + insets.right); - int contentHeight = renderTarget.getHeight() - - (insets.bottom + insets.top); - if (y < insets.top || y > contentHeight || x < insets.left - || x > contentWidth) { - return -1; - } - // can have rounding errors, not important here - int size = model.size(); - float tabWidth = (float) contentWidth / (float) size; - // move in between tabs - x = x - insets.left + (int) tabWidth / 2; - int result = (int) (x / tabWidth); - return Math.min(result, model.size()); - } - - public void setPadding(Dimension d) { - //do nothing - } - - /** - * Checks validity of given index - */ - private void checkIndex(int index) { - int size = model.size(); - if ((index < 0) || (index >= size)) { - throw new IllegalArgumentException("Index out of valid scope 0.." - + (size - 1) - + ": " - + index); - } - } - - /** - * Computes and returns x coordination of left side of the tab with given - * index - */ - private int computeX(int index) { - Insets insets = renderTarget.getInsets(); - int contentWidth = renderTarget.getWidth() - - (insets.left + insets.right); - return (contentWidth * index / model.size()) + insets.left; - } - - - } --- 1,0 ---- Index: TabLayoutModel.java *** D:\projects\substance-netbeans\src\org\jvnet\substance\netbeans\TabLayoutModel.java Base (1.1) --- D:\projects\substance-netbeans\src\org\jvnet\substance\netbeans\TabLayoutModel.java Locally Deleted *************** *** 1,85 **** - /* - * Sun Public License Notice - * - * The contents of this file are subject to the Sun Public License - * Version 1.0 (the "License"). You may not use this file except in - * compliance with the License. A copy of the License is available at - * http://www.sun.com/ - * - * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun - * Microsystems, Inc. All Rights Reserved. - *//* - * TabLayoutModel.java - * - * Created on May 16, 2003, 3:47 PM - */ - - package org.jvnet.substance.netbeans; - - import java.awt.*; - - - /** - * A model representing the visual layout of tabs in a TabDataModel as a set of - * rectangles. Used by BasicTabDisplayerUI and its subclasses to manage the layout of - * tabs in the displayer. - * - * @author Tim Boudreau - */ - public interface TabLayoutModel { - /** - * Get the x coordinate of the tab rectangle for the tab at index - * index in the data model. - * - * @param index The tab index - * @return The coordinate - */ - public int getX(int index); - - /** - * Get the y coordinate of the tab rectangle for the tab at index - * index in the data model. - * - * @param index The tab index - * @return The coordinate - */ - public int getY(int index); - - /** - * Get the width of the tab rectangle for the tab at index - * index in the data model. - * - * @param index The tab index - * @return The width - */ - public int getW(int index); - - /** - * Get the height of the tab rectangle for the tab at index - * index in the data model. - * - * @param index The tab index - * @return The height - */ - public int getH(int index); - - /** - * Get the index of the tab in the data model for the supplied point. - * - * @param x X coordinate of a point representing a set of pixel coordinate in the space - * modeled by this layout model - * @param y Y coordinate - * @return The index into the data model of the tab displayed at the passed - * point or -1 - */ - public int indexOfPoint(int x, int y); - - // XXX DnD only - /** - * Gets the index of possibly dropped component (as a new tab). - */ - public int dropIndexOfPoint(int x, int y); - - public void setPadding (Dimension d); - } --- 1,0 ---- Index: SubstanceViewTabDisplayerUI.java *** D:\projects\substance-netbeans\src\org\jvnet\substance\netbeans\SubstanceViewTabDisplayerUI.java Base (1.8) --- D:\projects\substance-netbeans\src\org\jvnet\substance\netbeans\SubstanceViewTabDisplayerUI.java Locally Modified (Based On 1.8) *************** *** 16,27 **** import java.util.Set; import org.jvnet.substance.button.BaseButtonShaper; import org.jvnet.substance.color.ColorScheme; - import org.jvnet.substance.netbeans.AbstractViewTabDisplayerUI.PinButton; import org.jvnet.substance.painter.SubstanceGradientPainter; import org.jvnet.substance.utils.SubstanceConstants.Side; import org.openide.awt.HtmlRenderer; --- 16,24 ---- import java.util.Set; import org.jvnet.substance.button.BaseButtonShaper; import org.jvnet.substance.color.ColorScheme; import org.jvnet.substance.painter.SubstanceGradientPainter; import org.jvnet.substance.utils.SubstanceConstants.Side; + import org.netbeans.swing.tabcontrol.plaf.AbstractViewTabDisplayerUI; import org.openide.awt.HtmlRenderer; *************** *** 38,50 **** * ****** static fields ********** */ - private static Icon closeIcon; - private static Color inactBgColor, actBgColor, borderHighlight, borderShadow; /** * ******* instance fields ********* --- 38,48 ---- * ****** static fields ********** */ private static Color inactBgColor, actBgColor, borderHighlight, borderShadow; + private FontMetrics fm; + + private Font txtFont; /** * ******* instance fields ********* */ *************** *** 61,69 **** public void installUI(JComponent c) { super.installUI(c); - if (closeIcon == null) { - closeIcon = SubstanceImageCreator.getCloseIcon(SubstanceLookAndFeel.getTheme()); - } displayer.setFont(SubstanceLookAndFeel.getFontPolicy().getFontSet("Substance", null).getControlFont()); } --- 62,67 ---- *************** *** 75,84 **** return new SubstanceViewTabDisplayerUI((TabDisplayer) c); } - protected AbstractViewTabDisplayerUI.Controller createController() { - return new OwnController(); - } - public Dimension getPreferredSize(JComponent c) { FontMetrics fm = getTxtFontMetrics(); int height = fm == null ? --- 73,78 ---- *************** *** 122,147 **** // setting font already here to compute string width correctly g2.setFont(getTxtFont()); int txtWidth = width; - if (isSelected(index)) { - PinButton pin = configurePinButton(index); - boolean showPin = pin != null && pin.getOrientation() != TabDisplayer.ORIENTATION_INVISIBLE; - int space4Pin = showPin ? pinButton.getWidth() + 1 : 0; - int space4Icon = 0; - if (displayer.isShowCloseButton()) { - Icon icon = closeIcon; - int iconWidth = icon.getIconWidth(); - space4Icon = iconWidth + ICON_X_LEFT_PAD + ICON_X_RIGHT_PAD + space4Pin; - txtWidth = width - 2 * TXT_X_PAD - space4Icon; - getCloseIconRect(tempRect, index); - icon.paintIcon(getDisplayer(), g2, tempRect.x, tempRect.y); - } else { - tempRect.x = x + (width - 2); ! tempRect.y = !showPin ? 0 : ((displayer.getHeight() / 2) - ! (pinButton.getPreferredSize().height / 2)); ! int pinWidth = showPin ? 0 : pinButton.getPreferredSize().width; ! txtWidth = (width - 2 * TXT_X_PAD) - pinWidth; ! space4Icon = pinWidth + 5; } txtWidth = (int)HtmlRenderer.renderString(text, g2, x + TXT_X_PAD, height - fm.getDescent() - 4, txtWidth, height, getTxtFont(), --- 116,128 ---- // setting font already here to compute string width correctly g2.setFont(getTxtFont()); int txtWidth = width; ! if (isSelected(index)) { ! Component buttons = getControlButtons(); ! if( null != buttons ) { ! Dimension buttonsSize = buttons.getPreferredSize(); ! txtWidth = width - (buttonsSize.width + ICON_X_LEFT_PAD + ICON_X_RIGHT_PAD + 2*TXT_X_PAD); ! buttons.setLocation( x + txtWidth+2*TXT_X_PAD, y + (height-buttonsSize.height)/2+1 ); } txtWidth = (int)HtmlRenderer.renderString(text, g2, x + TXT_X_PAD, height - fm.getDescent() - 4, txtWidth, height, getTxtFont(), *************** *** 148,170 **** UIManager.getColor("textText"), HtmlRenderer.STYLE_TRUNCATE, true); int bumpWidth = width ! - (TXT_X_PAD + txtWidth + BUMP_X_PAD + space4Icon); if (bumpWidth > 0) { paintBump(index, g2, x + TXT_X_PAD + txtWidth + BUMP_X_PAD, y + BUMP_Y_PAD, bumpWidth, height - 2 * BUMP_Y_PAD); } - if (showPin) { - // don't activate and draw pin button if tab is too narrow - if (tempRect.x - space4Pin < x + TXT_X_PAD - 1) { - pinButton.setVisible(false); } else { - pinButton.setVisible(true); - pinButton.setLocation(tempRect.x - space4Pin, tempRect.y + 2); - } - } else { - pinButton.setVisible(false); - } - } else { txtWidth = width - 2 * TXT_X_PAD; HtmlRenderer.renderString(text, g2, x + TXT_X_PAD, height - fm.getDescent() - 4, txtWidth, height, getTxtFont(), --- 129,143 ---- UIManager.getColor("textText"), HtmlRenderer.STYLE_TRUNCATE, true); int bumpWidth = width ! - (TXT_X_PAD + txtWidth + BUMP_X_PAD); if (bumpWidth > 0) { paintBump(index, g2, x + TXT_X_PAD + txtWidth + BUMP_X_PAD, y + BUMP_Y_PAD, bumpWidth, height - 2 * BUMP_Y_PAD); } } else { txtWidth = width - 2 * TXT_X_PAD; HtmlRenderer.renderString(text, g2, x + TXT_X_PAD, height - *************** *** 227,295 **** } /** ! * Computes rectangle occupied by close icon and fill values in given ! * rectangle. */ ! private Rectangle getCloseIconRect(Rectangle rect, int index) { ! TabLayoutModel tlm = getLayoutModel(); ! int x = tlm.getX(index); ! int w = tlm.getW(index); ! if (closeIcon == null) { ! //Tab control can be asked to process mouse motion events that ! //occured during startup - this causes an NPE here ! closeIcon = SubstanceImageCreator.getCloseIcon(SubstanceLookAndFeel.getTheme()); } - int iconWidth = closeIcon.getIconWidth(); - int iconHeight = closeIcon.getIconHeight(); - rect.x = x + w - iconWidth - ICON_X_RIGHT_PAD; - rect.y = getCenteredIconY(closeIcon, index); - rect.width = iconWidth; - rect.height = iconHeight; - return rect; } ! ! protected PinButton createPinButton() { ! Map normalIcons = new HashMap(6); ! normalIcons.put(TabDisplayer.ORIENTATION_EAST, "org/netbeans/swing/tabcontrol/resources/win-pin-normal-east.gif"); ! normalIcons.put(TabDisplayer.ORIENTATION_WEST, "org/netbeans/swing/tabcontrol/resources/win-pin-normal-west.gif"); ! normalIcons.put(TabDisplayer.ORIENTATION_SOUTH, "org/netbeans/swing/tabcontrol/resources/win-pin-normal-south.gif"); ! normalIcons.put(TabDisplayer.ORIENTATION_CENTER, "org/netbeans/swing/tabcontrol/resources/win-pin-normal-center.gif"); ! PinButton result = new PinButton(normalIcons, null, null); ! result.setRolloverEnabled(true); ! return result; } - - /** - * Own close icon button controller - */ - private class OwnController extends Controller { - //TODO - add a method to AbstractViewTabDisplayerUI to get the close button rect and implement everything - //on the parent class - - protected int inCloseIconRect(Point point) { - if (!displayer.isShowCloseButton()) { - return -1; } - int index = getLayoutModel().indexOfPoint(point.x, point.y); - if (index < 0 || !isSelected(index)) { - return -1; - } - return getCloseIconRect(tempRect, index).contains(point) ? - index : -1; - } - - protected boolean inPinButtonRect(Point p) { - if (!pinButton.isVisible()) { - return false; - } - Point p2 = SwingUtilities.convertPoint(displayer, p, pinButton); - return pinButton.contains(p2); - } - - - } // end of OwnController - } --- 197,219 ---- } /** ! * Specifies font to use for text and font metrics. Subclasses may override ! * to specify their own text font */ ! protected Font getTxtFont() { ! if (txtFont == null) { ! txtFont = SubstanceLookAndFeel.getFontPolicy().getFontSet("Substance", null).getControlFont(); ! if (txtFont == null) { ! txtFont = new Font("Dialog", Font.PLAIN, 11); ! } else if (txtFont.isBold()) { ! // don't use deriveFont() - see #49973 for details ! txtFont = new Font(txtFont.getName(), Font.PLAIN, txtFont.getSize()); } } ! return txtFont; } }