summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Schuster <theBohemian@gmx.net>2006-07-27 01:28:41 +0000
committerRobert Schuster <theBohemian@gmx.net>2006-07-27 01:28:41 +0000
commitc3578ff8df212cfd845d637bc8e129d627f9d68f (patch)
treee691fca4834e535e7eb474133eafdd514464cee0
parent23df147bbd9c192ff4aef97581041e1a0a97f421 (diff)
downloadclasspath-c3578ff8df212cfd845d637bc8e129d627f9d68f.tar.gz
2006-07-27 Robert Schuster <robertschuster@fsfe.org>
* javax/swing/plaf/basic/BasicTabbedPaneUI.java: Fixed copyright and authorship. (NavigateAction): New inner class. (NavigatePageDownAction): New inner class. (NavigatePageUpAction): New inner class. (RequestFocusAction): New inner class. (RequestFocusForVisibleComponentAction): New inner class. (FocusHandler.focusGained): Implemented. (FocusHandler.focusLost): Implemented. (MouseHandler.mouseReleased): Implemented. (MouseHandler.mousePressed): Rewritten. (PropertyChangeHandler.propertyChange): Reset currentScrollOffset and currentScrollLocation to 0. (TabbedPaneLayout.calculateSize): Stored tab count in local variable, removed local variables, fixed indentation to stay under 80 column limit. (TabbedPaneLayout.calculateTabRects): Decrease tab area position by one, set selectedIndex to 0 if its negative, corrected start values for normalization, suppressed padding when only one tab run, (TabbedPaneLayout.minimumLayoutSize): Toggled argument value. (TabbedPaneLayout.normalizeTabRuns): Fixed indentation to stay under 80 column limit, corrected the starting value for the bounds fixing phase. (TabbedPaneLayout.preferredTabAreaWidth): Fixed indentation. (TabbedPaneLayout.rotateTabInRuns): Corrected comparison value for selectedRun, set start index for loop to 0. (TabbedPaneScrollLayout.preferredLayoutSize): Toggled argument value. (TabbedPaneScrollLayout.calculateTabRects): Rewritten. (TabbedPaneScrollLayout.layoutContainer): Added scrolling button alignment and visibility handling. (TabSelectionHandler.stateChanged): Do revalidation only in wrap tab layout mode. (ScrollingPanel.ScrollingPanelUI.paint): Rewritten. (currentScrollOffset): New field. (tabRuns): Rewritten documentation. (selectedColor): New field. (tempTextRect): New field. (tempIconRect): New field. (scrollTab): New method. (updateButtons): New method. (updateViewPosition): New method. (createLayoutManager): Reordered method calls, predefine new fields, register proper listeners. (uninstallComponents): Implemented. (installDefaults): Corrected property names, fixed indentation,. (uninstallDefaults): Set new fields to null. (uninstallListeners): Remove listeners from components neccessary for scrolling tab layout. (installKeyboardActions): Implemented. (uninstallKeyboardActions): Implemented. (paint): Paint tab area background. (paintTabArea): Fixed indentation, removed usage of local Rectangle objects. (getTabLabelShiftX): Rewritten. (getTabLabelShiftY): Rewritten. (paintFocusIndicator): Reindented. (paintTabBorder): Rewritten. (paintTabBackground): Corrected color usage, rewritten background rectangle painting. (paintContentBorderTopEdge): Rewritten. (paintContentBorderBottomEdge): Rewritten. (paintContentBorderLeftEdge): Rewritten. (paintContentBorderRightEdge): Rewritten. (tabForCoordinate): Return selected index when no tab could be found, removed FIXME note. (getRunForTab): Changed return value for first if-statement. (navigateSelectedTab): Fixed last argument for both getTabRunOffset() calls. (selectedNextTabInRun): Added scrolling code. (selectedPreviousTabInRun): Added scrolling code. (selectedNextTab): Added scrolling code. (selectedPreviousTab): Added scrolling code. (selectAdjacentRunTab): Added scrolling code. (getTextViewForTab): Added FIXME note. (calculateTabHeight): Changed FIXME note. (getTabRunOffset): Fixed indentation. (getNextTabIndexInRun): Corrected return value. (rotateInsets): Make TOP case the default in switch-statement. (getActionMap): New method. (createActionMap): New method. * javax/swing/plaf/metal/MetalTabbedPaneUI.java: (createLayoutManager): Rewritten. (paintLeftTabBorder): Do not paint left line when previous tab is selected but current tab is the first in its run, do not paint left line when current tab is selected and is first in its run. (paintRightTabBorder): Added missing setColor() call, fixed color usage, do not paint right line if previous tab is selected but current tab is the first in its run. (paintBottomTabBorder): Do not paint left line if tab is selected and is the first tab in the last run. (paintFocusIndicator): New method. (getLabelShiftX): New method. (getLabelShiftY): New method.
-rw-r--r--ChangeLog96
-rw-r--r--javax/swing/plaf/basic/BasicTabbedPaneUI.java1220
-rw-r--r--javax/swing/plaf/metal/MetalTabbedPaneUI.java148
3 files changed, 1161 insertions, 303 deletions
diff --git a/ChangeLog b/ChangeLog
index ec582ed8a..55c781b79 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,99 @@
+2006-07-27 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/plaf/basic/BasicTabbedPaneUI.java: Fixed copyright and
+ authorship.
+ (NavigateAction): New inner class.
+ (NavigatePageDownAction): New inner class.
+ (NavigatePageUpAction): New inner class.
+ (RequestFocusAction): New inner class.
+ (RequestFocusForVisibleComponentAction): New inner class.
+ (FocusHandler.focusGained): Implemented.
+ (FocusHandler.focusLost): Implemented.
+ (MouseHandler.mouseReleased): Implemented.
+ (MouseHandler.mousePressed): Rewritten.
+ (PropertyChangeHandler.propertyChange): Reset currentScrollOffset and
+ currentScrollLocation to 0.
+ (TabbedPaneLayout.calculateSize): Stored tab count in local variable,
+ removed local variables, fixed indentation to stay under 80 column
+ limit.
+ (TabbedPaneLayout.calculateTabRects): Decrease tab area position by
+ one, set selectedIndex to 0 if its negative, corrected start values
+ for normalization, suppressed padding when only one tab run,
+ (TabbedPaneLayout.minimumLayoutSize): Toggled argument value.
+ (TabbedPaneLayout.normalizeTabRuns): Fixed indentation to stay under
+ 80 column limit, corrected the starting value for the bounds fixing
+ phase.
+ (TabbedPaneLayout.preferredTabAreaWidth): Fixed indentation.
+ (TabbedPaneLayout.rotateTabInRuns): Corrected comparison value for
+ selectedRun, set start index for loop to 0.
+ (TabbedPaneScrollLayout.preferredLayoutSize): Toggled argument value.
+ (TabbedPaneScrollLayout.calculateTabRects): Rewritten.
+ (TabbedPaneScrollLayout.layoutContainer): Added scrolling button
+ alignment and visibility handling.
+ (TabSelectionHandler.stateChanged): Do revalidation only in wrap tab
+ layout mode.
+ (ScrollingPanel.ScrollingPanelUI.paint): Rewritten.
+ (currentScrollOffset): New field.
+ (tabRuns): Rewritten documentation.
+ (selectedColor): New field.
+ (tempTextRect): New field.
+ (tempIconRect): New field.
+ (scrollTab): New method.
+ (updateButtons): New method.
+ (updateViewPosition): New method.
+ (createLayoutManager): Reordered method calls, predefine new fields,
+ register proper listeners.
+ (uninstallComponents): Implemented.
+ (installDefaults): Corrected property names, fixed indentation,.
+ (uninstallDefaults): Set new fields to null.
+ (uninstallListeners): Remove listeners from components neccessary for
+ scrolling tab layout.
+ (installKeyboardActions): Implemented.
+ (uninstallKeyboardActions): Implemented.
+ (paint): Paint tab area background.
+ (paintTabArea): Fixed indentation, removed usage of local Rectangle
+ objects.
+ (getTabLabelShiftX): Rewritten.
+ (getTabLabelShiftY): Rewritten.
+ (paintFocusIndicator): Reindented.
+ (paintTabBorder): Rewritten.
+ (paintTabBackground): Corrected color usage, rewritten background
+ rectangle painting.
+ (paintContentBorderTopEdge): Rewritten.
+ (paintContentBorderBottomEdge): Rewritten.
+ (paintContentBorderLeftEdge): Rewritten.
+ (paintContentBorderRightEdge): Rewritten.
+ (tabForCoordinate): Return selected index when no tab could be
+ found, removed FIXME note.
+ (getRunForTab): Changed return value for first if-statement.
+ (navigateSelectedTab): Fixed last argument for both
+ getTabRunOffset() calls.
+ (selectedNextTabInRun): Added scrolling code.
+ (selectedPreviousTabInRun): Added scrolling code.
+ (selectedNextTab): Added scrolling code.
+ (selectedPreviousTab): Added scrolling code.
+ (selectAdjacentRunTab): Added scrolling code.
+ (getTextViewForTab): Added FIXME note.
+ (calculateTabHeight): Changed FIXME note.
+ (getTabRunOffset): Fixed indentation.
+ (getNextTabIndexInRun): Corrected return value.
+ (rotateInsets): Make TOP case the default in switch-statement.
+ (getActionMap): New method.
+ (createActionMap): New method.
+ * javax/swing/plaf/metal/MetalTabbedPaneUI.java:
+ (createLayoutManager): Rewritten.
+ (paintLeftTabBorder): Do not paint left line when previous tab
+ is selected but current tab is the first in its run, do not paint
+ left line when current tab is selected and is first in its run.
+ (paintRightTabBorder): Added missing setColor() call, fixed color
+ usage, do not paint right line if previous tab is selected but
+ current tab is the first in its run.
+ (paintBottomTabBorder): Do not paint left line if tab is selected
+ and is the first tab in the last run.
+ (paintFocusIndicator): New method.
+ (getLabelShiftX): New method.
+ (getLabelShiftY): New method.
+
2006-07-27 Andreas Tobler <a.tobler@schweiz.ch>
* native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
diff --git a/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/javax/swing/plaf/basic/BasicTabbedPaneUI.java
index 17fa6075b..11f25167d 100644
--- a/javax/swing/plaf/basic/BasicTabbedPaneUI.java
+++ b/javax/swing/plaf/basic/BasicTabbedPaneUI.java
@@ -1,5 +1,5 @@
/* BasicTabbedPaneUI.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,8 +38,6 @@ exception statement from your version. */
package javax.swing.plaf.basic;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
@@ -51,6 +49,7 @@ import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
@@ -60,7 +59,10 @@ import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+import javax.swing.AbstractAction;
+import javax.swing.ActionMap;
import javax.swing.Icon;
+import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
@@ -72,6 +74,7 @@ import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
+import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.PanelUI;
import javax.swing.plaf.TabbedPaneUI;
@@ -80,11 +83,127 @@ import javax.swing.text.View;
/**
* This is the Basic Look and Feel's UI delegate for JTabbedPane.
+ *
+ * @author Lillian Angel (langel@redhat.com)
+ * @author Kim Ho (kho@redhat.com)
+ * @author Roman Kennke (kennke@aicas.com)
+ * @author Robert Schuster (robertschuster@fsfe.org)
*/
public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
+
+ static class NavigateAction extends AbstractAction
+ {
+ int direction;
+
+ NavigateAction(String name, int dir)
+ {
+ super(name);
+ direction = dir;
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTabbedPane tp = (JTabbedPane) event.getSource();
+ BasicTabbedPaneUI ui = (BasicTabbedPaneUI) tp.getUI();
+
+ ui.navigateSelectedTab(direction);
+ }
+
+ }
+
+ static class NavigatePageDownAction extends AbstractAction
+ {
+
+ public NavigatePageDownAction()
+ {
+ super("navigatePageDown");
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTabbedPane tp = (JTabbedPane) event.getSource();
+ BasicTabbedPaneUI ui = (BasicTabbedPaneUI) tp.getUI();
+
+ int i = tp.getSelectedIndex();
+
+ if (i < 0)
+ i = 0;
+
+ ui.selectNextTabInRun(i);
+ }
+
+ }
+
+ static class NavigatePageUpAction extends AbstractAction
+ {
+
+ public NavigatePageUpAction()
+ {
+ super("navigatePageUp");
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTabbedPane tp = (JTabbedPane) event.getSource();
+ BasicTabbedPaneUI ui = (BasicTabbedPaneUI) tp.getUI();
+
+ int i = tp.getSelectedIndex();
+
+ if (i < 0)
+ i = 0;
+
+ ui.selectPreviousTabInRun(i);
+
+ }
+ }
+
+ static class RequestFocusAction extends AbstractAction
+ {
+
+ public RequestFocusAction()
+ {
+ super("requestFocus");
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ ((JTabbedPane) event.getSource()).requestFocus();
+ }
+
+ }
+
+ static class RequestFocusForVisibleComponentAction extends AbstractAction
+ {
+
+ public RequestFocusForVisibleComponentAction()
+ {
+ super("requestFocusForVisibleComponent");
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTabbedPane tp = (JTabbedPane) event.getSource();
+
+ // FIXME: This should select a suitable component within
+ // the tab content. However I dont know whether we have
+ // to search for this component or wether the called is
+ // supposed to do that.
+ tp.getSelectedComponent().requestFocus();
+ }
+
+ }
+
/**
- * A helper class that handles focus.
+ * A helper class that handles focus.
+ * <p>The purpose of this class is to implement a more flexible focus
+ * handling for the tabbed pane, which is used to determine whether the
+ * focus indicator should be painted or not. When in scrolling layout
+ * mode the area containing the tabs is a scrollpane, so simply testing
+ * whether the tabbed pane has the focus does not work.</p>
+ * <p>The <code>FocusHandler</code> is installed on the scrollpane and
+ * the tabbed pane and sets the variable <code>hasFocus</code> to
+ * <code>false</code> only when both components do not hold the focus.</p>
*
* @specnote Apparently this class was intended to be protected,
* but was made public by a compiler bug and is now
@@ -98,9 +217,12 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
* @param e The FocusEvent.
*/
public void focusGained(FocusEvent e)
- throws NotImplementedException
{
- // FIXME: Implement.
+ Object source = e.getSource();
+ if (source == panel )
+ tabPane.requestFocus();
+ else if (source == tabPane)
+ tabPane.repaint();
}
/**
@@ -109,9 +231,11 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
* @param e The FocusEvent.
*/
public void focusLost(FocusEvent e)
- throws NotImplementedException
{
- // FIXME: Implement.
+ if (e.getOppositeComponent() == tabPane.getSelectedComponent())
+ tabPane.requestFocus();
+ else if (e.getSource() == tabPane)
+ tabPane.repaint();
}
}
@@ -126,6 +250,11 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
public class MouseHandler extends MouseAdapter
{
+ public void mouseReleased(MouseEvent e)
+ {
+ // Nothing to do here.
+ }
+
/**
* This method is called when the mouse is pressed. The index cannot
* change to a tab that is not enabled.
@@ -134,14 +263,84 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
public void mousePressed(MouseEvent e)
{
- if (tabPane.isEnabled())
+ Object s = e.getSource();
+ int placement = tabPane.getTabPlacement();
+
+ if (s == incrButton)
{
- int index = tabForCoordinate(tabPane, e.getX(), e.getY());
- if (index >= 0 && tabPane.isEnabledAt(index))
+ if(!incrButton.isEnabled())
+ return;
+
+ currentScrollLocation++;
+
+ switch (placement)
{
- tabPane.setSelectedIndex(index);
+ case JTabbedPane.TOP:
+ case JTabbedPane.BOTTOM:
+ currentScrollOffset = getTabAreaInsets(placement).left;
+ for (int i = 0; i < currentScrollLocation; i++)
+ currentScrollOffset += rects[i].width;
+ break;
+ default:
+ currentScrollOffset = getTabAreaInsets(placement).top;
+ for (int i = 0; i < currentScrollLocation; i++)
+ currentScrollOffset += rects[i].height;
+ break;
}
+
+ updateViewPosition();
+ updateButtons();
+
+ tabPane.repaint();
+ }
+ else if (s == decrButton)
+ {
+ if(!decrButton.isEnabled())
+ return;
+
+ // The scroll location may be zero but the offset
+ // greater than zero because of an adjustement to
+ // make a partially visible tab completely visible.
+ if (currentScrollLocation > 0)
+ currentScrollLocation--;
+
+ // Set the offset back to 0 and recompute it.
+ currentScrollOffset = 0;
+
+ switch (placement)
+ {
+ case JTabbedPane.TOP:
+ case JTabbedPane.BOTTOM:
+ // Take the tab area inset into account.
+ if (currentScrollLocation > 0)
+ currentScrollOffset = getTabAreaInsets(placement).left;
+ // Recompute scroll offset.
+ for (int i = 0; i < currentScrollLocation; i++)
+ currentScrollOffset += rects[i].width;
+ break;
+ default:
+ // Take the tab area inset into account.
+ if (currentScrollLocation > 0)
+ currentScrollOffset = getTabAreaInsets(placement).top;
+
+ for (int i = 0; i < currentScrollLocation; i++)
+ currentScrollOffset += rects[i].height;
+ }
+
+ updateViewPosition();
+ updateButtons();
+
+ tabPane.repaint();
+ } else if (tabPane.isEnabled())
+ {
+ int index = tabForCoordinate(tabPane, e.getX(), e.getY());
+ if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT
+ && s == panel)
+ scrollTab(index, placement);
+
+ tabPane.setSelectedIndex(index);
}
+
}
/**
@@ -199,6 +398,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
if (e.getPropertyName().equals("tabLayoutPolicy"))
{
+ currentScrollLocation = currentScrollOffset = 0;
+
layoutManager = createLayoutManager();
tabPane.setLayout(layoutManager);
@@ -267,7 +468,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
// Find out the minimum/preferred size to display the largest child
// of the tabbed pane.
- for (int i = 0; i < tabPane.getTabCount(); i++)
+ int count = tabPane.getTabCount();
+ for (int i = 0; i < count; i++)
{
c = tabPane.getComponentAt(i);
if (c == null)
@@ -284,21 +486,19 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
if (tabPlacement == SwingConstants.TOP
|| tabPlacement == SwingConstants.BOTTOM)
{
- int min = calculateMaxTabWidth(tabPlacement);
- width = Math.max(min, width);
- int tabAreaHeight = preferredTabAreaHeight(tabPlacement,
- width - tabAreaInsets.left
- - tabAreaInsets.right);
- height += tabAreaHeight;
+ width = Math.max(calculateMaxTabWidth(tabPlacement), width);
+
+ height += preferredTabAreaHeight(tabPlacement,
+ width - tabAreaInsets.left
+ - tabAreaInsets.right);
}
else
{
- int min = calculateMaxTabHeight(tabPlacement);
- height = Math.max(min, height);
- int tabAreaWidth = preferredTabAreaWidth(tabPlacement,
- height - tabAreaInsets.top
- - tabAreaInsets.bottom);
- width += tabAreaWidth;
+ height = Math.max(calculateMaxTabHeight(tabPlacement), height);
+
+ width += preferredTabAreaWidth(tabPlacement,
+ height - tabAreaInsets.top
+ - tabAreaInsets.bottom);
}
Insets tabPaneInsets = tabPane.getInsets();
@@ -308,7 +508,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
// if tab placement is LEFT OR RIGHT, they share width.
// if tab placement is TOP OR BOTTOM, they share height
- // PRE STEP: finds the default sizes for the labels as well as their locations.
+ // PRE STEP: finds the default sizes for the labels as well as their
+ // locations.
// AND where they will be placed within the run system.
// 1. calls normalizeTab Runs.
// 2. calls rotate tab runs.
@@ -347,7 +548,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
break;
case RIGHT:
maxTabWidth = calculateMaxTabWidth(tabPlacement);
- x = size.width - (insets.right + tabAreaInsets.right) - maxTabWidth;
+ x = size.width - (insets.right + tabAreaInsets.right)
+ - maxTabWidth - 1;
y = insets.top + tabAreaInsets.top;
breakAt = size.height - (insets.bottom + tabAreaInsets.bottom);
break;
@@ -355,7 +557,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
maxTabHeight = calculateMaxTabHeight(tabPlacement);
x = insets.left + tabAreaInsets.left;
y = size.height - (insets.bottom + tabAreaInsets.bottom)
- - maxTabHeight;
+ - maxTabHeight - 1;
breakAt = size.width - (insets.right + tabAreaInsets.right);
break;
case TOP:
@@ -374,6 +576,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
runCount = 0;
selectedRun = -1;
int selectedIndex = tabPane.getSelectedIndex();
+ if (selectedIndex < 0)
+ selectedIndex = 0;
Rectangle rect;
@@ -411,7 +615,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
rect.height = maxTabHeight;
if (i == selectedIndex)
selectedRun = runCount - 1;
-
}
}
else
@@ -456,9 +659,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
int start;
if (tabPlacement == SwingConstants.TOP
|| tabPlacement == SwingConstants.BOTTOM)
- start = y;
- else
start = x;
+ else
+ start = y;
normalizeTabRuns(tabPlacement, tabCount, start, breakAt);
selectedRun = getRunForTab(tabCount, selectedIndex);
if (shouldRotateTabRuns(tabPlacement))
@@ -466,7 +669,11 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
rotateTabRuns(tabPlacement, selectedRun);
}
}
-
+
+ // Suppress padding if we have only one tab run.
+ if (runCount == 1)
+ return;
+
// Pad the runs.
int tabRunOverlay = getTabRunOverlay(tabPlacement);
for (int i = runCount - 1; i >= 0; --i)
@@ -606,16 +813,18 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
public Dimension minimumLayoutSize(Container parent)
{
- return calculateSize(false);
+ return calculateSize(true);
}
- // If there is more free space in an adjacent run AND the tab in the run can fit in the
- // adjacent run, move it. This method is not perfect, it is merely an approximation.
+ // If there is more free space in an adjacent run AND the tab
+ // in the run can fit in the adjacent run, move it. This method
+ // is not perfect, it is merely an approximation.
// If you play around with Sun's JTabbedPane, you'll see that
// it does do some pretty strange things with regards to not moving tabs
// that should be moved.
// start = the x position where the tabs will begin
- // max = the maximum position of where the tabs can go to (tabAreaInsets.left + the width of the tab area)
+ // max = the maximum position of where the tabs can go to
+ // (tabAreaInsets.left + the width of the tab area)
/**
* This method tries to "even out" the number of tabs in each run based on
@@ -633,18 +842,20 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
if (tabPlacement == SwingUtilities.TOP
|| tabPlacement == SwingUtilities.BOTTOM)
{
- // We should only do this for runCount - 1, cause we can only shift that many times between
- // runs.
+ // We should only do this for runCount - 1, cause we can
+ // only shift that many times between runs.
for (int i = 1; i < runCount; i++)
{
Rectangle currRun = rects[lastTabInRun(tabCount, i)];
- Rectangle nextRun = rects[lastTabInRun(tabCount, getNextTabRun(i))];
+ Rectangle nextRun = rects[lastTabInRun(tabCount,
+ getNextTabRun(i))];
int spaceInCurr = currRun.x + currRun.width;
int spaceInNext = nextRun.x + nextRun.width;
int diffNow = spaceInCurr - spaceInNext;
int diffLater = (spaceInCurr - currRun.width)
- (spaceInNext + currRun.width);
+
while (Math.abs(diffLater) < Math.abs(diffNow)
&& spaceInNext + currRun.width < max)
{
@@ -656,11 +867,12 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
diffLater = (spaceInCurr - currRun.width)
- (spaceInNext + currRun.width);
}
-
- // Fix the bounds.
- int first = lastTabInRun(tabCount, i) + 1;
- int last = lastTabInRun(tabCount, getNextTabRun(i));
- int currX = tabAreaInsets.left;
+
+ // Fixes the bounds of all tabs in the current
+ // run.
+ int first = tabRuns[i];
+ int last = lastTabInRun(tabCount, i);
+ int currX = start;
for (int j = first; j <= last; j++)
{
rects[j].x = currX;
@@ -673,7 +885,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
for (int i = 1; i < runCount; i++)
{
Rectangle currRun = rects[lastTabInRun(tabCount, i)];
- Rectangle nextRun = rects[lastTabInRun(tabCount, getNextTabRun(i))];
+ Rectangle nextRun = rects[lastTabInRun(tabCount,
+ getNextTabRun(i))];
int spaceInCurr = currRun.y + currRun.height;
int spaceInNext = nextRun.y + nextRun.height;
@@ -692,9 +905,10 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
- (spaceInNext + currRun.height);
}
- int first = lastTabInRun(tabCount, i) + 1;
- int last = lastTabInRun(tabCount, getNextTabRun(i));
- int currY = tabAreaInsets.top;
+ // Fixes the bounds of tabs in the current run.
+ int first = tabRuns[i];
+ int last = lastTabInRun(tabCount, i);
+ int currY = start;
for (int j = first; j <= last; j++)
{
rects[j].y = currY;
@@ -720,7 +934,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
rects[selectedIndex].height += insets.top + insets.bottom;
}
- // If the tabs on the run don't fill the width of the window, make it fit now.
+ // If the tabs on the run don't fill the width of the window, make it
+ // fit now.
// start = starting index of the run
// end = last index of the run
// max = tabAreaInsets.left + width (or equivalent)
@@ -744,7 +959,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
int runWidth = rects[end].x + rects[end].width;
int spaceRemaining = max - runWidth;
int numTabs = end - start + 1;
-
+
// now divvy up the space.
int spaceAllocated = spaceRemaining / numTabs;
int currX = rects[start].x;
@@ -752,11 +967,13 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
rects[i].x = currX;
rects[i].width += spaceAllocated;
+
currX += rects[i].width;
// This is used because since the spaceAllocated
// variable is an int, it rounds down. Sometimes,
// we don't fill an entire row, so we make it do
// so now.
+
if (i == end && rects[i].x + rects[i].width != max)
rects[i].width = max - rects[i].x;
}
@@ -821,7 +1038,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
// The reason why we can't use runCount:
// This method is only called to calculate the size request
- // for the tabbedPane. However, this size request is dependent on
+ // for the tabbedPane. However, this size request is dependent on
// our desired width. We need to find out what the height would
// be IF we got our desired width.
for (int i = 0; i < tabPane.getTabCount(); i++)
@@ -884,7 +1101,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
runs++;
int maxTabWidth = calculateMaxTabWidth(tabPlacement);
- int tabAreaWidth = calculateTabAreaWidth(tabPlacement, runs, maxTabWidth);
+ int tabAreaWidth = calculateTabAreaWidth(tabPlacement, runs,
+ maxTabWidth);
return tabAreaWidth;
}
@@ -898,11 +1116,11 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
protected void rotateTabRuns(int tabPlacement, int selectedRun)
{
- if (runCount == 1 || selectedRun == 1 || selectedRun == -1)
+ if (runCount == 1 || selectedRun == 0 || selectedRun == -1)
return;
int[] newTabRuns = new int[tabRuns.length];
int currentRun = selectedRun;
- int i = 1;
+ int i = 0;
do
{
newTabRuns[i] = tabRuns[currentRun];
@@ -910,8 +1128,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
i++;
}
while (i < runCount);
- if (runCount > 1)
- newTabRuns[0] = tabRuns[currentRun];
tabRuns = newTabRuns;
BasicTabbedPaneUI.this.selectedRun = 1;
@@ -944,7 +1160,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
public Dimension preferredLayoutSize(Container parent)
{
- return super.calculateSize(true);
+ return super.calculateSize(false);
}
/**
@@ -1018,29 +1234,27 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
SwingUtilities.calculateInnerArea(tabPane, calcRect);
Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
Insets insets = tabPane.getInsets();
- int runs = 1;
- int start = 0;
- int top = 0;
if (tabPlacement == SwingConstants.TOP
|| tabPlacement == SwingConstants.BOTTOM)
{
int maxHeight = calculateMaxTabHeight(tabPlacement);
calcRect.width -= tabAreaInsets.left + tabAreaInsets.right;
- start = tabAreaInsets.left + insets.left;
int width = 0;
- int runWidth = start;
- top = insets.top + tabAreaInsets.top;
+ int runWidth = tabAreaInsets.left + insets.left;
+ int top = insets.top + tabAreaInsets.top;
for (int i = 0; i < tabCount; i++)
{
width = calculateTabWidth(tabPlacement, i, fm);
-
- rects[i] = new Rectangle(runWidth, top, width, maxHeight);
+
+ // The proper instances should exists because
+ // assureRectsCreated() was being run already.
+ rects[i].setBounds(runWidth, top, width, maxHeight);
+
runWidth += width;
}
tabAreaRect.width = tabPane.getWidth() - insets.left - insets.right;
- tabAreaRect.height = runs * maxTabHeight
- - (runs - 1) * tabRunOverlay
- + tabAreaInsets.top + tabAreaInsets.bottom;
+ tabAreaRect.height = maxTabHeight + tabAreaInsets.top
+ + tabAreaInsets.bottom;
contentRect.width = tabAreaRect.width;
contentRect.height = tabPane.getHeight() - insets.top
- insets.bottom - tabAreaRect.height;
@@ -1063,23 +1277,25 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
calcRect.height -= tabAreaInsets.top + tabAreaInsets.bottom;
int height = 0;
- start = tabAreaInsets.top + insets.top;
- int runHeight = start;
+ int runHeight = tabAreaInsets.top + insets.top;;
int fontHeight = fm.getHeight();
- top = insets.left + tabAreaInsets.left;
+ int left = insets.left + tabAreaInsets.left;
for (int i = 0; i < tabCount; i++)
{
height = calculateTabHeight(tabPlacement, i, fontHeight);
- rects[i] = new Rectangle(top, runHeight, maxWidth, height);
+
+ // The proper instances should exists because
+ // assureRectsCreated() was being run already.
+ rects[i].setBounds(left, runHeight, maxWidth, height);
runHeight += height;
}
- tabAreaRect.width = runs * maxTabWidth - (runs - 1) * tabRunOverlay
- + tabAreaInsets.left + tabAreaInsets.right;
+ tabAreaRect.width = maxTabWidth + tabAreaInsets.left
+ + tabAreaInsets.right;
tabAreaRect.height = tabPane.getHeight() - insets.top
- - insets.bottom;
+ - insets.bottom;
tabAreaRect.y = insets.top;
contentRect.width = tabPane.getWidth() - insets.left - insets.right
- - tabAreaRect.width;
+ - tabAreaRect.width;
contentRect.height = tabAreaRect.height;
contentRect.y = insets.top;
if (tabPlacement == SwingConstants.LEFT)
@@ -1093,11 +1309,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
tabAreaRect.x = contentRect.x + contentRect.width;
}
}
- runCount = runs;
- if (runCount > tabRuns.length)
- expandTabRunsArray();
-
- padSelectedTab(tabPlacement, tabPane.getSelectedIndex());
+
+ // Unlike the behavior in the WRAP_TAB_LAYOUT the selected
+ // tab is not padded specially.
}
/**
@@ -1115,8 +1329,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
if (tabCount == 0)
return;
int tabPlacement = tabPane.getTabPlacement();
- incrButton.setVisible(false);
- decrButton.setVisible(false);
+
if (tabPlacement == SwingConstants.TOP
|| tabPlacement == SwingConstants.BOTTOM)
{
@@ -1126,18 +1339,49 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
Dimension incrDims = incrButton.getPreferredSize();
Dimension decrDims = decrButton.getPreferredSize();
- decrButton.setBounds(tabAreaRect.x + tabAreaRect.width
- - incrDims.width - decrDims.width,
- tabAreaRect.y, decrDims.width,
- tabAreaRect.height);
- incrButton.setBounds(tabAreaRect.x + tabAreaRect.width
- - incrDims.width, tabAreaRect.y,
- decrDims.width, tabAreaRect.height);
-
+ if (tabPlacement == SwingConstants.BOTTOM)
+ {
+ // Align scroll buttons with the bottom border of the tabbed
+ // pane's content area.
+ decrButton.setBounds(tabAreaRect.x + tabAreaRect.width
+ - incrDims.width - decrDims.width,
+ tabAreaRect.y, decrDims.width,
+ decrDims.height);
+ incrButton.setBounds(tabAreaRect.x + tabAreaRect.width
+ - incrDims.width, tabAreaRect.y,
+ incrDims.width, incrDims.height);
+ }
+ else
+ {
+ // Align scroll buttons with the top border of the tabbed
+ // pane's content area.
+ decrButton.setBounds(tabAreaRect.x + tabAreaRect.width
+ - incrDims.width - decrDims.width,
+ tabAreaRect.y + tabAreaRect.height
+ - decrDims.height, decrDims.width,
+ decrDims.height);
+ incrButton.setBounds(tabAreaRect.x + tabAreaRect.width
+ - incrDims.width,
+ tabAreaRect.y + tabAreaRect.height
+ - incrDims.height,
+ incrDims.width, incrDims.height);
+ }
+
tabAreaRect.width -= decrDims.width + incrDims.width;
+
+ updateButtons();
+
incrButton.setVisible(true);
decrButton.setVisible(true);
}
+ else
+ {
+ incrButton.setVisible(false);
+ decrButton.setVisible(false);
+
+ currentScrollOffset = 0;
+ currentScrollLocation = 0;
+ }
}
if (tabPlacement == SwingConstants.LEFT
@@ -1149,34 +1393,54 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
Dimension incrDims = incrButton.getPreferredSize();
Dimension decrDims = decrButton.getPreferredSize();
- decrButton.setBounds(tabAreaRect.x,
- tabAreaRect.y + tabAreaRect.height
- - incrDims.height - decrDims.height,
- tabAreaRect.width, decrDims.height);
- incrButton.setBounds(tabAreaRect.x,
- tabAreaRect.y + tabAreaRect.height
- - incrDims.height, tabAreaRect.width,
- incrDims.height);
+ if (tabPlacement == SwingConstants.RIGHT)
+ {
+ // Align scroll buttons with the right border of the tabbed
+ // pane's content area.
+ decrButton.setBounds(tabAreaRect.x,
+ tabAreaRect.y + tabAreaRect.height
+ - incrDims.height - decrDims.height,
+ decrDims.width, decrDims.height);
+ incrButton.setBounds(tabAreaRect.x,
+ tabAreaRect.y + tabAreaRect.height
+ - incrDims.height, incrDims.width,
+ incrDims.height);
+ }
+ else
+ {
+ // Align scroll buttons with the left border of the tabbed
+ // pane's content area.
+ decrButton.setBounds(tabAreaRect.x + tabAreaRect.width
+ - decrDims.width,
+ tabAreaRect.y + tabAreaRect.height
+ - incrDims.height - decrDims.height,
+ decrDims.width, decrDims.height);
+ incrButton.setBounds(tabAreaRect.x + tabAreaRect.width
+ - incrDims.width,
+ tabAreaRect.y + tabAreaRect.height
+ - incrDims.height, incrDims.width,
+ incrDims.height);
+ }
tabAreaRect.height -= decrDims.height + incrDims.height;
+
incrButton.setVisible(true);
decrButton.setVisible(true);
}
+ else
+ {
+ incrButton.setVisible(false);
+ decrButton.setVisible(false);
+
+ currentScrollOffset = 0;
+ currentScrollLocation = 0;
+ }
}
viewport.setBounds(tabAreaRect.x, tabAreaRect.y, tabAreaRect.width,
tabAreaRect.height);
- int tabC = tabPane.getTabCount() - 1;
- if (tabCount > 0)
- {
- int w = Math.max(rects[tabC].width + rects[tabC].x, tabAreaRect.width);
- int h = Math.max(rects[tabC].height, tabAreaRect.height);
- p = findPointForIndex(currentScrollLocation);
-
- // we want to cover that entire space so that borders that run under
- // the tab area don't show up when we move the viewport around.
- panel.setSize(w + p.x, h + p.y);
- }
- viewport.setViewPosition(p);
+
+ updateViewPosition();
+
viewport.repaint();
}
}
@@ -1200,7 +1464,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
selectedRun = getRunForTab(tabPane.getTabCount(),
tabPane.getSelectedIndex());
- tabPane.revalidate();
+
+ if (tabPane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT)
+ tabPane.revalidate();
tabPane.repaint();
}
}
@@ -1226,7 +1492,17 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
public void paint(Graphics g, JComponent c)
{
- paintTabArea(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex());
+ int placement = tabPane.getTabPlacement();
+ g.setColor(highlight);
+ if (placement == SwingUtilities.TOP
+ || placement == SwingUtilities.BOTTOM)
+ g.fillRect(currentScrollOffset, 0,
+ tabAreaRect.width, tabAreaRect.height);
+ else
+ g.fillRect(0, currentScrollOffset,
+ tabAreaRect.width, tabAreaRect.height);
+
+ paintTabArea(g, placement, tabPane.getSelectedIndex());
}
}
@@ -1287,6 +1563,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
/** The starting visible tab in the run in SCROLL_TAB_MODE.
* This is package-private to avoid an accessor method. */
transient int currentScrollLocation;
+
+ transient int currentScrollOffset;
/** A reusable rectangle. */
protected Rectangle calcRect;
@@ -1342,16 +1620,11 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
/** The gap between text and label */
protected int textIconGap;
- // Keeps track of tab runs.
- // The organization of this array is as follows (lots of experimentation to
- // figure this out)
- // index 0 = furthest away from the component area (aka outer run)
- // index 1 = closest to component area (aka selected run)
- // index > 1 = listed in order leading from selected run to outer run.
- // each int in the array is the tab index + 1 (counting starts at 1)
- // for the last tab in the run. (same as the rects array)
-
- /** This array keeps track of which tabs are in which run. See above. */
+ /** This array keeps track of which tabs are in which run.
+ * <p>The value at index i denotes the index of the first tab in run i.</p>
+ * <p>If the value for any index (i > 0) is 0 then (i - 1) is the last
+ * run.</p>
+ */
protected int[] tabRuns;
/**
@@ -1430,7 +1703,13 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
* The currently visible component.
*/
private Component visibleComponent;
-
+
+ private Color selectedColor;
+
+ private Rectangle tempTextRect = new Rectangle();
+
+ private Rectangle tempIconRect = new Rectangle();
+
/**
* Creates a new BasicTabbedPaneUI object.
*/
@@ -1519,8 +1798,115 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
Point p = new Point(w, h);
return p;
}
+
+ /** TabbedPanes in scrolling mode should use this method to
+ * scroll properly to the tab given by the index argument.
+ *
+ * @param index The tab to scroll to.
+ * @param placement The tab's placement.
+ */
+ final void scrollTab(int index, int placement)
+ {
+ int diff;
+ if (index >= 0 && tabPane.isEnabledAt(index))
+ {
+ // If the user clicked on the last tab and that one was
+ // only partially visible shift the scroll offset to make
+ // it completely visible.
+ switch (placement)
+ {
+ case JTabbedPane.TOP:
+ case JTabbedPane.BOTTOM:
+ if ((diff = rects[index].x
+ + rects[index].width
+ - decrButton.getX() - currentScrollOffset) > 0)
+ currentScrollOffset += diff;
+ else if ((diff = rects[index].x - currentScrollOffset) < 0)
+ {
+ if (index == 0)
+ currentScrollOffset = 0;
+ else
+ currentScrollOffset += diff;
+ }
+
+ currentScrollLocation = tabForCoordinate(tabPane,
+ currentScrollOffset,
+ rects[index].y);
+ break;
+ default:
+ if ((diff = rects[index].y + rects[index].height
+ - decrButton.getY() - currentScrollOffset) > 0)
+ currentScrollOffset += diff;
+ else if ((diff = rects[index].y - currentScrollOffset) < 0)
+ {
+ if (index == 0)
+ currentScrollOffset = 0;
+ else
+ currentScrollOffset += diff;
+ }
+
+ currentScrollLocation = tabForCoordinate(tabPane,
+ rects[index].x,
+ currentScrollOffset);
+ }
+
+ updateViewPosition();
+ updateButtons();
+ }
+ }
+
+ /** Sets the enabled state of the increase and decrease button
+ * according to the current scrolling offset and tab pane width
+ * (or height in TOP/BOTTOM placement).
+ */
+ final void updateButtons()
+ {
+ int tc = tabPane.getTabCount();
+
+ // The increase button should be enabled as long as the
+ // right/bottom border of the last tab is under the left/top
+ // border of the decrease button.
+ switch (tabPane.getTabPlacement())
+ {
+ case JTabbedPane.BOTTOM:
+ case JTabbedPane.TOP:
+ incrButton.setEnabled(currentScrollLocation + 1 < tc
+ && rects[tc-1].x + rects[tc-1].width
+ - currentScrollOffset > decrButton.getX());
+ break;
+ default:
+ incrButton.setEnabled(currentScrollLocation + 1 < tc
+ && rects[tc-1].y + rects[tc-1].height
+ - currentScrollOffset > decrButton.getY());
+ }
+
+ // The decrease button is enabled when the tab pane is scrolled in any way.
+ decrButton.setEnabled(currentScrollOffset > 0);
+
+ }
/**
+ * Updates the position of the scrolling viewport's view
+ * according to the current scroll offset.
+ */
+ final void updateViewPosition()
+ {
+ Point p = viewport.getViewPosition();
+
+ switch (tabPane.getTabPlacement())
+ {
+ case JTabbedPane.LEFT:
+ case JTabbedPane.RIGHT:
+ p.y = currentScrollOffset;
+ break;
+ default:
+ p.x = currentScrollOffset;
+ }
+
+ viewport.setViewPosition(p);
+ }
+
+ /**
* This method creates a new BasicTabbedPaneUI.
*
* @param c The JComponent to create a UI for.
@@ -1585,22 +1971,30 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
return new TabbedPaneLayout();
else
{
+ runCount = 1;
+ tabRuns[0] = 0;
+
incrButton = createIncreaseButton();
+ incrButton.addMouseListener(mouseListener);
+
decrButton = createDecreaseButton();
- viewport = new ScrollingViewport();
- viewport.setLayout(null);
+ decrButton.addMouseListener(mouseListener);
+ decrButton.setEnabled(false);
+
panel = new ScrollingPanel();
+ panel.setSize(Integer.MAX_VALUE, Integer.MAX_VALUE);
+ panel.addMouseListener(mouseListener);
+ panel.addFocusListener(focusListener);
+
+ viewport = new ScrollingViewport();
+ viewport.setBackground(Color.LIGHT_GRAY);
viewport.setView(panel);
+ viewport.setLayout(null);
+
tabPane.add(incrButton);
tabPane.add(decrButton);
tabPane.add(viewport);
- currentScrollLocation = 0;
- decrButton.setEnabled(false);
- panel.addMouseListener(mouseListener);
- incrButton.addMouseListener(mouseListener);
- decrButton.addMouseListener(mouseListener);
- viewport.setBackground(Color.LIGHT_GRAY);
-
+
return new TabbedPaneScrollLayout();
}
}
@@ -1618,7 +2012,14 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
protected void uninstallComponents()
{
- // Nothing to be done.
+ if (incrButton != null)
+ tabPane.remove(incrButton);
+
+ if (decrButton != null)
+ tabPane.remove(decrButton);
+
+ if (viewport != null)
+ tabPane.remove(viewport);
}
/**
@@ -1631,8 +2032,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
"TabbedPane.font");
tabPane.setOpaque(false);
- highlight = UIManager.getColor("TabbedPane.highlight");
- lightHighlight = UIManager.getColor("TabbedPane.lightHighlight");
+ lightHighlight = UIManager.getColor("TabbedPane.highlight");
+ highlight = UIManager.getColor("TabbedPane.light");
shadow = UIManager.getColor("TabbedPane.shadow");
darkShadow = UIManager.getColor("TabbedPane.darkShadow");
@@ -1643,10 +2044,18 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
tabRunOverlay = UIManager.getInt("TabbedPane.tabRunOverlay");
tabInsets = UIManager.getInsets("TabbedPane.tabInsets");
- selectedTabPadInsets = UIManager.getInsets("TabbedPane.tabbedPaneTabPadInsets");
+ selectedTabPadInsets
+ = UIManager.getInsets("TabbedPane.selectedTabPadInsets");
tabAreaInsets = UIManager.getInsets("TabbedPane.tabAreaInsets");
- contentBorderInsets = UIManager.getInsets("TabbedPane.tabbedPaneContentBorderInsets");
+ contentBorderInsets
+ = UIManager.getInsets("TabbedPane.contentBorderInsets");
tabsOpaque = UIManager.getBoolean("TabbedPane.tabsOpaque");
+
+ // Although 'TabbedPane.contentAreaColor' is not defined in the defaults
+ // of BasicLookAndFeel it is used by this class.
+ selectedColor = UIManager.getColor("TabbedPane.contentAreaColor");
+ if (selectedColor == null)
+ selectedColor = UIManager.getColor("control");
calcRect = new Rectangle();
tabRuns = new int[10];
@@ -1663,6 +2072,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
tabAreaRect = null;
contentRect = null;
tabRuns = null;
+
+ tempIconRect = null;
+ tempTextRect = null;
contentBorderInsets = null;
tabAreaInsets = null;
@@ -1674,11 +2086,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
shadow = null;
lightHighlight = null;
highlight = null;
-
- // Install UI colors and fonts.
- LookAndFeel.installColorsAndFont(tabPane, "TabbedPane.background",
- "TabbedPane.foreground",
- "TabbedPane.font");
+
+ selectedColor = null;
}
/**
@@ -1706,6 +2115,18 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
tabPane.removePropertyChangeListener(propertyChangeListener);
tabPane.removeChangeListener(tabChangeListener);
tabPane.removeMouseListener(mouseListener);
+
+ if (incrButton != null)
+ incrButton.removeMouseListener(mouseListener);
+
+ if (decrButton != null)
+ decrButton.removeMouseListener(mouseListener);
+
+ if (panel != null)
+ {
+ panel.removeMouseListener(mouseListener);
+ panel.removeFocusListener(focusListener);
+ }
focusListener = null;
propertyChangeListener = null;
@@ -1757,18 +2178,31 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
* This method installs keyboard actions for the JTabbedPane.
*/
protected void installKeyboardActions()
- throws NotImplementedException
{
- // FIXME: Implement.
+ InputMap keyMap = (InputMap) UIManager.get("TabbedPane.focusInputMap");
+ SwingUtilities.replaceUIInputMap(tabPane, JComponent.WHEN_FOCUSED, keyMap);
+
+ keyMap = (InputMap) UIManager.get("TabbedPane.ancestorInputMap");
+ SwingUtilities
+ .replaceUIInputMap(tabPane,
+ JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
+ keyMap);
+
+ ActionMap map = getActionMap();
+ SwingUtilities.replaceUIActionMap(tabPane, map);
}
/**
* This method uninstalls keyboard actions for the JTabbedPane.
*/
protected void uninstallKeyboardActions()
- throws NotImplementedException
{
- // FIXME: Implement.
+ SwingUtilities.replaceUIActionMap(tabPane, null);
+ SwingUtilities.replaceUIInputMap(tabPane, JComponent.WHEN_FOCUSED, null);
+ SwingUtilities
+ .replaceUIInputMap(tabPane,
+ JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
+ null);
}
/**
@@ -1808,9 +2242,25 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
if (tabPane.getTabCount() == 0)
return;
+
+ int index = tabPane.getSelectedIndex();
+ if (index < 0)
+ index = 0;
+
+ int tabPlacement = tabPane.getTabPlacement();
+
+ // Paint the tab area only in WRAP_TAB_LAYOUT Mode from this method
+ // because it is done through the ScrollingViewport.paint() method
+ // for the SCROLL_TAB_LAYOUT mode.
if (tabPane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT)
- paintTabArea(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex());
- paintContentBorder(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex());
+ {
+ g.setColor(highlight);
+ g.fillRect(tabAreaRect.x, tabAreaRect.y,
+ tabAreaRect.width, tabAreaRect.height);
+ paintTabArea(g, tabPlacement, index);
+ }
+
+ paintContentBorder(g, tabPlacement, index);
}
/**
@@ -1823,14 +2273,12 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex)
{
- Rectangle ir = new Rectangle();
- Rectangle tr = new Rectangle();
-
- boolean isScroll = tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT;
-
// Please note: the ordering of the painting is important.
// we WANT to paint the outermost run first and then work our way in.
+
+ // The following drawing code works for both tab layouts.
int tabCount = tabPane.getTabCount();
+
for (int i = runCount - 1; i >= 0; --i)
{
int start = tabRuns[i];
@@ -1844,14 +2292,16 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
if (j != selectedIndex)
{
- paintTab(g, tabPlacement, rects, j, ir, tr);
+ paintTab(g, tabPlacement, rects, j,
+ tempIconRect, tempTextRect);
}
}
}
-
+
// Paint selected tab in front of every other tab.
if (selectedIndex >= 0)
- paintTab(g, tabPlacement, rects, selectedIndex, ir, tr);
+ paintTab(g, tabPlacement, rects, selectedIndex,
+ tempIconRect, tempTextRect);
}
/**
@@ -1891,8 +2341,10 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
// Paint the text.
paintText(g, tabPlacement, tabPane.getFont(), fm, tabIndex, title,
textRect, isSelected);
+
// Paint icon if necessary.
paintIcon(g, tabPlacement, tabIndex, icon, iconRect, isSelected);
+
// Paint focus indicator.
paintFocusIndicator(g, tabPlacement, rects, tabIndex, iconRect, textRect,
isSelected);
@@ -2032,8 +2484,17 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
protected int getTabLabelShiftX(int tabPlacement, int tabIndex,
boolean isSelected)
{
- // No reason to shift.
- return 0;
+ switch (tabPlacement)
+ {
+ default:
+ case SwingUtilities.TOP:
+ case SwingUtilities.BOTTOM:
+ return 1;
+ case SwingUtilities.LEFT:
+ return (isSelected) ? -1 : 1;
+ case SwingUtilities.RIGHT:
+ return (isSelected) ? 1 : -1;
+ }
}
/**
@@ -2049,8 +2510,17 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
protected int getTabLabelShiftY(int tabPlacement, int tabIndex,
boolean isSelected)
{
- // No reason to shift.
- return 0;
+ switch (tabPlacement)
+ {
+ default:
+ case SwingUtilities.TOP:
+ return (isSelected) ? -1 : 1;
+ case SwingUtilities.BOTTOM:
+ return (isSelected) ? 1 : -1;
+ case SwingUtilities.LEFT:
+ case SwingUtilities.RIGHT:
+ return 0;
+ }
}
/**
@@ -2080,32 +2550,33 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
g.setColor(focus);
switch (tabPlacement)
- {
- case LEFT:
- x = rect.x + 3;
- y = rect.y + 3;
- w = rect.width - 5;
- h = rect.height - 6;
- break;
- case RIGHT:
- x = rect.x + 2;
- y = rect.y + 3;
- w = rect.width - 6;
- h = rect.height - 5;
- break;
- case BOTTOM:
- x = rect.x + 3;
- y = rect.y + 2;
- w = rect.width - 6;
- h = rect.height - 5;
- break;
- case TOP:
- default:
- x = rect.x + 3;
- y = rect.y + 3;
- w = rect.width - 6;
- h = rect.height - 5;
- }
+ {
+ case LEFT:
+ x = rect.x + 3;
+ y = rect.y + 3;
+ w = rect.width - 5;
+ h = rect.height - 6;
+ break;
+ case RIGHT:
+ x = rect.x + 2;
+ y = rect.y + 3;
+ w = rect.width - 6;
+ h = rect.height - 5;
+ break;
+ case BOTTOM:
+ x = rect.x + 3;
+ y = rect.y + 2;
+ w = rect.width - 6;
+ h = rect.height - 5;
+ break;
+ case TOP:
+ default:
+ x = rect.x + 3;
+ y = rect.y + 3;
+ w = rect.width - 6;
+ h = rect.height - 5;
+ }
+
BasicGraphicsUtils.drawDashedRect(g, x, y, w, h);
}
}
@@ -2127,34 +2598,109 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
Color saved = g.getColor();
- if (! isSelected || tabPlacement != SwingConstants.TOP)
- {
+ switch (tabPlacement)
+ {
+ case SwingConstants.TOP:
g.setColor(shadow);
- g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1);
- g.setColor(darkShadow);
- g.drawLine(x, y + h, x + w, y + h);
- }
+ // Inner right line.
+ g.drawLine(x + w - 2, y + 2, x + w - 2, y + h);
- if (! isSelected || tabPlacement != SwingConstants.LEFT)
- {
g.setColor(darkShadow);
- g.drawLine(x + w, y, x + w, y + h);
+ // Outer right line.
+ g.drawLine(x + w - 1, y + 2, x + w - 1, y + h);
+
+ // Upper right corner.
+ g.drawLine(x + w - 2, y + 1, x + w - 1, y + 2);
+
+ g.setColor(lightHighlight);
+
+ // Left line.
+ g.drawLine(x, y + 3, x, y + h);
+
+ // Upper line.
+ g.drawLine(x + 3, y, x + w - 3, y);
+
+ // Upper left corner.
+ g.drawLine(x, y + 2, x + 2, y);
+
+ break;
+ case SwingConstants.LEFT:
+ g.setColor(lightHighlight);
+ // Top line.
+ g.drawLine(x + 3, y, x + w - 1, y);
+
+ // Top left border.
+ g.drawLine(x + 2, y, x, y + 2);
+
+ // Left line.
+ g.drawLine(x, y + 3, x, y + h - 4);
+
+ // Bottom left corner.
+ g.drawLine(x, y + h - 3, x + 1, y + h - 2);
+
+ g.setColor(darkShadow);
+ // Outer bottom line.
+ g.drawLine(x + 2, y + h - 1, x + w - 1, y + h - 1);
+
g.setColor(shadow);
- g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);
- }
+ // Inner bottom line.
+ g.drawLine(x + 2, y + h - 2, x + w - 1, y + h - 2);
+
+ break;
+ case SwingConstants.BOTTOM:
+ g.setColor(shadow);
+ // Inner right line.
+ g.drawLine(x + w - 2, y, x + w - 2, y + h - 2);
- if (! isSelected || tabPlacement != SwingConstants.RIGHT)
- {
- g.setColor(lightHighlight);
- g.drawLine(x, y, x, y + h);
- }
+ // Inner bottom line.
+ g.drawLine(x + 2, y + h - 1, x + w - 3, y + h - 1);
- if (! isSelected || tabPlacement != SwingConstants.BOTTOM)
- {
+ g.setColor(darkShadow);
+ // Outer right line.
+ g.drawLine(x + w - 1, y, x + w - 1, y + h - 3);
+
+ // Bottom right corner.
+ g.drawLine(x + w - 1, y + h - 2, x + w - 3, y + h);
+
+ // Bottom line.
+ g.drawLine(x + 2, y + h, x + w - 4, y + h);
+
g.setColor(lightHighlight);
- g.drawLine(x, y, x + w, y);
- }
-
+ // Left line.
+ g.drawLine(x, y, x, y + h - 3);
+
+ // Bottom left corner.
+ g.drawLine(x, y + h - 2, x + 1, y + h - 1);
+ break;
+ case SwingConstants.RIGHT:
+ g.setColor(lightHighlight);
+ // Top line.
+ g.drawLine(x, y, x + w - 3, y);
+
+ g.setColor(darkShadow);
+ // Top right corner.
+ g.drawLine(x + w - 2, y + 1, x + w - 1, y + 2);
+
+ // Outer right line.
+ g.drawLine(x + w - 1, y + 3, x + w - 1, y + h - 3);
+
+ // Bottom right corner.
+ g.drawLine(x + w - 2, y + h - 2, x + w - 3, y + h - 1);
+
+ // Bottom line.
+ g.drawLine(x, y + h - 1, x + w - 4, y + h - 1);
+
+ g.setColor(shadow);
+
+ // Inner right line.
+ g.drawLine(x + w - 2, y + 2, x + w - 2, y + h - 3);
+
+ // Inner bottom line.
+ g.drawLine(x, y + h - 2, x + w - 3, y + h - 2);
+
+ break;
+ }
+
g.setColor(saved);
}
@@ -2175,17 +2721,32 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
boolean isSelected)
{
Color saved = g.getColor();
+
if (isSelected)
- g.setColor(Color.LIGHT_GRAY);
+ g.setColor(selectedColor);
else
{
Color bg = tabPane.getBackgroundAt(tabIndex);
if (bg == null)
- bg = Color.GRAY;
+ bg = Color.LIGHT_GRAY;
g.setColor(bg);
}
- g.fillRect(x, y, w, h);
+ switch (tabPlacement)
+ {
+ case SwingConstants.TOP:
+ g.fillRect(x + 1, y + 1, w - 1, h - 1);
+ break;
+ case SwingConstants.BOTTOM:
+ g.fillRect(x, y, w - 1, h - 1);
+ break;
+ case SwingConstants.LEFT:
+ g.fillRect(x + 1, y + 1, w - 1, h - 2);
+ break;
+ case SwingConstants.RIGHT:
+ g.fillRect(x, y + 1, w - 1, h - 2);
+ break;
+ }
g.setColor(saved);
}
@@ -2262,25 +2823,27 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
Color saved = g.getColor();
g.setColor(lightHighlight);
- int startgap = rects[selectedIndex].x;
- int endgap = rects[selectedIndex].x + rects[selectedIndex].width;
-
- int diff = 0;
+ int startgap = rects[selectedIndex].x - currentScrollOffset;
+ int endgap = rects[selectedIndex].x + rects[selectedIndex].width
+ - currentScrollOffset;
- if (tabPlacement == SwingConstants.TOP)
+ // Paint the highlight line with a gap if the tabs are at the top
+ // and the selected tab is inside the visible area.
+ if (tabPlacement == SwingConstants.TOP && startgap >= 0)
{
- if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
- {
- Point p = findPointForIndex(currentScrollLocation);
- diff = p.x;
- }
-
- g.drawLine(x, y, startgap - diff, y);
- g.drawLine(endgap - diff, y, x + w, y);
+ g.drawLine(x, y, startgap, y);
+ g.drawLine(endgap, y, x + w - 1, y);
+
+ g.setColor(selectedColor);
+ g.drawLine(startgap, y, endgap - 1, y);
}
else
g.drawLine(x, y, x + w, y);
-
+
+ g.setColor(selectedColor);
+ g.drawLine(x, y + 1, x + w - 1, y + 1);
+ g.drawLine(x, y + 2, x + w - 1, y + 2);
+
g.setColor(saved);
}
@@ -2302,24 +2865,25 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
Color saved = g.getColor();
g.setColor(lightHighlight);
- int startgap = rects[selectedIndex].y;
- int endgap = rects[selectedIndex].y + rects[selectedIndex].height;
+ int startgap = rects[selectedIndex].y - currentScrollOffset;
+ int endgap = rects[selectedIndex].y + rects[selectedIndex].height
+ - currentScrollOffset;
int diff = 0;
- if (tabPlacement == SwingConstants.LEFT)
+ if (tabPlacement == SwingConstants.LEFT && startgap >= 0)
{
- if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
- {
- Point p = findPointForIndex(currentScrollLocation);
- diff = p.y;
- }
-
- g.drawLine(x, y, x, startgap - diff);
- g.drawLine(x, endgap - diff, x, y + h);
+ g.drawLine(x, y, x, startgap);
+ g.drawLine(x, endgap, x, y + h - 1);
+
+ g.setColor(selectedColor);
+ g.drawLine(x, startgap, x, endgap - 1);
}
else
- g.drawLine(x, y, x, y + h);
+ g.drawLine(x, y, x, y + h - 1);
+
+ g.setColor(selectedColor);
+ g.drawLine(x + 1, y + 1, x + 1, y + h - 4);
g.setColor(saved);
}
@@ -2341,34 +2905,34 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
Color saved = g.getColor();
- int startgap = rects[selectedIndex].x;
- int endgap = rects[selectedIndex].x + rects[selectedIndex].width;
-
- int diff = 0;
+ int startgap = rects[selectedIndex].x - currentScrollOffset;
+ int endgap = rects[selectedIndex].x + rects[selectedIndex].width
+ - currentScrollOffset;
- if (tabPlacement == SwingConstants.BOTTOM)
+ if (tabPlacement == SwingConstants.BOTTOM && startgap >= 0)
{
- if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
- {
- Point p = findPointForIndex(currentScrollLocation);
- diff = p.x;
- }
-
g.setColor(shadow);
- g.drawLine(x + 1, y + h - 1, startgap - diff, y + h - 1);
- g.drawLine(endgap - diff, y + h - 1, x + w - 1, y + h - 1);
+ g.drawLine(x + 1, y + h - 2, startgap, y + h - 2);
+ g.drawLine(endgap, y + h - 2, x + w - 2, y + h - 2);
g.setColor(darkShadow);
- g.drawLine(x, y + h, startgap - diff, y + h);
- g.drawLine(endgap - diff, y + h, x + w, y + h);
+ g.drawLine(x, y + h - 1, startgap , y + h - 1);
+ g.drawLine(endgap, y + h - 1, x + w - 1, y + h - 1);
+
+ g.setColor(selectedColor);
+ g.drawLine(startgap, y + h - 1, endgap - 1, y + h - 1);
+ g.drawLine(startgap, y + h - 2, endgap - 1, y + h - 2);
}
else
{
g.setColor(shadow);
- g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1);
+ g.drawLine(x + 1, y + h - 2, x + w - 1, y + h - 2);
g.setColor(darkShadow);
- g.drawLine(x, y + h, x + w, y + h);
+ g.drawLine(x, y + h - 1, x + w - 1, y + h - 1);
}
+
+ g.setColor(selectedColor);
+ g.drawLine(x + 1, y + h - 3, x + w - 2, y + h - 3);
g.setColor(saved);
}
@@ -2389,34 +2953,36 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
int w, int h)
{
Color saved = g.getColor();
- int startgap = rects[selectedIndex].y;
- int endgap = rects[selectedIndex].y + rects[selectedIndex].height;
+ int startgap = rects[selectedIndex].y - currentScrollOffset;
+ int endgap = rects[selectedIndex].y + rects[selectedIndex].height
+ - currentScrollOffset;
int diff = 0;
- if (tabPlacement == SwingConstants.RIGHT)
+ if (tabPlacement == SwingConstants.RIGHT && startgap >= 0)
{
- if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
- {
- Point p = findPointForIndex(currentScrollLocation);
- diff = p.y;
- }
-
g.setColor(shadow);
- g.drawLine(x + w - 1, y + 1, x + w - 1, startgap - diff);
- g.drawLine(x + w - 1, endgap - diff, x + w - 1, y + h - 1);
+ g.drawLine(x + w - 2, y + 1, x + w - 2, startgap);
+ g.drawLine(x + w - 2, endgap, x + w - 2, y + h - 2);
g.setColor(darkShadow);
- g.drawLine(x + w, y, x + w, startgap - diff);
- g.drawLine(x + w, endgap - diff, x + w, y + h);
+ g.drawLine(x + w - 1, y, x + w - 1, startgap);
+ g.drawLine(x + w - 1, endgap, x + w - 1, y + h - 2);
+
+ g.setColor(selectedColor);
+ g.drawLine(x + w - 2, startgap, x + w - 2, endgap - 1);
+ g.drawLine(x + w - 1, startgap, x + w - 1, endgap - 1);
}
else
{
g.setColor(shadow);
- g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);
+ g.drawLine(x + w - 2, y + 1, x + w - 2, y + h - 2);
g.setColor(darkShadow);
- g.drawLine(x + w, y, x + w, y + h);
+ g.drawLine(x + w - 1, y, x + w - 1, y + h - 2);
}
+
+ g.setColor(selectedColor);
+ g.drawLine(x + w - 3, y + 1, x + w - 3, y + h - 4);
g.setColor(saved);
}
@@ -2460,11 +3026,15 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
public int tabForCoordinate(JTabbedPane pane, int x, int y)
{
+ // Note: This code is tab layout mode agnostic.
if (! tabPane.isValid())
tabPane.validate();
-
+
int tabCount = tabPane.getTabCount();
- int index = -1;
+
+ // If the user clicked outside of any tab rect the
+ // selection should not change.
+ int index = tabPane.getSelectedIndex();
for (int i = 0; i < tabCount; ++i)
{
if (rects[i].contains(x, y))
@@ -2474,8 +3044,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
}
}
- // FIXME: Handle scrollable tab layout.
-
return index;
}
@@ -2571,7 +3139,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
protected int getRunForTab(int tabCount, int tabIndex)
{
if (runCount == 1 && tabIndex < tabCount && tabIndex >= 0)
- return 1;
+ return 0;
for (int i = 0; i < runCount; i++)
{
int first = lastTabInRun(tabCount, getPreviousTabRun(i)) + 1;
@@ -2690,6 +3258,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
protected View getTextViewForTab(int tabIndex)
{
+ // FIXME: When the label contains HTML this should return something
+ // non-null.
return null;
}
@@ -2706,7 +3276,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
protected int calculateTabHeight(int tabPlacement, int tabIndex,
int fontHeight)
{
- // FIXME: Handle HTML somehow.
+ // FIXME: Handle HTML by using the view (see getTextViewForTab).
int height = fontHeight;
Icon icon = getIconForTab(tabIndex);
@@ -2923,8 +3493,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
int offset = getTabRunOffset(tabPlacement, tabPane.getTabCount(),
tabPane.getSelectedIndex(),
- (tabPlacement == SwingConstants.RIGHT)
- ? true : false);
+ (tabPlacement == SwingConstants.TOP)
+ ? direction == SwingConstants.NORTH
+ : direction == SwingConstants.SOUTH);
selectAdjacentRunTab(tabPlacement, tabPane.getSelectedIndex(),
offset);
}
@@ -2940,8 +3511,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
int offset = getTabRunOffset(tabPlacement, tabPane.getTabCount(),
tabPane.getSelectedIndex(),
- (tabPlacement == SwingConstants.RIGHT)
- ? true : false);
+ (tabPlacement == SwingConstants.LEFT)
+ ? direction == SwingConstants.WEST
+ : direction == SwingConstants.EAST);
selectAdjacentRunTab(tabPlacement, tabPane.getSelectedIndex(),
offset);
}
@@ -2955,8 +3527,13 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
protected void selectNextTabInRun(int current)
{
- tabPane.setSelectedIndex(getNextTabIndexInRun(tabPane.getTabCount(),
- current));
+ current = getNextTabIndexInRun(tabPane.getTabCount(),
+ current);
+
+ if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+ scrollTab(current, tabPane.getTabPlacement());
+
+ tabPane.setSelectedIndex(current);
}
/**
@@ -2966,8 +3543,13 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
protected void selectPreviousTabInRun(int current)
{
- tabPane.setSelectedIndex(getPreviousTabIndexInRun(tabPane.getTabCount(),
- current));
+ current = getPreviousTabIndexInRun(tabPane.getTabCount(),
+ current);
+
+ if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+ scrollTab(current, tabPane.getTabPlacement());
+
+ tabPane.setSelectedIndex(current);
}
/**
@@ -2977,7 +3559,12 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
protected void selectNextTab(int current)
{
- tabPane.setSelectedIndex(getNextTabIndex(current));
+ current = getNextTabIndex(current);
+
+ if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+ scrollTab(current, tabPane.getTabPlacement());
+
+ tabPane.setSelectedIndex(current);
}
/**
@@ -2987,7 +3574,12 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
protected void selectPreviousTab(int current)
{
- tabPane.setSelectedIndex(getPreviousTabIndex(current));
+ current = getPreviousTabIndex(current);
+
+ if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+ scrollTab(current, tabPane.getTabPlacement());
+
+ tabPane.setSelectedIndex(current);
}
/**
@@ -3021,7 +3613,11 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
int index = tabForCoordinate(tabPane, x, y);
if (index != -1)
- tabPane.setSelectedIndex(index);
+ {
+ if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+ scrollTab(index, tabPlacement);
+ tabPane.setSelectedIndex(index);
+ }
}
// This method is called when you press up/down to cycle through tab runs.
@@ -3058,6 +3654,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
else
offset = rects[lastTabInRun(tabCount, nextRun)].x
- rects[lastTabInRun(tabCount, currRun)].x;
+
return offset;
}
@@ -3104,9 +3701,12 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
int index = getNextTabIndex(base);
int run = getRunForTab(tabCount, base);
- if (index == lastTabInRun(tabCount, run) + 1)
- index = lastTabInRun(tabCount, getPreviousTabRun(run)) + 1;
- return getNextTabIndex(base);
+ if (base == lastTabInRun(tabCount, run))
+ index = (run > 0)
+ ? lastTabInRun(tabCount, getPreviousTabRun(run)) + 1
+ : 0;
+
+ return index;
}
/**
@@ -3124,7 +3724,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
int run = getRunForTab(tabCount, base);
if (index == lastTabInRun(tabCount, getPreviousTabRun(run)))
index = lastTabInRun(tabCount, run);
- return getPreviousTabIndex(base);
+
+ return index;
}
/**
@@ -3182,6 +3783,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
// so I won't check it either.
switch (targetPlacement)
{
+ default:
case SwingConstants.TOP:
targetInsets.top = topInsets.top;
targetInsets.left = topInsets.left;
@@ -3208,6 +3810,44 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
break;
}
}
+
+ ActionMap getActionMap()
+ {
+ ActionMap map = (ActionMap) UIManager.get("TabbedPane.actionMap");
+
+ if (map == null) // first time here
+ {
+ map = createActionMap();
+ if (map != null)
+ UIManager.put("TabbedPane.actionMap", map);
+ }
+ return map;
+ }
+
+ ActionMap createActionMap()
+ {
+ ActionMap map = new ActionMapUIResource();
+
+ map.put("navigatePageDown", new NavigatePageDownAction());
+ map.put("navigatePageUp", new NavigatePageUpAction());
+ map.put("navigateDown",
+ new NavigateAction("navigateDown", SwingConstants.SOUTH));
+
+ map.put("navigateUp",
+ new NavigateAction("navigateUp", SwingConstants.NORTH));
+
+ map.put("navigateLeft",
+ new NavigateAction("navigateLeft", SwingConstants.WEST));
+
+ map.put("navigateRight",
+ new NavigateAction("navigateRight", SwingConstants.EAST));
+
+ map.put("requestFocusForVisibleComponent",
+ new RequestFocusForVisibleComponentAction());
+ map.put("requestFocus", new RequestFocusAction());
+
+ return map;
+ }
/**
* Sets the tab which should be highlighted when in rollover mode. And
diff --git a/javax/swing/plaf/metal/MetalTabbedPaneUI.java b/javax/swing/plaf/metal/MetalTabbedPaneUI.java
index c49abe832..20135fc85 100644
--- a/javax/swing/plaf/metal/MetalTabbedPaneUI.java
+++ b/javax/swing/plaf/metal/MetalTabbedPaneUI.java
@@ -1,5 +1,5 @@
/* MetalTabbedPaneUI.java
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -170,7 +170,9 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI
*/
protected LayoutManager createLayoutManager()
{
- return new TabbedPaneLayout();
+ return (tabPane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT)
+ ? new MetalTabbedPaneUI.TabbedPaneLayout()
+ : super.createLayoutManager();
}
/**
@@ -326,7 +328,6 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI
int bottom = h - 1;
int right = w - 1;
-
int tabCount = tabPane.getTabCount();
int currentRun = getRunForTab(tabCount, tabIndex);
int firstIndex = tabRuns[currentRun];
@@ -396,14 +397,17 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI
{
if (tabPane.getSelectedIndex() == tabIndex - 1)
{
- g.drawLine(0, 5, 0, bottom);
- g.setColor(oceanSelectedBorder);
- g.drawLine(0, 0, 0, 5);
+ g.drawLine(0, 6, 0, bottom);
+ if (tabIndex != firstIndex)
+ {
+ g.setColor(oceanSelectedBorder);
+ g.drawLine(0, 0, 0, 5);
+ }
}
else if (isSelected)
{
g.drawLine(0, 5, 0, bottom);
- if (tabIndex != 0)
+ if (tabIndex != firstIndex)
{
g.setColor(darkShadow);
g.drawLine(0, 0, 0, 5);
@@ -463,9 +467,10 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI
{
Color c;
if (tabPane.getSelectedIndex() == tabIndex - 1)
- c = UIManager.getColor("TabbedPane.tabAreaBackground");
+ c = selectColor;
else
c = getUnselectedBackground(tabIndex - 1);
+ g.setColor(c);
g.fillRect(right - 5, 0, 5, 3);
g.fillRect(right - 2, 3, 2, 2);
}
@@ -522,10 +527,13 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI
}
else if (isOcean && tabPane.getSelectedIndex() == tabIndex - 1)
{
- g.setColor(oceanSelectedBorder);
- g.drawLine(right, 0, right, 6);
+ if (tabIndex != firstIndex)
+ {
+ g.setColor(oceanSelectedBorder);
+ g.drawLine(right, 0, right, 6);
+ }
g.setColor(darkShadow);
- g.drawLine(right, 6, right, bottom);
+ g.drawLine(right, 7, right, bottom);
}
else if (tabIndex != firstIndex)
{
@@ -598,8 +606,10 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI
if (isOcean && isSelected)
{
g.drawLine(0, 0, 0, bottom - 5);
- if ((currentRun == 0 && tabIndex != 0)
- || (currentRun > 0 && tabIndex != tabRuns[currentRun - 1]))
+
+ // Paint a connecting line to the tab below for all
+ // but the first tab in the last run.
+ if (tabIndex != tabRuns[runCount-1])
{
g.setColor(darkShadow);
g.drawLine(0, bottom - 5, 0, bottom);
@@ -688,6 +698,103 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI
}
/**
+ * This method paints the focus rectangle around the selected tab.
+ *
+ * @param g The Graphics object to paint with.
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param rects The array of rectangles keeping track of size and position.
+ * @param tabIndex The tab index.
+ * @param iconRect The icon bounds.
+ * @param textRect The text bounds.
+ * @param isSelected Whether this tab is selected.
+ */
+ protected void paintFocusIndicator(Graphics g, int tabPlacement,
+ Rectangle[] rects, int tabIndex,
+ Rectangle iconRect, Rectangle textRect,
+ boolean isSelected)
+ {
+ if (tabPane.hasFocus() && isSelected)
+ {
+ Rectangle rect = rects[tabIndex];
+
+ g.setColor(focus);
+ g.translate(rect.x, rect.y);
+
+ switch (tabPlacement)
+ {
+ case LEFT:
+ // Top line
+ g.drawLine(7, 2, rect.width-2, 2);
+
+ // Right line
+ g.drawLine(rect.width-1, 2, rect.width-1, rect.height-3);
+
+ // Bottom line
+ g.drawLine(rect.width-2, rect.height-2, 3, rect.height-2);
+
+ // Left line
+ g.drawLine(2, rect.height-3, 2, 7);
+
+ // Slant
+ g.drawLine(2, 6, 6, 2);
+ break;
+ case RIGHT:
+ // Top line
+ g.drawLine(1, 2, rect.width-8, 2);
+
+ // Slant
+ g.drawLine(rect.width-7, 2, rect.width-3, 6);
+
+ // Right line
+ g.drawLine(rect.width-3, 7, rect.width-3, rect.height-3);
+
+ // Bottom line
+ g.drawLine(rect.width-3, rect.height-2, 2, rect.height-2);
+
+ // Left line
+ g.drawLine(1, rect.height-2, 1, 2);
+ break;
+ case BOTTOM:
+ // Top line
+ g.drawLine(2, 1, rect.width-2, 1);
+
+ // Right line
+ g.drawLine(rect.width-1, 2, rect.width-1, rect.height-3);
+
+ // Bottom line
+ g.drawLine(7, rect.height-3, rect.width-2, rect.height-3);
+
+ // Slant
+ g.drawLine(6, rect.height-3, 2, rect.height-7);
+
+ // Left line
+ g.drawLine(2, rect.height-8, 2, 2);
+
+ break;
+ case TOP:
+ default:
+ // Top line
+ g.drawLine(6, 2, rect.width-2, 2);
+
+ // Right line
+ g.drawLine(rect.width-1, 2, rect.width-1, rect.height-3);
+
+ // Bottom line
+ g.drawLine(3, rect.height-3, rect.width-2, rect.height-3);
+
+ // Left line
+ g.drawLine(2, rect.height-3, 2, 7);
+
+ // Slant
+ g.drawLine(2, 6, 6, 2);
+
+ }
+
+ g.translate(-rect.x, -rect.y);
+ }
+ }
+
+ /**
* Returns <code>true</code> if the tabs in the specified run should be
* padded to make the run fill the width/height of the {@link JTabbedPane}.
*
@@ -1144,4 +1251,19 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI
bg = unselectedBackground;
return bg;
}
+
+ protected int getTabLabelShiftX(int tabPlacement,
+ int index,
+ boolean isSelected)
+ {
+ return 0;
+ }
+
+ protected int getTabLabelShiftY(int tabPlacement,
+ int index,
+ boolean isSelected)
+ {
+ return 0;
+ }
+
}