Source for javax.swing.plaf.metal.MetalTabbedPaneUI

   1: /* MetalTabbedPaneUI.java
   2:    Copyright (C) 2005 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   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.
  10: 
  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.
  15: 
  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.
  20: 
  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.
  25: 
  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. */
  37: 
  38: 
  39: package javax.swing.plaf.metal;
  40: 
  41: import java.awt.Graphics;
  42: import java.awt.LayoutManager;
  43: 
  44: import javax.swing.JComponent;
  45: import javax.swing.JTabbedPane;
  46: import javax.swing.plaf.ComponentUI;
  47: import javax.swing.plaf.basic.BasicTabbedPaneUI;
  48: 
  49: /**
  50:  * A UI delegate for the {@link JTabbedPane} component.
  51:  */
  52: public class MetalTabbedPaneUI extends BasicTabbedPaneUI
  53: {
  54: 
  55:   /**
  56:    * A {@link LayoutManager} responsible for placing all the tabs and the 
  57:    * visible component inside the {@link JTabbedPane}. This class is only used 
  58:    * for {@link JTabbedPane#WRAP_TAB_LAYOUT}.
  59:    *
  60:    * @specnote Apparently this class was intended to be protected,
  61:    *           but was made public by a compiler bug and is now
  62:    *           public for compatibility.
  63:    */
  64:   public class TabbedPaneLayout 
  65:     extends BasicTabbedPaneUI.TabbedPaneLayout
  66:   {
  67:     /**
  68:      * Creates a new instance of the layout manager.
  69:      */
  70:     public TabbedPaneLayout()
  71:     {
  72:       // Nothing to do here.
  73:     }
  74:     
  75:     /**
  76:      * Overridden to do nothing, because tab runs are not rotated in the 
  77:      * {@link MetalLookAndFeel}.
  78:      * 
  79:      * @param tabPlacement  the tab placement (one of {@link #TOP}, 
  80:      *        {@link #BOTTOM}, {@link #LEFT} or {@link #RIGHT}).
  81:      * @param selectedRun  the index of the selected run.
  82:      */
  83:     protected void rotateTabRuns(int tabPlacement, int selectedRun)
  84:     {
  85:       // do nothing, because tab runs are not rotated in the MetalLookAndFeel
  86:     }
  87:     
  88:     /**
  89:      * Overridden to do nothing, because the selected tab does not have extra
  90:      * padding in the {@link MetalLookAndFeel}.
  91:      * 
  92:      * @param tabPlacement  the tab placement (one of {@link #TOP}, 
  93:      *        {@link #BOTTOM}, {@link #LEFT} or {@link #RIGHT}).
  94:      * @param selectedIndex  the index of the selected tab.
  95:      */
  96:     protected void padSelectedTab(int tabPlacement, int selectedIndex)
  97:     {
  98:       // do nothing, because the selected tab does not have extra padding in 
  99:       // the MetalLookAndFeel
 100:     }
 101:   }
 102: 
 103:   /**
 104:    * Constructs a new instance of MetalTabbedPaneUI.
 105:    */
 106:   public MetalTabbedPaneUI()
 107:   {
 108:     super();
 109:   }
 110: 
 111:   /**
 112:    * Returns an instance of MetalTabbedPaneUI.
 113:    *
 114:    * @param component the component for which we return an UI instance
 115:    *
 116:    * @return an instance of MetalTabbedPaneUI
 117:    */
 118:   public static ComponentUI createUI(JComponent component)
 119:   {
 120:     return new MetalTabbedPaneUI();
 121:   }
 122:   
 123:   /**
 124:    * Creates and returns an instance of {@link TabbedPaneLayout}.
 125:    * 
 126:    * @return A layout manager used by this UI delegate.
 127:    */
 128:   protected LayoutManager createLayoutManager()
 129:   {
 130:     return super.createLayoutManager();
 131:   }
 132:   
 133:   /**
 134:    * Paints the border for a single tab.
 135:    * 
 136:    * @param g  the graphics device.
 137:    * @param tabPlacement  the tab placement ({@link #TOP}, {@link #LEFT}, 
 138:    *        {@link #BOTTOM} or {@link #RIGHT}).
 139:    * @param tabIndex  the index of the tab to draw the border for.
 140:    * @param x  the x-coordinate for the tab's bounding rectangle.
 141:    * @param y  the y-coordinate for the tab's bounding rectangle.
 142:    * @param w  the width for the tab's bounding rectangle.
 143:    * @param h  the height for the tab's bounding rectangle.
 144:    * @param isSelected  indicates whether or not the tab is selected.
 145:    */
 146:   protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, 
 147:           int x, int y, int w, int h, boolean isSelected) 
 148:   {
 149:     if (tabPlacement == TOP)
 150:       paintTopTabBorder(tabIndex, g, x, y, w, h, 0, 0, isSelected);
 151:     else if (tabPlacement == LEFT) 
 152:       paintLeftTabBorder(tabIndex, g, x, y, w, h, 0, 0, isSelected);
 153:     else if (tabPlacement == BOTTOM)
 154:       paintBottomTabBorder(tabIndex, g, x, y, w, h, 0, 0, isSelected);
 155:     else if (tabPlacement == RIGHT)
 156:       paintRightTabBorder(tabIndex, g, x, y, w, h, 0, 0, isSelected);
 157:     else 
 158:       throw new AssertionError("Unrecognised 'tabPlacement' argument.");
 159:   }
 160: 
 161:   /**
 162:    * Paints the border for a tab assuming that the tab position is at the top
 163:    * ({@link #TOP}).
 164:    * 
 165:    * @param tabIndex  the tab index.
 166:    * @param g  the graphics device.
 167:    * @param x  the x-coordinate for the tab's bounding rectangle.
 168:    * @param y  the y-coordinate for the tab's bounding rectangle.
 169:    * @param w  the width for the tab's bounding rectangle.
 170:    * @param h  the height for the tab's bounding rectangle.
 171:    * @param btm  ???
 172:    * @param rght  ???
 173:    * @param isSelected  indicates whether the tab is selected.
 174:    */
 175:   protected void paintTopTabBorder(int tabIndex, Graphics g, int x, int y,
 176:       int w, int h, int btm, int rght, boolean isSelected)
 177:   {
 178:     if (isSelected)
 179:     {
 180:       g.setColor(MetalLookAndFeel.getControlHighlight());
 181:       g.drawLine(x + 1, y + h, x + 1, y + 6);      
 182:       g.drawLine(x + 1, y + 6, x + 6, y + 1);
 183:       g.drawLine(x + 6, y + 1, x + w - 1, y + 1);
 184:     }
 185:     g.setColor(MetalLookAndFeel.getControlDarkShadow());
 186:     g.drawLine(x, y + h - 1, x, y + 6);
 187:     g.drawLine(x, y + 6, x + 6, y);
 188:     g.drawLine(x + 6, y, x + w, y);
 189:     g.drawLine(x + w, y, x + w, y + h - 1);
 190:   }
 191:   
 192:   /**
 193:    * Paints the border for a tab assuming that the tab position is at the left
 194:    * ({@link #LEFT}).
 195:    * 
 196:    * @param tabIndex  the tab index.
 197:    * @param g  the graphics device.
 198:    * @param x  the x-coordinate for the tab's bounding rectangle.
 199:    * @param y  the y-coordinate for the tab's bounding rectangle.
 200:    * @param w  the width for the tab's bounding rectangle.
 201:    * @param h  the height for the tab's bounding rectangle.
 202:    * @param btm  ???
 203:    * @param rght  ???
 204:    * @param isSelected  indicates whether the tab is selected.
 205:    */
 206:   protected void paintLeftTabBorder(int tabIndex, Graphics g, int x, int y,
 207:       int w, int h, int btm, int rght, boolean isSelected)
 208:   {
 209:     if (isSelected)
 210:     {
 211:       g.setColor(MetalLookAndFeel.getControlHighlight());
 212:       g.drawLine(x + 1, y + h, x + 1, y + 6);      
 213:       g.drawLine(x + 1, y + 6, x + 6, y + 1);
 214:       g.drawLine(x + 6, y + 1, x + w - 1, y + 1);
 215:     }
 216:     g.setColor(MetalLookAndFeel.getControlDarkShadow());
 217:     g.drawLine(x, y + h, x, y + 6);
 218:     g.drawLine(x, y + 6, x + 6, y);
 219:     g.drawLine(x + 6, y, x + w - 1, y);
 220:     g.drawLine(x, y + h, x + w - 1, y + h);
 221:   }
 222:   
 223:   /**
 224:    * Paints the border for a tab assuming that the tab position is at the right
 225:    * ({@link #RIGHT}).
 226:    * 
 227:    * @param tabIndex  the tab index.
 228:    * @param g  the graphics device.
 229:    * @param x  the x-coordinate for the tab's bounding rectangle.
 230:    * @param y  the y-coordinate for the tab's bounding rectangle.
 231:    * @param w  the width for the tab's bounding rectangle.
 232:    * @param h  the height for the tab's bounding rectangle.
 233:    * @param btm  ???
 234:    * @param rght  ???
 235:    * @param isSelected  indicates whether the tab is selected.
 236:    */
 237:   protected void paintRightTabBorder(int tabIndex, Graphics g, int x, int y,
 238:       int w, int h, int btm, int rght, boolean isSelected)
 239:   {
 240:     if (isSelected)
 241:     {
 242:       g.setColor(MetalLookAndFeel.getControlHighlight());
 243:       g.drawLine(x, y + 1, x + w - 7, y + 1);      
 244:       g.drawLine(x + w - 7, y + 1, x + w - 1, y + 7);
 245:     }
 246:     g.setColor(MetalLookAndFeel.getControlDarkShadow());
 247:     g.drawLine(x, y, x + w - 7, y);
 248:     g.drawLine(x + w - 7, y, x + w - 1, y + 6);
 249:     g.drawLine(x + w - 1, y + 6, x + w - 1, y + h - 1);
 250:     g.drawLine(x + w - 1, y + h, x, y + h);
 251:   }
 252:   
 253:   /**
 254:    * Paints the border for a tab assuming that the tab position is at the bottom
 255:    * ({@link #BOTTOM}).
 256:    * 
 257:    * @param tabIndex  the tab index.
 258:    * @param g  the graphics device.
 259:    * @param x  the x-coordinate for the tab's bounding rectangle.
 260:    * @param y  the y-coordinate for the tab's bounding rectangle.
 261:    * @param w  the width for the tab's bounding rectangle.
 262:    * @param h  the height for the tab's bounding rectangle.
 263:    * @param btm  ???
 264:    * @param rght  ???
 265:    * @param isSelected  indicates whether the tab is selected.
 266:    */
 267:   protected void paintBottomTabBorder(int tabIndex, Graphics g, int x, int y,
 268:       int w, int h, int btm, int rght, boolean isSelected)
 269:   {
 270:     if (isSelected)
 271:     {
 272:       g.setColor(MetalLookAndFeel.getControlHighlight());
 273:       g.drawLine(x + 1, y, x + 1, y + h - 7);      
 274:       g.drawLine(x + 1, y + h - 7, x + 7, y + h - 1);
 275:     }
 276:     g.setColor(MetalLookAndFeel.getControlDarkShadow());
 277:     g.drawLine(x, y, x, y + h - 7);
 278:     g.drawLine(x, y + h - 7, x + 6, y + h - 1);
 279:     g.drawLine(x + 6, y + h - 1, x + w, y + h - 1);
 280:     g.drawLine(x + w, y + h - 1, x + w, y);
 281:   }
 282: 
 283:   /**
 284:    * Paints the background for a tab.
 285:    * 
 286:    * @param g  the graphics device.
 287:    * @param tabPlacement  the tab placement ({@link #TOP}, {@link #LEFT}, 
 288:    *        {@link #BOTTOM} or {@link #RIGHT}).
 289:    * @param tabIndex  the index of the tab to draw the border for.
 290:    * @param x  the x-coordinate for the tab's bounding rectangle.
 291:    * @param y  the y-coordinate for the tab's bounding rectangle.
 292:    * @param w  the width for the tab's bounding rectangle.
 293:    * @param h  the height for the tab's bounding rectangle.
 294:    * @param isSelected  indicates whether or not the tab is selected.
 295:    */
 296:   protected void paintTabBackground(Graphics g, int tabPlacement,
 297:       int tabIndex, int x, int y, int w, int h, boolean isSelected)
 298:   {
 299:     if (isSelected)
 300:       g.setColor(MetalLookAndFeel.getControl());
 301:     else
 302:       g.setColor(MetalLookAndFeel.getControlShadow());
 303:     int[] px, py;
 304:     if (tabPlacement == TOP) 
 305:       {
 306:         px = new int[] {x + 6, x + w - 1, x + w -1, x + 2, x + 2};
 307:         py = new int[] {y + 2, y + 2, y + h - 1, y + h -1, y + 6};
 308:       }
 309:     else if (tabPlacement == LEFT)
 310:       {
 311:         px = new int[] {x + 6, x + w - 1, x + w -1, x + 2, x + 2};
 312:         py = new int[] {y + 2, y + 2, y + h - 1, y + h -1, y + 6};
 313:       }
 314:     else if (tabPlacement == BOTTOM)
 315:       {
 316:         px = new int[] {x + 2, x + w - 1, x + w -1, x + 8, x + 2};
 317:         py = new int[] {y, y, y + h - 1, y + h -1, y + h - 7};
 318:       }
 319:     else if (tabPlacement == RIGHT)
 320:       {
 321:         px = new int[] {x + 2, x + w - 7, x + w - 1, x + w - 1, x + 2};
 322:         py = new int[] {y + 2, y + 2, y + 7, y + h -1, y + h - 1};
 323:       }
 324:     else 
 325:       throw new AssertionError("Unrecognised 'tabPlacement' argument.");
 326:     g.fillPolygon(px, py, 5);
 327:   }
 328:   
 329:   /**
 330:    * Returns <code>true</code> if the tabs in the specified run should be 
 331:    * padded to make the run fill the width/height of the {@link JTabbedPane}.
 332:    * 
 333:    * @param tabPlacement  the tab placement for the {@link JTabbedPane} (one of
 334:    *        {@link #TOP}, {@link #BOTTOM}, {@link #LEFT} and {@link #RIGHT}).
 335:    * @param run  the run index.
 336:    * 
 337:    * @return A boolean.
 338:    */
 339:   protected boolean shouldPadTabRun(int tabPlacement, int run)
 340:   {
 341:     // as far as I can tell, all runs should be padded except the last run
 342:     // (which is drawn at the very top for tabPlacement == TOP)
 343:     return run < this.runCount - 1;
 344:   }
 345:   
 346: }