summaryrefslogtreecommitdiff
path: root/javax/swing/plaf/basic/BasicTabbedPaneUI.java
diff options
context:
space:
mode:
Diffstat (limited to 'javax/swing/plaf/basic/BasicTabbedPaneUI.java')
-rw-r--r--javax/swing/plaf/basic/BasicTabbedPaneUI.java852
1 files changed, 493 insertions, 359 deletions
diff --git a/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/javax/swing/plaf/basic/BasicTabbedPaneUI.java
index 5b1e1ff0f..6d9bed331 100644
--- a/javax/swing/plaf/basic/BasicTabbedPaneUI.java
+++ b/javax/swing/plaf/basic/BasicTabbedPaneUI.java
@@ -38,6 +38,8 @@ 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;
@@ -130,52 +132,49 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
public void mousePressed(MouseEvent e)
{
- int x = e.getX();
- int y = e.getY();
- int tabCount = tabPane.getTabCount();
-
- if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+ if (tabPane.isEnabled())
{
- if (e.getSource() == incrButton)
+ int index = tabForCoordinate(tabPane, e.getX(), e.getY());
+ if (index >= 0 && tabPane.isEnabledAt(index))
{
- if (++currentScrollLocation >= tabCount)
- currentScrollLocation = tabCount - 1;
-
- int width = 0;
- for (int i = currentScrollLocation - 1; i < tabCount; i++)
- width += rects[i].width;
- if (width < viewport.getWidth())
- // FIXME: Still getting mouse events after the button is disabled.
- // incrButton.setEnabled(false);
- currentScrollLocation--;
- else if (! decrButton.isEnabled())
- decrButton.setEnabled(true);
- tabPane.revalidate();
- tabPane.repaint();
- return;
- }
- else if (e.getSource() == decrButton)
- {
- if (--currentScrollLocation < 0)
- currentScrollLocation = 0;
- if (currentScrollLocation == 0)
- decrButton.setEnabled(false);
- else if (! incrButton.isEnabled())
- incrButton.setEnabled(true);
- tabPane.revalidate();
- tabPane.repaint();
- return;
+ tabPane.setSelectedIndex(index);
}
}
+ }
- int index = tabForCoordinate(tabPane, x, y);
+ /**
+ * Receives notification when the mouse pointer has entered the tabbed
+ * pane.
+ *
+ * @param ev the mouse event
+ */
+ public void mouseEntered(MouseEvent ev)
+ {
+ int tabIndex = tabForCoordinate(tabPane, ev.getX(), ev.getY());
+ setRolloverTab(tabIndex);
+ }
- // We need to check since there are areas where tabs cannot be
- // e.g. in the inset area.
- if (index != -1 && tabPane.isEnabledAt(index))
- tabPane.setSelectedIndex(index);
- tabPane.revalidate();
- tabPane.repaint();
+ /**
+ * Receives notification when the mouse pointer has exited the tabbed
+ * pane.
+ *
+ * @param ev the mouse event
+ */
+ public void mouseExited(MouseEvent ev)
+ {
+ setRolloverTab(-1);
+ }
+
+ /**
+ * Receives notification when the mouse pointer has moved over the tabbed
+ * pane.
+ *
+ * @param ev the mouse event
+ */
+ public void mouseMoved(MouseEvent ev)
+ {
+ int tabIndex = tabForCoordinate(tabPane, ev.getX(), ev.getY());
+ setRolloverTab(tabIndex);
}
}
@@ -241,21 +240,10 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
public void calculateLayoutInfo()
{
- assureRectsCreated(tabPane.getTabCount());
- contentRect = SwingUtilities.calculateInnerArea(tabPane, contentRect);
-
- calculateTabRects(tabPane.getTabPlacement(), tabPane.getTabCount());
-
- if (tabPane.getSelectedIndex() != -1)
- {
- Component visible = getVisibleComponent();
- Insets insets = getContentBorderInsets(tabPane.getTabPlacement());
- if (visible != null)
- visible.setBounds(contentRect.x + insets.left,
- contentRect.y + insets.top,
- contentRect.width - insets.left - insets.right,
- contentRect.height - insets.top - insets.bottom);
- }
+ int count = tabPane.getTabCount();
+ assureRectsCreated(count);
+ calculateTabRects(tabPane.getTabPlacement(), count);
+ tabRunsDirty = false;
}
/**
@@ -269,45 +257,51 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
protected Dimension calculateSize(boolean minimum)
{
int tabPlacement = tabPane.getTabPlacement();
+
int width = 0;
int height = 0;
-
- int componentHeight = 0;
- int componentWidth = 0;
Component c;
Dimension dims;
+
+ // Find out the minimum/preferred size to display the largest child
+ // of the tabbed pane.
for (int i = 0; i < tabPane.getTabCount(); i++)
{
c = tabPane.getComponentAt(i);
if (c == null)
continue;
- calcRect = c.getBounds();
- dims = c.getPreferredSize();
+ dims = minimum ? c.getMinimumSize() : c.getPreferredSize();
if (dims != null)
{
- componentHeight = Math.max(componentHeight, dims.height);
- componentWidth = Math.max(componentWidth, dims.width);
+ height = Math.max(height, dims.height);
+ width = Math.max(width, dims.width);
}
}
+
+ Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
if (tabPlacement == SwingConstants.TOP
|| tabPlacement == SwingConstants.BOTTOM)
{
int min = calculateMaxTabWidth(tabPlacement);
- width = Math.max(min, componentWidth);
-
- int tabAreaHeight = preferredTabAreaHeight(tabPlacement, width);
- height = tabAreaHeight + componentHeight;
+ width = Math.max(min, width);
+ int tabAreaHeight = preferredTabAreaHeight(tabPlacement,
+ width - tabAreaInsets.left
+ -tabAreaInsets.right);
+ height += tabAreaHeight;
}
else
{
int min = calculateMaxTabHeight(tabPlacement);
- height = Math.max(min, componentHeight);
-
- int tabAreaWidth = preferredTabAreaWidth(tabPlacement, height);
- width = tabAreaWidth + componentWidth;
+ height = Math.max(min, height);
+ int tabAreaWidth = preferredTabAreaWidth(tabPlacement,
+ height - tabAreaInsets.top
+ - tabAreaInsets.bottom);
+ width += tabAreaWidth;
}
- return new Dimension(width, height);
+ Insets tabPaneInsets = tabPane.getInsets();
+ return new Dimension(width + tabPaneInsets.left + tabPaneInsets.right,
+ height + tabPaneInsets.top + tabPaneInsets.bottom);
}
// if tab placement is LEFT OR RIGHT, they share width.
@@ -330,192 +324,197 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
protected void calculateTabRects(int tabPlacement, int tabCount)
{
+ Insets insets = tabPane.getInsets();
+ Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
+ Dimension size = tabPane.getSize();
+
+ // The coordinates of the upper left corner of the tab area.
+ int x;
+ int y;
+ // The location at which the runs must be broken.
+ int breakAt;
+
+ // Calculate the bounds for the tab area.
+ switch (tabPlacement)
+ {
+ case LEFT:
+ maxTabWidth = calculateMaxTabWidth(tabPlacement);
+ x = insets.left + tabAreaInsets.left;
+ y = insets.top + tabAreaInsets.top;
+ breakAt = size.height - (insets.bottom + tabAreaInsets.bottom);
+ break;
+ case RIGHT:
+ maxTabWidth = calculateMaxTabWidth(tabPlacement);
+ x = size.width - (insets.right + tabAreaInsets.right) - maxTabWidth;
+ y = insets.top + tabAreaInsets.top;
+ breakAt = size.height - (insets.bottom + tabAreaInsets.bottom);
+ break;
+ case BOTTOM:
+ maxTabHeight = calculateMaxTabHeight(tabPlacement);
+ x = insets.left + tabAreaInsets.left;
+ y = size.height - (insets.bottom + tabAreaInsets.bottom)
+ - maxTabHeight;
+ breakAt = size.width - (insets.right + tabAreaInsets.right);
+ break;
+ case TOP:
+ default:
+ maxTabHeight = calculateMaxTabHeight(tabPlacement);
+ x = insets.left + tabAreaInsets.left;
+ y = insets.top + tabAreaInsets.top;
+ breakAt = size.width - (insets.right + tabAreaInsets.right);
+ break;
+ }
+
if (tabCount == 0)
return;
FontMetrics fm = getFontMetrics();
- SwingUtilities.calculateInnerArea(tabPane, calcRect);
- Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
- Insets insets = tabPane.getInsets();
- int max = 0;
- int runs = 0;
- int start = getTabRunIndent(tabPlacement, 1);
+ runCount = 0;
+ selectedRun = -1;
+ int selectedIndex = tabPane.getSelectedIndex();
+
+ Rectangle rect;
+
+ // Go through all the tabs and build the tab runs.
if (tabPlacement == SwingConstants.TOP
|| tabPlacement == SwingConstants.BOTTOM)
{
- int maxHeight = calculateMaxTabHeight(tabPlacement);
-
- calcRect.width -= tabAreaInsets.left + tabAreaInsets.right;
- max = calcRect.width + tabAreaInsets.left + insets.left;
- start += tabAreaInsets.left + insets.left;
- int width = 0;
- int runWidth = start;
-
for (int i = 0; i < tabCount; i++)
{
- width = calculateTabWidth(tabPlacement, i, fm);
- if (runWidth + width > max)
+ rect = rects[i];
+ if (i > 0)
{
- runWidth = tabAreaInsets.left + insets.left
- + getTabRunIndent(tabPlacement, ++runs);
- rects[i] = new Rectangle(runWidth,
- insets.top + tabAreaInsets.top,
- width, maxHeight);
- runWidth += width;
- if (runs > tabRuns.length - 1)
- expandTabRunsArray();
- tabRuns[runs] = i;
+ rect.x = rects[i - 1].x + rects[i - 1].width;
}
else
{
- rects[i] = new Rectangle(runWidth,
- insets.top + tabAreaInsets.top,
- width, maxHeight);
- runWidth += width;
+ tabRuns[0] = 0;
+ runCount = 1;
+ maxTabWidth = 0;
+ rect.x = x;
}
- }
- runs++;
- tabAreaRect.width = tabPane.getWidth() - insets.left - insets.right;
- tabAreaRect.height = runs * maxTabHeight
- - (runs - 1) * tabRunOverlay
- + tabAreaInsets.top + tabAreaInsets.bottom;
- contentRect.width = tabAreaRect.width;
- contentRect.height = tabPane.getHeight() - insets.top
- - insets.bottom - tabAreaRect.height;
- contentRect.x = insets.left;
- tabAreaRect.x = insets.left;
- if (tabPlacement == SwingConstants.BOTTOM)
- {
- contentRect.y = insets.top;
- tabAreaRect.y = contentRect.y + contentRect.height;
- }
- else
- {
- tabAreaRect.y = insets.top;
- contentRect.y = tabAreaRect.y + tabAreaRect.height;
+ rect.width = calculateTabWidth(tabPlacement, i, fm);
+ maxTabWidth = Math.max(maxTabWidth, rect.width);
+
+ if (rect.x != 2 + insets.left && rect.x + rect.width > breakAt)
+ {
+ if (runCount > tabRuns.length - 1)
+ expandTabRunsArray();
+ tabRuns[runCount] = i;
+ runCount++;
+ rect.x = x;
+ }
+
+ rect.y = y;
+ rect.height = maxTabHeight;
+ if (i == selectedIndex)
+ selectedRun = runCount - 1;
+
}
}
else
{
- int maxWidth = calculateMaxTabWidth(tabPlacement);
- calcRect.height -= tabAreaInsets.top + tabAreaInsets.bottom;
- max = calcRect.height + tabAreaInsets.top + insets.top;
-
- int height = 0;
- start += tabAreaInsets.top + insets.top;
- int runHeight = start;
-
- int fontHeight = fm.getHeight();
-
for (int i = 0; i < tabCount; i++)
{
- height = calculateTabHeight(tabPlacement, i, fontHeight);
- if (runHeight + height > max)
+ rect = rects[i];
+ if (i > 0)
{
- runHeight = tabAreaInsets.top + insets.top
- + getTabRunIndent(tabPlacement, ++runs);
- rects[i] = new Rectangle(insets.left + tabAreaInsets.left,
- runHeight, maxWidth, height);
- runHeight += height;
- if (runs > tabRuns.length - 1)
- expandTabRunsArray();
- tabRuns[runs] = i;
+ rect.y = rects[i - 1].y + rects[i - 1].height;
}
else
{
- rects[i] = new Rectangle(insets.left + tabAreaInsets.left,
- runHeight, maxWidth, height);
- runHeight += height;
+ tabRuns[0] = 0;
+ runCount = 1;
+ maxTabHeight = 0;
+ rect.y = y;
}
- }
- runs++;
+ rect.height = calculateTabHeight(tabPlacement, i,
+ fm.getHeight());
+ maxTabHeight = Math.max(maxTabHeight, rect.height);
- tabAreaRect.width = runs * maxTabWidth - (runs - 1) * tabRunOverlay
- + tabAreaInsets.left + tabAreaInsets.right;
- tabAreaRect.height = tabPane.getHeight() - insets.top
- - insets.bottom;
- tabAreaRect.y = insets.top;
- contentRect.width = tabPane.getWidth() - insets.left - insets.right
- - tabAreaRect.width;
- contentRect.height = tabAreaRect.height;
- contentRect.y = insets.top;
- if (tabPlacement == SwingConstants.LEFT)
- {
- tabAreaRect.x = insets.left;
- contentRect.x = tabAreaRect.x + tabAreaRect.width;
- }
- else
- {
- contentRect.x = insets.left;
- tabAreaRect.x = contentRect.x + contentRect.width;
+ if (rect.y != 2 + insets.top && rect.y + rect.height > breakAt)
+ {
+ if (runCount > tabRuns.length - 1)
+ expandTabRunsArray();
+ tabRuns[runCount] = i;
+ runCount++;
+ rect.y = y;
+ }
+
+ rect.x = x;
+ rect.width = maxTabWidth;
+
+ if (i == selectedIndex)
+ selectedRun = runCount - 1;
}
}
- runCount = runs;
- if (runCount > tabRuns.length)
- expandTabRunsArray();
-
- tabRuns[0] = 0;
- normalizeTabRuns(tabPlacement, tabCount, start, max);
- selectedRun = getRunForTab(tabCount, tabPane.getSelectedIndex());
- if (shouldRotateTabRuns(tabPlacement))
- rotateTabRuns(tabPlacement, selectedRun);
- // Need to pad the runs and move them to the correct location.
- for (int i = 0; i < runCount; i++)
+ if (runCount > 1)
{
- int first = lastTabInRun(tabCount, getPreviousTabRun(i)) + 1;
- if (first == tabCount)
- first = 0;
- int last = lastTabInRun(tabCount, i);
- if (shouldPadTabRun(tabPlacement, i))
- padTabRun(tabPlacement, first, last, max);
-
- // Done padding, now need to move it.
- if (tabPlacement == SwingConstants.TOP && i > 0)
+ int start;
+ if (tabPlacement == SwingConstants.TOP
+ || tabPlacement == SwingConstants.BOTTOM)
+ start = y;
+ else
+ start = x;
+ normalizeTabRuns(tabPlacement, tabCount, start, breakAt);
+ selectedRun = getRunForTab(tabCount, selectedIndex);
+ if (shouldRotateTabRuns(tabPlacement))
{
- for (int j = first; j <= last; j++)
- rects[j].y += (runCount - i) * maxTabHeight
- - (runCount - i) * tabRunOverlay;
+ rotateTabRuns(tabPlacement, selectedRun);
}
+ }
- if (tabPlacement == SwingConstants.BOTTOM)
+ // Pad the runs.
+ int tabRunOverlay = getTabRunOverlay(tabPlacement);
+ for (int i = runCount - 1; i >= 0; --i)
+ {
+ int start = tabRuns[i];
+ int nextIndex;
+ if (i == runCount - 1)
+ nextIndex = 0;
+ else
+ nextIndex = i + 1;
+ int next = tabRuns[nextIndex];
+ int end = (next != 0 ? next - 1 : tabCount - 1);
+ if (tabPlacement == SwingConstants.TOP
+ || tabPlacement == SwingConstants.BOTTOM)
{
- int height = tabPane.getBounds().height - insets.bottom
- - tabAreaInsets.bottom;
- int adjustment;
- if (i == 0)
- adjustment = height - maxTabHeight;
+ for (int j = start; j <= end; ++j)
+ {
+ rect = rects[j];
+ rect.y = y;
+ rect.x += getTabRunIndent(tabPlacement, i);
+ }
+ if (shouldPadTabRun(tabPlacement, i))
+ {
+ padTabRun(tabPlacement, start, end, breakAt);
+ }
+ if (tabPlacement == BOTTOM)
+ y -= (maxTabHeight - tabRunOverlay);
else
- adjustment = height - (runCount - i + 1) * maxTabHeight
- - (runCount - i) * tabRunOverlay;
-
- for (int j = first; j <= last; j++)
- rects[j].y = adjustment;
- }
-
- if (tabPlacement == SwingConstants.LEFT && i > 0)
- {
- for (int j = first; j <= last; j++)
- rects[j].x += (runCount - i) * maxTabWidth
- - (runCount - i) * tabRunOverlay;
+ y += (maxTabHeight - tabRunOverlay);
}
-
- if (tabPlacement == SwingConstants.RIGHT)
+ else
{
- int width = tabPane.getBounds().width - insets.right
- - tabAreaInsets.right;
- int adjustment;
- if (i == 0)
- adjustment = width - maxTabWidth;
+ for (int j = start; j <= end; ++j)
+ {
+ rect = rects[j];
+ rect.x = x;
+ rect.y += getTabRunIndent(tabPlacement, i);
+ }
+ if (shouldPadTabRun(tabPlacement, i))
+ {
+ padTabRun(tabPlacement, start, end, breakAt);
+ }
+ if (tabPlacement == RIGHT)
+ x -= (maxTabWidth - tabRunOverlay);
else
- adjustment = width - (runCount - i + 1) * maxTabWidth
- + (runCount - i) * tabRunOverlay;
-
- for (int j = first; j <= last; j++)
- rects[j].x = adjustment;
+ x += (maxTabWidth - tabRunOverlay);
+
}
}
- padSelectedTab(tabPlacement, tabPane.getSelectedIndex());
+ padSelectedTab(tabPlacement, selectedIndex);
}
/**
@@ -528,6 +527,58 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
public void layoutContainer(Container parent)
{
calculateLayoutInfo();
+
+ int tabPlacement = tabPane.getTabPlacement();
+ Insets insets = tabPane.getInsets();
+ int childCount = tabPane.getComponentCount();
+ if (childCount > 0)
+ {
+ int compX;
+ int compY;
+ int tabAreaWidth = 0;
+ int tabAreaHeight = 0;
+ switch (tabPlacement)
+ {
+ case LEFT:
+ tabAreaWidth = calculateTabAreaWidth(tabPlacement, runCount,
+ maxTabWidth);
+ compX = tabAreaWidth + insets.left + contentBorderInsets.left;
+ compY = insets.top + contentBorderInsets.top;
+ break;
+ case RIGHT:
+ tabAreaWidth = calculateTabAreaWidth(tabPlacement, runCount,
+ maxTabWidth);
+ compX = insets.left + contentBorderInsets.left;
+ compY = insets.top + contentBorderInsets.top;
+ break;
+ case BOTTOM:
+ tabAreaHeight = calculateTabAreaHeight(tabPlacement, runCount,
+ maxTabHeight);
+ compX = insets.left + contentBorderInsets.left;
+ compY = insets.top + contentBorderInsets.top;
+ break;
+ case TOP:
+ default:
+ tabAreaHeight = calculateTabAreaHeight(tabPlacement, runCount,
+ maxTabHeight);
+ compX = insets.left + contentBorderInsets.left;
+ compY = tabAreaHeight + insets.top + contentBorderInsets.top;
+ }
+ Rectangle bounds = tabPane.getBounds();
+ int compWidth = bounds.width - tabAreaWidth - insets.left
+ - insets.right - contentBorderInsets.left
+ - contentBorderInsets.right;
+ int compHeight = bounds.height - tabAreaHeight - insets.top
+ - insets.bottom - contentBorderInsets.top
+ - contentBorderInsets.bottom;
+
+
+ for (int i = 0; i < childCount; ++i)
+ {
+ Component c = tabPane.getComponent(i);
+ c.setBounds(compX, compY, compWidth, compHeight);
+ }
+ }
}
/**
@@ -1288,6 +1339,12 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
protected int[] tabRuns;
/**
+ * Indicates if the layout of the tab runs is ok or not. This is package
+ * private to avoid a synthetic accessor method.
+ */
+ boolean tabRunsDirty;
+
+ /**
* This is the keystroke for moving down.
*
* @deprecated 1.3
@@ -1343,6 +1400,17 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
transient Rectangle contentRect;
/**
+ * The index over which the mouse is currently moving.
+ */
+ private int rolloverTab;
+
+ /**
+ * Determines if tabs are painted opaque or not. This can be adjusted using
+ * the UIManager property 'TabbedPane.tabsOpaque'.
+ */
+ private boolean tabsOpaque;
+
+ /**
* Creates a new BasicTabbedPaneUI object.
*/
public BasicTabbedPaneUI()
@@ -1557,6 +1625,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
selectedTabPadInsets = UIManager.getInsets("TabbedPane.tabbedPaneTabPadInsets");
tabAreaInsets = UIManager.getInsets("TabbedPane.tabAreaInsets");
contentBorderInsets = UIManager.getInsets("TabbedPane.tabbedPaneContentBorderInsets");
+ tabsOpaque = UIManager.getBoolean("TabbedPane.tabsOpaque");
calcRect = new Rectangle();
tabRuns = new int[10];
@@ -1585,9 +1654,10 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
lightHighlight = null;
highlight = null;
- tabPane.setBackground(null);
- tabPane.setForeground(null);
- tabPane.setFont(null);
+ // Install UI colors and fonts.
+ LookAndFeel.installColorsAndFont(tabPane, "TabbedPane.background",
+ "TabbedPane.foreground",
+ "TabbedPane.font");
}
/**
@@ -1666,6 +1736,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
* This method installs keyboard actions for the JTabbedPane.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Implement.
}
@@ -1674,6 +1745,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
* This method uninstalls keyboard actions for the JTabbedPane.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Implement.
}
@@ -1710,6 +1782,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
public void paint(Graphics g, JComponent c)
{
+ if (!tabPane.isValid())
+ tabPane.validate();
+
if (tabPane.getTabCount() == 0)
return;
if (tabPane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT)
@@ -1735,42 +1810,26 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
// Please note: the ordering of the painting is important.
// we WANT to paint the outermost run first and then work our way in.
int tabCount = tabPane.getTabCount();
- int currRun = 1;
-
- if (tabCount < 1)
- return;
-
- if (runCount > 1)
- currRun = 0;
- for (int i = 0; i < runCount; i++)
+ for (int i = runCount - 1; i >= 0; --i)
{
- int first = lastTabInRun(tabCount, getPreviousTabRun(currRun)) + 1;
- if (isScroll)
- first = currentScrollLocation;
- else if (first == tabCount)
- first = 0;
- int last = lastTabInRun(tabCount, currRun);
- if (isScroll)
+ int start = tabRuns[i];
+ int next;
+ if (i == runCount - 1)
+ next = tabRuns[0];
+ else
+ next = tabRuns[i + 1];
+ int end = (next != 0 ? next - 1 : tabCount - 1);
+ for (int j = start; j <= end; ++j)
{
- for (int k = first; k < tabCount; k++)
+ if (j != selectedIndex)
{
- if (rects[k].x + rects[k].width - rects[first].x > viewport
- .getWidth())
- {
- last = k;
- break;
- }
+ paintTab(g, tabPlacement, rects, j, ir, tr);
}
}
-
- for (int j = first; j <= last; j++)
- {
- if (j != selectedIndex || isScroll)
- paintTab(g, tabPlacement, rects, j, ir, tr);
- }
- currRun = getPreviousTabRun(currRun);
}
- if (! isScroll)
+
+ // Paint selected tab in front of every other tab.
+ if (selectedIndex >= 0)
paintTab(g, tabPlacement, rects, selectedIndex, ir, tr);
}
@@ -1788,49 +1847,34 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
protected void paintTab(Graphics g, int tabPlacement, Rectangle[] rects,
int tabIndex, Rectangle iconRect, Rectangle textRect)
{
- FontMetrics fm = getFontMetrics();
- Icon icon = getIconForTab(tabIndex);
- String title = tabPane.getTitleAt(tabIndex);
+ Rectangle rect = rects[tabIndex];
boolean isSelected = tabIndex == tabPane.getSelectedIndex();
- calcRect = getTabBounds(tabPane, tabIndex);
-
- int x = calcRect.x;
- int y = calcRect.y;
- int w = calcRect.width;
- int h = calcRect.height;
- if (getRunForTab(tabPane.getTabCount(), tabIndex) == 1)
+ // Paint background if necessary.
+ if (tabsOpaque || tabPane.isOpaque())
{
- Insets insets = getTabAreaInsets(tabPlacement);
- switch (tabPlacement)
- {
- case TOP:
- h += insets.bottom;
- break;
- case LEFT:
- w += insets.right;
- break;
- case BOTTOM:
- y -= insets.top;
- h += insets.top;
- break;
- case RIGHT:
- x -= insets.left;
- w += insets.left;
- break;
- }
+ paintTabBackground(g, tabPlacement, tabIndex, rect.x, rect.y,
+ rect.width, rect.height, isSelected);
}
- layoutLabel(tabPlacement, fm, tabIndex, title, icon, calcRect, iconRect,
- textRect, isSelected);
- paintTabBackground(g, tabPlacement, tabIndex, x, y, w, h, isSelected);
- paintTabBorder(g, tabPlacement, tabIndex, x, y, w, h, isSelected);
+ // Paint border.
+ paintTabBorder(g, tabPlacement, tabIndex, rect.x, rect.y, rect.width,
+ rect.height, isSelected);
- // FIXME: Paint little folding corner and jagged edge clipped tab.
- if (icon != null)
- paintIcon(g, tabPlacement, tabIndex, icon, iconRect, isSelected);
- if (title != null && ! title.equals(""))
- paintText(g, tabPlacement, tabPane.getFont(), fm, tabIndex, title,
+
+ // Layout label.
+ FontMetrics fm = getFontMetrics();
+ Icon icon = getIconForTab(tabIndex);
+ String title = tabPane.getTitleAt(tabIndex);
+ layoutLabel(tabPlacement, fm, tabIndex, title, icon, rect, iconRect,
textRect, isSelected);
+ // 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);
}
/**
@@ -1902,6 +1946,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
FontMetrics metrics, int tabIndex, String title,
Rectangle textRect, boolean isSelected)
{
+ g.setFont(font);
View textView = getTextViewForTab(tabIndex);
if (textView != null)
{
@@ -1909,54 +1954,48 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
return;
}
- Color fg = tabPane.getForegroundAt(tabIndex);
- if (fg == null)
- fg = tabPane.getForeground();
- Color bg = tabPane.getBackgroundAt(tabIndex);
- if (bg == null)
- bg = tabPane.getBackground();
-
- Color saved_color = g.getColor();
- Font f = g.getFont();
- g.setFont(font);
+ int ascent = metrics.getAscent();
- if (tabPane.isEnabledAt(tabIndex))
+ int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex);
+ if (tabPane.isEnabled() && tabPane.isEnabledAt(tabIndex))
{
+ Color fg = tabPane.getForegroundAt(tabIndex);
+ if (isSelected && (fg instanceof UIResource))
+ {
+ Color selectionForeground =
+ UIManager.getColor("TabbedPane.selectionForeground");
+ if (selectionForeground != null)
+ fg = selectionForeground;
+ }
g.setColor(fg);
- int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex);
-
if (mnemIndex != -1)
BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
textRect.x,
- textRect.y
- + metrics.getAscent());
+ textRect.y + ascent);
else
- g.drawString(title, textRect.x, textRect.y + metrics.getAscent());
+ g.drawString(title, textRect.x, textRect.y + ascent);
}
else
{
+ Color bg = tabPane.getBackgroundAt(tabIndex);
g.setColor(bg.brighter());
-
- int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex);
-
if (mnemIndex != -1)
BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
- textRect.x, textRect.y);
+ textRect.x, textRect.y
+ + ascent);
else
- g.drawString(title, textRect.x, textRect.y);
+ g.drawString(title, textRect.x, textRect.y + ascent);
g.setColor(bg.darker());
if (mnemIndex != -1)
BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
textRect.x + 1,
- textRect.y + 1);
+ textRect.y + 1
+ + ascent);
else
- g.drawString(title, textRect.x + 1, textRect.y + 1);
+ g.drawString(title, textRect.x + 1, textRect.y + 1 + ascent);
}
-
- g.setColor(saved_color);
- g.setFont(f);
}
/**
@@ -2009,14 +2048,45 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
Rectangle iconRect, Rectangle textRect,
boolean isSelected)
{
- Color saved = g.getColor();
- calcRect = iconRect.union(textRect);
-
- g.setColor(focus);
-
- g.drawRect(calcRect.x, calcRect.y, calcRect.width, calcRect.height);
-
- g.setColor(saved);
+ if (tabPane.hasFocus() && isSelected)
+ {
+ Rectangle rect = rects[tabIndex];
+ // The focus rectangle.
+ int x;
+ int y;
+ int w;
+ int h;
+
+ 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;
+ }
+ BasicGraphicsUtils.drawDashedRect(g, x, y, w, h);
+ }
}
/**
@@ -2109,10 +2179,44 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
protected void paintContentBorder(Graphics g, int tabPlacement,
int selectedIndex)
{
- int x = contentRect.x;
- int y = contentRect.y;
- int w = contentRect.width;
- int h = contentRect.height;
+ int width = tabPane.getWidth();
+ int height = tabPane.getHeight();
+ Insets insets = tabPane.getInsets();
+ Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
+
+ // Calculate coordinates of content area.
+ int x = insets.left;
+ int y = insets.top;
+ int w = width - insets.left - insets.right;
+ int h = height - insets.top - insets.bottom;
+
+ switch (tabPlacement)
+ {
+ case LEFT:
+ x += calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth);
+ w -= (x - insets.left);
+ break;
+ case RIGHT:
+ w -= calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth);
+ break;
+ case BOTTOM:
+ h -= calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight);
+ break;
+ case TOP:
+ default:
+ y += calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight);
+ h -= (y - insets.top);
+ }
+
+ // Fill background if necessary.
+ if (tabPane.isOpaque())
+ {
+ Color bg = UIManager.getColor("TabbedPane.contentAreaColor");
+ g.setColor(bg);
+ g.fillRect(x, y, w, h);
+ }
+
+ // Paint border.
paintContentBorderTopEdge(g, tabPlacement, selectedIndex, x, y, w, h);
paintContentBorderLeftEdge(g, tabPlacement, selectedIndex, x, y, w, h);
paintContentBorderBottomEdge(g, tabPlacement, selectedIndex, x, y, w, h);
@@ -2332,23 +2436,23 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
public int tabForCoordinate(JTabbedPane pane, int x, int y)
{
- Point p = new Point(x, y);
+ if (! tabPane.isValid())
+ tabPane.validate();
+
int tabCount = tabPane.getTabCount();
- int currRun = 1;
- for (int i = 0; i < runCount; i++)
+ int index = -1;
+ for (int i = 0; i < tabCount; ++i)
{
- int first = lastTabInRun(tabCount, getPreviousTabRun(currRun)) + 1;
- if (first == tabCount)
- first = 0;
- int last = lastTabInRun(tabCount, currRun);
- for (int j = first; j <= last; j++)
+ if (rects[i].contains(x, y))
{
- if (getTabBounds(pane, j).contains(p))
- return j;
+ index = i;
+ break;
}
- currRun = getNextTabRun(currRun);
}
- return -1;
+
+ // FIXME: Handle scrollable tab layout.
+
+ return index;
}
/**
@@ -2455,10 +2559,23 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
protected int lastTabInRun(int tabCount, int run)
{
- if (tabRuns[run] == 0)
- return tabCount - 1;
+ int lastTab;
+ if (runCount == 1)
+ lastTab = tabCount - 1;
else
- return tabRuns[run] - 1;
+ {
+ int nextRun;
+ if (run == runCount - 1)
+ nextRun = 0;
+ else
+ nextRun = run + 1;
+
+ if (tabRuns[nextRun] == 0)
+ lastTab = tabCount - 1;
+ else
+ lastTab = tabRuns[nextRun] - 1;
+ }
+ return lastTab;
}
/**
@@ -2554,24 +2671,14 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
protected int calculateTabHeight(int tabPlacement, int tabIndex,
int fontHeight)
{
- Icon icon = getIconForTab(tabIndex);
- Insets insets = getTabInsets(tabPlacement, tabIndex);
+ // FIXME: Handle HTML somehow.
- int height = 0;
+ int height = fontHeight;
+ Icon icon = getIconForTab(tabIndex);
+ Insets tabInsets = getTabInsets(tabPlacement, tabIndex);
if (icon != null)
- {
- Rectangle vr = new Rectangle();
- Rectangle ir = new Rectangle();
- Rectangle tr = new Rectangle();
- layoutLabel(tabPlacement, getFontMetrics(), tabIndex,
- tabPane.getTitleAt(tabIndex), icon, vr, ir, tr,
- tabIndex == tabPane.getSelectedIndex());
- height = tr.union(ir).height;
- }
- else
- height = fontHeight;
-
- height += insets.top + insets.bottom;
+ height = Math.max(height, icon.getIconHeight());
+ height += tabInsets.top + tabInsets.bottom + 2;
return height;
}
@@ -2704,9 +2811,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
protected Insets getTabInsets(int tabPlacement, int tabIndex)
{
- Insets target = new Insets(0, 0, 0, 0);
- rotateInsets(tabInsets, target, tabPlacement);
- return target;
+ return tabInsets;
}
/**
@@ -3068,4 +3173,33 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
break;
}
}
+
+ /**
+ * Sets the tab which should be highlighted when in rollover mode. And
+ * <code>index</code> of <code>-1</code> means that the rollover tab
+ * is deselected (i.e. the mouse is outside of the tabarea).
+ *
+ * @param index the index of the tab that is under the mouse, <code>-1</code>
+ * for no tab
+ *
+ * @since 1.5
+ */
+ protected void setRolloverTab(int index)
+ {
+ rolloverTab = index;
+ }
+
+ /**
+ * Retunrs the index of the tab over which the mouse is currently moving,
+ * or <code>-1</code> for no tab.
+ *
+ * @return the index of the tab over which the mouse is currently moving,
+ * or <code>-1</code> for no tab
+ *
+ * @since 1.5
+ */
+ protected int getRolloverTab()
+ {
+ return rolloverTab;
+ }
}