classpath-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cp-patches] FYI: MetalTabbedPaneUI


From: David Gilbert
Subject: [cp-patches] FYI: MetalTabbedPaneUI
Date: Tue, 30 Aug 2005 10:46:56 +0000
User-agent: Mozilla Thunderbird 1.0.6 (X11/20050728)

I implemented some missing methods in MetalTabbedPaneUI to bring our Metal look and feel a small step closer to looking like the real thing, and added a 'Tab world' item to our Swing demo:

2005-08-30  David Gilbert  <address@hidden>

        * javax/swing/plaf/metal/MetalLookAndFeel.java
        (initComponentDefaults): added some defaults for TabbedPane,
        * javax/swing/plaf/metal/MetalTabbedPaneUI.java
        (TabbedPaneLayout): implemented new class,
        (createLayoutManager): implemented,
        (paintTabBorder): implemented,
        (paintTopTabBorder): implemented,
        (paintLeftTabBorder): implemented,
        (paintBottomTabBorder): implemented,
        (paintRightTabBorder): implemented,
        (paintTabBackground): implemented,
        (shouldPadTabRun): implemented,
        * examples/gnu/classpath/examples/swing/Demo.java:
        (mkTabWorld): new method,
        (mkTabbedPane): added tab for 'Tab World'.

Regards,

Dave Gilbert
Index: examples/gnu/classpath/examples/swing/Demo.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/examples/gnu/classpath/examples/swing/Demo.java,v
retrieving revision 1.17
diff -u -r1.17 Demo.java
--- examples/gnu/classpath/examples/swing/Demo.java     1 Aug 2005 22:32:44 
-0000       1.17
+++ examples/gnu/classpath/examples/swing/Demo.java     30 Aug 2005 09:34:17 
-0000
@@ -640,6 +640,29 @@
     return panel;
   }
 
+  static JPanel mkTabWorld() 
+  {
+    JPanel panel = new JPanel(new GridLayout(2, 2));
+    panel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
+    JTabbedPane tabs1 = new JTabbedPane(SwingConstants.TOP);
+    tabs1.add("Top Item 1", new JButton("Button"));
+    tabs1.add("Top Item 2", new JButton("Button"));
+    JTabbedPane tabs2 = new JTabbedPane(SwingConstants.LEFT);
+    tabs2.add("Left Item 1", new JButton("Button"));
+    tabs2.add("Left Item 2", new JButton("Button"));
+    JTabbedPane tabs3 = new JTabbedPane(SwingConstants.BOTTOM);
+    tabs3.add("Bottom Item 1", new JButton("Button"));
+    tabs3.add("Bottom Item 2", new JButton("Button"));
+    JTabbedPane tabs4 = new JTabbedPane(SwingConstants.RIGHT);
+    tabs4.add("Right Item 1", new JButton("Button"));
+    tabs4.add("Right Item 2", new JButton("Button"));
+    panel.add(tabs1);
+    panel.add(tabs2);
+    panel.add(tabs3);
+    panel.add(tabs4);
+    return panel;        
+  }
+
   static JTabbedPane mkTabbedPane()
   {
     JTabbedPane tabs = new JTabbedPane();
@@ -648,6 +671,7 @@
     tabs.add("List world!", mkListWorld());
     tabs.add("Desktop world!", mkDesktopWorld());
     tabs.add("Tree world!", mkTreeWorld());
+    tabs.add("Tab world!", mkTabWorld());
     return tabs;
   }
 
Index: javax/swing/plaf/metal/MetalLookAndFeel.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java,v
retrieving revision 1.43
diff -u -r1.43 MetalLookAndFeel.java
--- javax/swing/plaf/metal/MetalLookAndFeel.java        26 Aug 2005 18:17:57 
-0000      1.43
+++ javax/swing/plaf/metal/MetalLookAndFeel.java        30 Aug 2005 09:34:28 
-0000
@@ -843,6 +843,11 @@
       "Slider.trackWidth", new Integer(7),
       "Slider.majorTickLength", new Integer(6),
       
+      "TabbedPane.font", new FontUIResource("Dialog", Font.BOLD, 12),
+      "TabbedPane.tabInsets", new InsetsUIResource(0, 9, 1, 9),
+      "TabbedPane.selectedTabPadInsets", new InsetsUIResource(2, 2, 2, 1),
+      "TabbedPane.tabAreaInsets", new InsetsUIResource(4, 2, 0, 6),
+
       "ToggleButton.background", new ColorUIResource(getControl()),
       "ToggleButton.border", MetalBorders.getButtonBorder(),
       "ToggleButton.darkShadow", new ColorUIResource(getControlDarkShadow()),
