Imported GNU Classpath 0.20
[official-gcc.git] / libjava / classpath / javax / swing / plaf / metal / MetalTabbedPaneUI.java
blobc6c46ffe6145553892fb3f1a40b66b9453a040e8
1 /* MetalTabbedPaneUI.java
2 Copyright (C) 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing.plaf.metal;
41 import java.awt.Color;
42 import java.awt.Graphics;
43 import java.awt.LayoutManager;
44 import java.awt.Rectangle;
46 import javax.swing.JComponent;
47 import javax.swing.JTabbedPane;
48 import javax.swing.UIManager;
49 import javax.swing.plaf.ComponentUI;
50 import javax.swing.plaf.basic.BasicTabbedPaneUI;
52 /**
53 * A UI delegate for the {@link JTabbedPane} component.
55 public class MetalTabbedPaneUI extends BasicTabbedPaneUI
58 /**
59 * A {@link LayoutManager} responsible for placing all the tabs and the
60 * visible component inside the {@link JTabbedPane}. This class is only used
61 * for {@link JTabbedPane#WRAP_TAB_LAYOUT}.
63 * @specnote Apparently this class was intended to be protected,
64 * but was made public by a compiler bug and is now
65 * public for compatibility.
67 public class TabbedPaneLayout
68 extends BasicTabbedPaneUI.TabbedPaneLayout
70 /**
71 * Creates a new instance of the layout manager.
73 public TabbedPaneLayout()
75 // Nothing to do here.
78 /**
79 * Overridden to do nothing, because tab runs are not rotated in the
80 * {@link MetalLookAndFeel}.
82 * @param tabPlacement the tab placement (one of {@link #TOP},
83 * {@link #BOTTOM}, {@link #LEFT} or {@link #RIGHT}).
84 * @param selectedRun the index of the selected run.
86 protected void rotateTabRuns(int tabPlacement, int selectedRun)
88 // do nothing, because tab runs are not rotated in the MetalLookAndFeel
91 /**
92 * Overridden to do nothing, because the selected tab does not have extra
93 * padding in the {@link MetalLookAndFeel}.
95 * @param tabPlacement the tab placement (one of {@link #TOP},
96 * {@link #BOTTOM}, {@link #LEFT} or {@link #RIGHT}).
97 * @param selectedIndex the index of the selected tab.
99 protected void padSelectedTab(int tabPlacement, int selectedIndex)
101 // do nothing, because the selected tab does not have extra padding in
102 // the MetalLookAndFeel
107 * The minimum tab width.
109 protected int minTabWidth;
112 * The color for the selected tab.
114 protected Color selectColor;
117 * The color for a highlighted selected tab.
119 protected Color selectHighlight;
122 * The background color used for the tab area.
124 protected Color tabAreaBackground;
126 /** The graphics to draw the highlight below the tab. */
127 private Graphics hg;
130 * Constructs a new instance of MetalTabbedPaneUI.
132 public MetalTabbedPaneUI()
134 super();
138 * Returns an instance of MetalTabbedPaneUI.
140 * @param component the component for which we return an UI instance
142 * @return an instance of MetalTabbedPaneUI
144 public static ComponentUI createUI(JComponent component)
146 return new MetalTabbedPaneUI();
150 * Creates and returns an instance of {@link TabbedPaneLayout}.
152 * @return A layout manager used by this UI delegate.
154 protected LayoutManager createLayoutManager()
156 return super.createLayoutManager();
160 * Paints the border for a single tab.
162 * @param g the graphics device.
163 * @param tabPlacement the tab placement ({@link #TOP}, {@link #LEFT},
164 * {@link #BOTTOM} or {@link #RIGHT}).
165 * @param tabIndex the index of the tab to draw the border for.
166 * @param x the x-coordinate for the tab's bounding rectangle.
167 * @param y the y-coordinate for the tab's bounding rectangle.
168 * @param w the width for the tab's bounding rectangle.
169 * @param h the height for the tab's bounding rectangle.
170 * @param isSelected indicates whether or not the tab is selected.
172 protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex,
173 int x, int y, int w, int h, boolean isSelected)
175 if (tabPlacement == TOP)
176 paintTopTabBorder(tabIndex, g, x, y, w, h, 0, 0, isSelected);
177 else if (tabPlacement == LEFT)
178 paintLeftTabBorder(tabIndex, g, x, y, w, h, 0, 0, isSelected);
179 else if (tabPlacement == BOTTOM)
180 paintBottomTabBorder(tabIndex, g, x, y, w, h, 0, 0, isSelected);
181 else if (tabPlacement == RIGHT)
182 paintRightTabBorder(tabIndex, g, x, y, w, h, 0, 0, isSelected);
183 else
184 throw new AssertionError("Unrecognised 'tabPlacement' argument.");
188 * Paints the border for a tab assuming that the tab position is at the top
189 * ({@link #TOP}).
191 * @param tabIndex the tab index.
192 * @param g the graphics device.
193 * @param x the x-coordinate for the tab's bounding rectangle.
194 * @param y the y-coordinate for the tab's bounding rectangle.
195 * @param w the width for the tab's bounding rectangle.
196 * @param h the height for the tab's bounding rectangle.
197 * @param btm ???
198 * @param rght ???
199 * @param isSelected indicates whether the tab is selected.
201 protected void paintTopTabBorder(int tabIndex, Graphics g, int x, int y,
202 int w, int h, int btm, int rght, boolean isSelected)
204 int currentRun = getRunForTab(tabPane.getTabCount(), tabIndex);
205 if (shouldFillGap(currentRun, tabIndex, x, y))
207 g.translate(x, y);
208 g.setColor(getColorForGap(currentRun, x, y));
209 g.fillRect(1, 0, 5, 3);
210 g.fillRect(1, 3, 2, 2);
211 g.translate(-x, -y);
214 if (isSelected)
216 g.setColor(MetalLookAndFeel.getControlHighlight());
217 g.drawLine(x + 1, y + h, x + 1, y + 6);
218 g.drawLine(x + 1, y + 6, x + 6, y + 1);
219 g.drawLine(x + 6, y + 1, x + w - 1, y + 1);
221 g.setColor(MetalLookAndFeel.getControlDarkShadow());
222 g.drawLine(x, y + h - 1, x, y + 6);
223 g.drawLine(x, y + 6, x + 6, y);
224 g.drawLine(x + 6, y, x + w, y);
225 g.drawLine(x + w, y, x + w, y + h - 1);
229 * Paints the border for a tab assuming that the tab position is at the left
230 * ({@link #LEFT}).
232 * @param tabIndex the tab index.
233 * @param g the graphics device.
234 * @param x the x-coordinate for the tab's bounding rectangle.
235 * @param y the y-coordinate for the tab's bounding rectangle.
236 * @param w the width for the tab's bounding rectangle.
237 * @param h the height for the tab's bounding rectangle.
238 * @param btm ???
239 * @param rght ???
240 * @param isSelected indicates whether the tab is selected.
242 protected void paintLeftTabBorder(int tabIndex, Graphics g, int x, int y,
243 int w, int h, int btm, int rght, boolean isSelected)
245 if (isSelected)
247 g.setColor(MetalLookAndFeel.getControlHighlight());
248 g.drawLine(x + 1, y + h, x + 1, y + 6);
249 g.drawLine(x + 1, y + 6, x + 6, y + 1);
250 g.drawLine(x + 6, y + 1, x + w - 1, y + 1);
252 g.setColor(MetalLookAndFeel.getControlDarkShadow());
253 g.drawLine(x, y + h, x, y + 6);
254 g.drawLine(x, y + 6, x + 6, y);
255 g.drawLine(x + 6, y, x + w - 1, y);
256 g.drawLine(x, y + h, x + w - 1, y + h);
260 * Paints the border for a tab assuming that the tab position is at the right
261 * ({@link #RIGHT}).
263 * @param tabIndex the tab index.
264 * @param g the graphics device.
265 * @param x the x-coordinate for the tab's bounding rectangle.
266 * @param y the y-coordinate for the tab's bounding rectangle.
267 * @param w the width for the tab's bounding rectangle.
268 * @param h the height for the tab's bounding rectangle.
269 * @param btm ???
270 * @param rght ???
271 * @param isSelected indicates whether the tab is selected.
273 protected void paintRightTabBorder(int tabIndex, Graphics g, int x, int y,
274 int w, int h, int btm, int rght, boolean isSelected)
276 if (isSelected)
278 g.setColor(MetalLookAndFeel.getControlHighlight());
279 g.drawLine(x, y + 1, x + w - 7, y + 1);
280 g.drawLine(x + w - 7, y + 1, x + w - 1, y + 7);
282 g.setColor(MetalLookAndFeel.getControlDarkShadow());
283 g.drawLine(x, y, x + w - 7, y);
284 g.drawLine(x + w - 7, y, x + w - 1, y + 6);
285 g.drawLine(x + w - 1, y + 6, x + w - 1, y + h - 1);
286 g.drawLine(x + w - 1, y + h, x, y + h);
290 * Paints the border for a tab assuming that the tab position is at the bottom
291 * ({@link #BOTTOM}).
293 * @param tabIndex the tab index.
294 * @param g the graphics device.
295 * @param x the x-coordinate for the tab's bounding rectangle.
296 * @param y the y-coordinate for the tab's bounding rectangle.
297 * @param w the width for the tab's bounding rectangle.
298 * @param h the height for the tab's bounding rectangle.
299 * @param btm ???
300 * @param rght ???
301 * @param isSelected indicates whether the tab is selected.
303 protected void paintBottomTabBorder(int tabIndex, Graphics g, int x, int y,
304 int w, int h, int btm, int rght, boolean isSelected)
306 int currentRun = getRunForTab(tabPane.getTabCount(), tabIndex);
307 if (shouldFillGap(currentRun, tabIndex, x, y))
309 g.translate(x, y);
310 g.setColor(getColorForGap(currentRun, x, y));
311 g.fillRect(1, h - 5, 3, 5);
312 g.fillRect(4, h - 2, 2, 2);
313 g.translate(-x, -y);
316 if (isSelected)
318 g.setColor(MetalLookAndFeel.getControlHighlight());
319 g.drawLine(x + 1, y, x + 1, y + h - 7);
320 g.drawLine(x + 1, y + h - 7, x + 7, y + h - 1);
322 g.setColor(MetalLookAndFeel.getControlDarkShadow());
323 g.drawLine(x, y, x, y + h - 7);
324 g.drawLine(x, y + h - 7, x + 6, y + h - 1);
325 g.drawLine(x + 6, y + h - 1, x + w, y + h - 1);
326 g.drawLine(x + w, y + h - 1, x + w, y);
330 * Paints the background for a tab.
332 * @param g the graphics device.
333 * @param tabPlacement the tab placement ({@link #TOP}, {@link #LEFT},
334 * {@link #BOTTOM} or {@link #RIGHT}).
335 * @param tabIndex the index of the tab to draw the border for.
336 * @param x the x-coordinate for the tab's bounding rectangle.
337 * @param y the y-coordinate for the tab's bounding rectangle.
338 * @param w the width for the tab's bounding rectangle.
339 * @param h the height for the tab's bounding rectangle.
340 * @param isSelected indicates whether or not the tab is selected.
342 protected void paintTabBackground(Graphics g, int tabPlacement,
343 int tabIndex, int x, int y, int w, int h, boolean isSelected)
345 if (isSelected)
346 g.setColor(UIManager.getColor("TabbedPane.selected"));
347 else
349 // This is only present in the OceanTheme, so we must check if it
350 // is actually there
351 Color background = UIManager.getColor("TabbedPane.unselectedBackground");
352 if (background == null)
353 background = UIManager.getColor("TabbedPane.background");
354 g.setColor(background);
356 int[] px, py;
357 if (tabPlacement == TOP)
359 px = new int[] {x + 6, x + w - 1, x + w -1, x + 2, x + 2};
360 py = new int[] {y + 2, y + 2, y + h - 1, y + h -1, y + 6};
362 else if (tabPlacement == LEFT)
364 px = new int[] {x + 6, x + w - 1, x + w -1, x + 2, x + 2};
365 py = new int[] {y + 2, y + 2, y + h - 1, y + h -1, y + 6};
367 else if (tabPlacement == BOTTOM)
369 px = new int[] {x + 2, x + w - 1, x + w -1, x + 8, x + 2};
370 py = new int[] {y, y, y + h - 1, y + h -1, y + h - 7};
372 else if (tabPlacement == RIGHT)
374 px = new int[] {x + 2, x + w - 7, x + w - 1, x + w - 1, x + 2};
375 py = new int[] {y + 2, y + 2, y + 7, y + h -1, y + h - 1};
377 else
378 throw new AssertionError("Unrecognised 'tabPlacement' argument.");
379 g.fillPolygon(px, py, 5);
380 hg = g;
381 paintHighlightBelowTab();
385 * Returns <code>true</code> if the tabs in the specified run should be
386 * padded to make the run fill the width/height of the {@link JTabbedPane}.
388 * @param tabPlacement the tab placement for the {@link JTabbedPane} (one of
389 * {@link #TOP}, {@link #BOTTOM}, {@link #LEFT} and {@link #RIGHT}).
390 * @param run the run index.
392 * @return A boolean.
394 protected boolean shouldPadTabRun(int tabPlacement, int run)
396 // as far as I can tell, all runs should be padded except the last run
397 // (which is drawn at the very top for tabPlacement == TOP)
398 return run < this.runCount - 1;
402 * Installs the defaults for this UI. This method calls super.installDefaults
403 * and then loads the Metal specific defaults for TabbedPane.
405 protected void installDefaults()
407 super.installDefaults();
408 selectColor = UIManager.getColor("TabbedPane.selected");
409 selectHighlight = UIManager.getColor("TabbedPane.selectHighlight");
410 tabAreaBackground = UIManager.getColor("TabbedPane.tabAreaBackground");
411 minTabWidth = 0;
415 * Returns the color for the gap.
417 * @param currentRun - The current run to return the color for
418 * @param x - The x position of the current run
419 * @param y - The y position of the current run
421 * @return the color for the gap in the current run.
423 protected Color getColorForGap(int currentRun, int x, int y)
425 int index = tabForCoordinate(tabPane, x, y);
426 int selected = tabPane.getSelectedIndex();
427 if (selected == index)
428 return selectColor;
429 return tabAreaBackground;
433 * Returns true if the gap should be filled in.
435 * @param currentRun - The current run
436 * @param tabIndex - The current tab
437 * @param x - The x position of the tab
438 * @param y - The y position of the tab
440 * @return true if the gap at the current run should be filled
442 protected boolean shouldFillGap(int currentRun, int tabIndex, int x, int y)
444 // As far as I can tell, the gap is never filled in.
445 return false;
449 * Paints the highlight below the tab, if there is one.
451 protected void paintHighlightBelowTab()
453 int selected = tabPane.getSelectedIndex();
454 int tabPlacement = tabPane.getTabPlacement();
455 Rectangle bounds = getTabBounds(tabPane, selected);
457 hg.setColor(selectColor);
458 int x = bounds.x;
459 int y = bounds.y;
460 int w = bounds.width;
461 int h = bounds.height;
463 if (tabPlacement == TOP)
464 hg.fillRect(x, y + h - 2, w, 30);
465 else if (tabPlacement == LEFT)
466 hg.fillRect(x + w - 1, y, 20, h);
467 else if (tabPlacement == BOTTOM)
468 hg.fillRect(x, y - h + 2, w, 30);
469 else if (tabPlacement == RIGHT)
470 hg.fillRect(x - 18, y, 20, h);
471 else
472 throw new AssertionError("Unrecognised 'tabPlacement' argument.");
473 hg = null;
477 * Returns true if we should rotate the tab runs.
479 * @param tabPlacement - The current tab placement.
480 * @param selectedRun - The selected run.
482 * @return true if the tab runs should be rotated.
484 protected boolean shouldRotateTabRuns(int tabPlacement,
485 int selectedRun)
487 // false because tab runs are not rotated in the MetalLookAndFeel
488 return false;