Index: javax/swing/plaf/metal/MetalTabbedPaneUI.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java,v
retrieving revision 1.5
diff -u -r1.5 MetalTabbedPaneUI.java
--- javax/swing/plaf/metal/MetalTabbedPaneUI.java       2 Jul 2005 20:32:51 
-0000       1.5
+++ javax/swing/plaf/metal/MetalTabbedPaneUI.java       30 Aug 2005 09:34:28 
-0000
@@ -38,16 +38,70 @@
 
 package javax.swing.plaf.metal;
 
+import java.awt.Graphics;
+import java.awt.LayoutManager;
 import java.util.HashMap;
 
 import javax.swing.JComponent;
+import javax.swing.JTabbedPane;
 import javax.swing.plaf.ComponentUI;
 import javax.swing.plaf.basic.BasicTabbedPaneUI;
 
+/**
+ * A UI delegate used for the address@hidden JTabbedPane} component in the 
+ * address@hidden MetalLookAndFeel}.
+ */
 public class MetalTabbedPaneUI
   extends BasicTabbedPaneUI
 {
 
+  /**
+   * A address@hidden LayoutManager} responsible for placing all the tabs and 
the 
+   * visible component inside the address@hidden JTabbedPane}. This class is 
only used 
+   * for address@hidden JTabbedPane#WRAP_TAB_LAYOUT}.
+   *
+   * @specnote Apparently this class was intended to be protected,
+   *           but was made public by a compiler bug and is now
+   *           public for compatibility.
+   */
+  public class TabbedPaneLayout 
+      extends BasicTabbedPaneUI.TabbedPaneLayout
+  {
+    /**
+     * Creates a new instance of the layout manager.
+     */
+    public TabbedPaneLayout()
+    {
+    }
+    
+    /**
+     * Overridden to do nothing, because tab runs are not rotated in the 
+     * address@hidden MetalLookAndFeel}.
+     * 
+     * @param tabPlacement  the tab placement (one of address@hidden #TOP}, 
+     *        address@hidden #BOTTOM}, address@hidden #LEFT} or address@hidden 
#RIGHT}).
+     * @param selectedRun  the index of the selected run.
+     */
+    protected void rotateTabRuns(int tabPlacement, int selectedRun)
+    {
+      // do nothing, because tab runs are not rotated in the MetalLookAndFeel
+    }
+    
+    /**
+     * Overridden to do nothing, because the selected tab does not have extra
+     * padding in the address@hidden MetalLookAndFeel}.
+     * 
+     * @param tabPlacement  the tab placement (one of address@hidden #TOP}, 
+     *        address@hidden #BOTTOM}, address@hidden #LEFT} or address@hidden 
#RIGHT}).
+     * @param selectedIndex  the index of the selected tab.
+     */
+    protected void padSelectedTab(int tabPlacement, int selectedIndex)
+    {
+      // do nothing, because the selected tab does not have extra padding in 
+      // the MetalLookAndFeel
+    }
+  }
+
   /** The shared UI instance for JTabbedPanes. */
   private static HashMap instances = null;
 
@@ -83,4 +137,228 @@
 
     return instance;
   }
+  
+  /**
+   * Creates and returns an instance of address@hidden TabbedPaneLayout}.
+   * 
+   * @return A layout manager used by this UI delegate.
+   */
+  protected LayoutManager createLayoutManager()
+  {
+    return new TabbedPaneLayout();
+  }
+  
+  /**
+   * Paints the border for a single tab.
+   * 
+   * @param g  the graphics device.
+   * @param tabPlacement  the tab placement (address@hidden #TOP}, 
address@hidden #LEFT}, 
+   *        address@hidden #BOTTOM} or address@hidden #RIGHT}).
+   * @param tabIndex  the index of the tab to draw the border for.
+   * @param x  the x-coordinate for the tab's bounding rectangle.
+   * @param y  the y-coordinate for the tab's bounding rectangle.
+   * @param w  the width for the tab's bounding rectangle.
+   * @param h  the height for the tab's bounding rectangle.
+   * @param isSelected  indicates whether or not the tab is selected.
+   */
+  protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, 
+          int x, int y, int w, int h, boolean isSelected) 
+  {
+    if (tabPlacement == TOP)
+      paintTopTabBorder(tabIndex, g, x, y, w, h, 0, 0, isSelected);
+    else if (tabPlacement == LEFT) 
+      paintLeftTabBorder(tabIndex, g, x, y, w, h, 0, 0, isSelected);
+    else if (tabPlacement == BOTTOM)
+      paintBottomTabBorder(tabIndex, g, x, y, w, h, 0, 0, isSelected);
+    else if (tabPlacement == RIGHT)
+      paintRightTabBorder(tabIndex, g, x, y, w, h, 0, 0, isSelected);
+    else 
+      throw new AssertionError("Unrecognised 'tabPlacement' argument.");
+  }
+
+  /**
+   * Paints the border for a tab assuming that the tab position is at the top
+   * (address@hidden #TOP}).
+   * 
+   * @param tabIndex  the tab index.
+   * @param g  the graphics device.
+   * @param x  the x-coordinate for the tab's bounding rectangle.
+   * @param y  the y-coordinate for the tab's bounding rectangle.
+   * @param w  the width for the tab's bounding rectangle.
+   * @param h  the height for the tab's bounding rectangle.
+   * @param btm  ???
+   * @param rght  ???
+   * @param isSelected  indicates whether the tab is selected.
+   */
+  protected void paintTopTabBorder(int tabIndex, Graphics g, int x, int y,
+      int w, int h, int btm, int rght, boolean isSelected)
+  {
+    if (isSelected)
+    {
+      g.setColor(MetalLookAndFeel.getControlHighlight());
+      g.drawLine(x + 1, y + h, x + 1, y + 6);      
+      g.drawLine(x + 1, y + 6, x + 6, y + 1);
+      g.drawLine(x + 6, y + 1, x + w - 1, y + 1);
+    }
+    g.setColor(MetalLookAndFeel.getControlDarkShadow());
+    g.drawLine(x, y + h - 1, x, y + 6);
+    g.drawLine(x, y + 6, x + 6, y);
+    g.drawLine(x + 6, y, x + w, y);
+    g.drawLine(x + w, y, x + w, y + h - 1);
+  }
+  
+  /**
+   * Paints the border for a tab assuming that the tab position is at the left
+   * (address@hidden #LEFT}).
+   * 
+   * @param tabIndex  the tab index.
+   * @param g  the graphics device.
+   * @param x  the x-coordinate for the tab's bounding rectangle.
+   * @param y  the y-coordinate for the tab's bounding rectangle.
+   * @param w  the width for the tab's bounding rectangle.
+   * @param h  the height for the tab's bounding rectangle.
+   * @param btm  ???
+   * @param rght  ???
+   * @param isSelected  indicates whether the tab is selected.
+   */
+  protected void paintLeftTabBorder(int tabIndex, Graphics g, int x, int y,
+      int w, int h, int btm, int rght, boolean isSelected)
+  {
+    if (isSelected)
+    {
+      g.setColor(MetalLookAndFeel.getControlHighlight());
+      g.drawLine(x + 1, y + h, x + 1, y + 6);      
+      g.drawLine(x + 1, y + 6, x + 6, y + 1);
+      g.drawLine(x + 6, y + 1, x + w - 1, y + 1);
+    }
+    g.setColor(MetalLookAndFeel.getControlDarkShadow());
+    g.drawLine(x, y + h, x, y + 6);
+    g.drawLine(x, y + 6, x + 6, y);
+    g.drawLine(x + 6, y, x + w - 1, y);
+    g.drawLine(x, y + h, x + w - 1, y + h);
+  }
+  
+  /**
+   * Paints the border for a tab assuming that the tab position is at the right
+   * (address@hidden #RIGHT}).
+   * 
+   * @param tabIndex  the tab index.
+   * @param g  the graphics device.
+   * @param x  the x-coordinate for the tab's bounding rectangle.
+   * @param y  the y-coordinate for the tab's bounding rectangle.
+   * @param w  the width for the tab's bounding rectangle.
+   * @param h  the height for the tab's bounding rectangle.
+   * @param btm  ???
+   * @param rght  ???
+   * @param isSelected  indicates whether the tab is selected.
+   */
+  protected void paintRightTabBorder(int tabIndex, Graphics g, int x, int y,
+      int w, int h, int btm, int rght, boolean isSelected)
+  {
+    if (isSelected)
+    {
+      g.setColor(MetalLookAndFeel.getControlHighlight());
+      g.drawLine(x, y + 1, x + w - 7, y + 1);      
+      g.drawLine(x + w - 7, y + 1, x + w - 1, y + 7);
+    }
+    g.setColor(MetalLookAndFeel.getControlDarkShadow());
+    g.drawLine(x, y, x + w - 7, y);
+    g.drawLine(x + w - 7, y, x + w - 1, y + 6);
+    g.drawLine(x + w - 1, y + 6, x + w - 1, y + h - 1);
+    g.drawLine(x + w - 1, y + h, x, y + h);
+  }
+  
+  /**
+   * Paints the border for a tab assuming that the tab position is at the 
bottom
+   * (address@hidden #BOTTOM}).
+   * 
+   * @param tabIndex  the tab index.
+   * @param g  the graphics device.
+   * @param x  the x-coordinate for the tab's bounding rectangle.
+   * @param y  the y-coordinate for the tab's bounding rectangle.
+   * @param w  the width for the tab's bounding rectangle.
+   * @param h  the height for the tab's bounding rectangle.
+   * @param btm  ???
+   * @param rght  ???
+   * @param isSelected  indicates whether the tab is selected.
+   */
+  protected void paintBottomTabBorder(int tabIndex, Graphics g, int x, int y,
+      int w, int h, int btm, int rght, boolean isSelected)
+  {
+    if (isSelected)
+    {
+      g.setColor(MetalLookAndFeel.getControlHighlight());
+      g.drawLine(x + 1, y, x + 1, y + h - 7);      
+      g.drawLine(x + 1, y + h - 7, x + 7, y + h - 1);
+    }
+    g.setColor(MetalLookAndFeel.getControlDarkShadow());
+    g.drawLine(x, y, x, y + h - 7);
+    g.drawLine(x, y + h - 7, x + 6, y + h - 1);
+    g.drawLine(x + 6, y + h - 1, x + w, y + h - 1);
+    g.drawLine(x + w, y + h - 1, x + w, y);
+  }
+
+  /**
+   * Paints the background for a tab.
+   * 
+   * @param g  the graphics device.
+   * @param tabPlacement  the tab placement (address@hidden #TOP}, 
address@hidden #LEFT}, 
+   *        address@hidden #BOTTOM} or address@hidden #RIGHT}).
+   * @param tabIndex  the index of the tab to draw the border for.
+   * @param x  the x-coordinate for the tab's bounding rectangle.
+   * @param y  the y-coordinate for the tab's bounding rectangle.
+   * @param w  the width for the tab's bounding rectangle.
+   * @param h  the height for the tab's bounding rectangle.
+   * @param isSelected  indicates whether or not the tab is selected.
+   */
+  protected void paintTabBackground(Graphics g, int tabPlacement,
+      int tabIndex, int x, int y, int w, int h, boolean isSelected)
+  {
+    if (isSelected)
+      g.setColor(MetalLookAndFeel.getControl());
+    else
+      g.setColor(MetalLookAndFeel.getControlShadow());
+    int[] px, py;
+    if (tabPlacement == TOP) 
+      {
+        px = new int[] {x + 6, x + w - 1, x + w -1, x + 2, x + 2};
+        py = new int[] {y + 2, y + 2, y + h - 1, y + h -1, y + 6};
+      }
+    else if (tabPlacement == LEFT)
+      {
+        px = new int[] {x + 6, x + w - 1, x + w -1, x + 2, x + 2};
+        py = new int[] {y + 2, y + 2, y + h - 1, y + h -1, y + 6};
+      }
+    else if (tabPlacement == BOTTOM)
+      {
+        px = new int[] {x + 2, x + w - 1, x + w -1, x + 8, x + 2};
+        py = new int[] {y, y, y + h - 1, y + h -1, y + h - 7};
+      }
+    else if (tabPlacement == RIGHT)
+      {
+        px = new int[] {x + 2, x + w - 7, x + w - 1, x + w - 1, x + 2};
+        py = new int[] {y + 2, y + 2, y + 7, y + h -1, y + h - 1};
+      }
+    else 
+      throw new AssertionError("Unrecognised 'tabPlacement' argument.");
+    g.fillPolygon(px, py, 5);
+  }
+  
+  /**
+   * Returns <code>true</code> if the tabs in the specified run should be 
+   * padded to make the run fill the width/height of the address@hidden 
JTabbedPane}.
+   * 
+   * @param tabPlacement  the tab placement for the address@hidden 
JTabbedPane} (one of
+   *        address@hidden #TOP}, address@hidden #BOTTOM}, address@hidden 
#LEFT} and address@hidden #RIGHT}).
+   * @param run  the run index.
+   * 
+   * @return A boolean.
+   */
+  protected boolean shouldPadTabRun(int tabPlacement, int run)
+  {
+    // as far as I can tell, all runs should be padded except the last run
+    // (which is drawn at the very top for tabPlacement == TOP)
+    return run < this.runCount - 1;
+  }
+  
 }

reply via email to

[Prev in Thread] Current Thread [Next in Thread]