BasicTaskPaneUI.java
上传用户:zhengdagz
上传日期:2014-03-06
资源大小:1956k
文件大小:17k
源码类别:

xml/soap/webservice

开发平台:

Java

  1. /*
  2.  * $Id: BasicTaskPaneUI.java,v 1.6 2005/10/10 18:02:54 rbair Exp $
  3.  *
  4.  * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
  5.  * Santa Clara, California 95054, U.S.A. All rights reserved.
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  * 
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  * 
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  20.  */
  21. package org.jdesktop.swingx.plaf.basic;
  22. import java.awt.Color;
  23. import java.awt.Component;
  24. import java.awt.Cursor;
  25. import java.awt.Dimension;
  26. import java.awt.Graphics;
  27. import java.awt.Insets;
  28. import java.awt.Rectangle;
  29. import java.awt.event.ActionEvent;
  30. import java.awt.event.FocusEvent;
  31. import java.awt.event.FocusListener;
  32. import java.awt.event.MouseEvent;
  33. import java.beans.PropertyChangeEvent;
  34. import java.beans.PropertyChangeListener;
  35. import javax.swing.AbstractAction;
  36. import javax.swing.Action;
  37. import javax.swing.ActionMap;
  38. import javax.swing.BorderFactory;
  39. import javax.swing.Icon;
  40. import javax.swing.InputMap;
  41. import javax.swing.JComponent;
  42. import javax.swing.JLabel;
  43. import javax.swing.LookAndFeel;
  44. import javax.swing.SwingUtilities;
  45. import javax.swing.UIManager;
  46. import javax.swing.border.Border;
  47. import javax.swing.border.CompoundBorder;
  48. import javax.swing.event.MouseInputAdapter;
  49. import javax.swing.event.MouseInputListener;
  50. import javax.swing.plaf.ActionMapUIResource;
  51. import javax.swing.plaf.ComponentUI;
  52. import javax.swing.plaf.basic.BasicGraphicsUtils;
  53. import org.jdesktop.swingx.JXCollapsiblePane;
  54. import org.jdesktop.swingx.JXHyperlink;
  55. import org.jdesktop.swingx.JXTaskPane;
  56. import org.jdesktop.swingx.icon.EmptyIcon;
  57. import org.jdesktop.swingx.plaf.TaskPaneUI;
  58. /**
  59.  * Base implementation of the <code>JXTaskPane</code> UI.
  60.  * 
  61.  * @author <a href="mailto:fred@L2FProd.com">Frederic Lavigne</a>
  62.  */
  63. public class BasicTaskPaneUI extends TaskPaneUI {
  64.   private static FocusListener focusListener = new RepaintOnFocus();
  65.   public static ComponentUI createUI(JComponent c) {
  66.     return new BasicTaskPaneUI();
  67.   }
  68.   protected static int TITLE_HEIGHT = 25;
  69.   protected static int ROUND_HEIGHT = 5;
  70.   
  71.   protected JXTaskPane group;
  72.   protected boolean mouseOver;
  73.   protected MouseInputListener mouseListener;
  74.   protected PropertyChangeListener propertyListener;
  75.   
  76.   public void installUI(JComponent c) {
  77.     super.installUI(c);
  78.     group = (JXTaskPane)c;
  79.     installDefaults();
  80.     installListeners();
  81.     installKeyboardActions();
  82.   }
  83.   protected void installDefaults() {
  84.     group.setOpaque(true);
  85.     group.setBorder(createPaneBorder());
  86.     ((JComponent)group.getContentPane()).setBorder(createContentPaneBorder());
  87.     LookAndFeel.installColorsAndFont(
  88.       group,
  89.       "TaskPane.background",
  90.       "TaskPane.foreground",
  91.       "TaskPane.font");
  92.     LookAndFeel.installColorsAndFont(
  93.       (JComponent)group.getContentPane(),
  94.       "TaskPane.background",
  95.       "TaskPane.foreground",
  96.       "TaskPane.font");    
  97.   }
  98.   protected void installListeners() {
  99.     mouseListener = createMouseInputListener();
  100.     group.addMouseMotionListener(mouseListener);
  101.     group.addMouseListener(mouseListener);
  102.     group.addFocusListener(focusListener);
  103.     propertyListener = createPropertyListener();
  104.     group.addPropertyChangeListener(propertyListener);
  105.   }
  106.   protected void installKeyboardActions() {
  107.     InputMap inputMap = (InputMap)UIManager.get("TaskPane.focusInputMap");
  108.     if (inputMap != null) {
  109.       SwingUtilities.replaceUIInputMap(
  110.         group,
  111.         JComponent.WHEN_FOCUSED,
  112.         inputMap);
  113.     }
  114.     ActionMap map = getActionMap();
  115.     if (map != null) {
  116.       SwingUtilities.replaceUIActionMap(group, map);
  117.     }
  118.   }
  119.   ActionMap getActionMap() {
  120.     ActionMap map = new ActionMapUIResource();
  121.     map.put("toggleExpanded", new ToggleExpandedAction());
  122.     return map;
  123.   }
  124.   public void uninstallUI(JComponent c) {
  125.     uninstallListeners();
  126.     super.uninstallUI(c);
  127.   }
  128.   protected void uninstallListeners() {
  129.     group.removeMouseListener(mouseListener);
  130.     group.removeMouseMotionListener(mouseListener);
  131.     group.removeFocusListener(focusListener);
  132.     group.removePropertyChangeListener(propertyListener);
  133.   }
  134.   protected MouseInputListener createMouseInputListener() {
  135.     return new ToggleListener();
  136.   }
  137.   protected PropertyChangeListener createPropertyListener() {
  138.     return new ChangeListener();
  139.   }
  140.   
  141.   protected boolean isInBorder(MouseEvent event) {
  142.     return event.getY() < getTitleHeight();
  143.   }
  144.   protected final int getTitleHeight() {
  145.     return TITLE_HEIGHT;
  146.   }
  147.   protected Border createPaneBorder() {
  148.     return new PaneBorder();
  149.   }
  150.   @Override
  151.   public Dimension getPreferredSize(JComponent c) {
  152.     Component component = group.getComponent(0);
  153.     if (!(component instanceof JXCollapsiblePane)) {
  154.       // something wrong in this JXTaskPane
  155.       return super.getPreferredSize(c);
  156.     }
  157.     
  158.     JXCollapsiblePane collapsible = (JXCollapsiblePane)component;
  159.     Dimension dim = collapsible.getPreferredSize();
  160.     
  161.     Border groupBorder = group.getBorder();
  162.     if (groupBorder instanceof PaneBorder) {
  163.       Dimension border = ((PaneBorder)groupBorder).getPreferredSize(group);
  164.       dim.width = Math.max(dim.width, border.width);
  165.       dim.height += border.height;
  166.     } else {
  167.       dim.height += getTitleHeight();
  168.     }      
  169.     
  170.     return dim;
  171.   }
  172.   
  173.   protected Border createContentPaneBorder() {
  174.     Color borderColor = UIManager.getColor("TaskPane.borderColor");
  175.     return new CompoundBorder(new ContentPaneBorder(borderColor), BorderFactory
  176.       .createEmptyBorder(10, 10, 10, 10));
  177.   }
  178.   
  179.   public Component createAction(Action action) {
  180.     JXHyperlink button = new JXHyperlink(action);
  181.     button.setOpaque(false);
  182.     button.setBorder(null);
  183.     button.setBorderPainted(false);
  184.     button.setFocusPainted(true);
  185.     button.setForeground(UIManager.getColor("TaskPane.titleForeground"));
  186.     return button;
  187.   }
  188.   protected void ensureVisible() {
  189.     SwingUtilities.invokeLater(new Runnable() {
  190.       public void run() {
  191.         group.scrollRectToVisible(
  192.           new Rectangle(group.getWidth(), group.getHeight()));
  193.       }
  194.     });
  195.   }
  196.   
  197.   static class RepaintOnFocus implements FocusListener {
  198.     public void focusGained(FocusEvent e) {
  199.       e.getComponent().repaint();
  200.     }
  201.     public void focusLost(FocusEvent e) {
  202.       e.getComponent().repaint();
  203.     }
  204.   }
  205.   
  206.   class ChangeListener implements PropertyChangeListener {
  207.     public void propertyChange(PropertyChangeEvent evt) {
  208.       // if group is expanded but not animated
  209.       // or if animated has reached expanded state
  210.       // scroll to visible if scrollOnExpand is enabled
  211.       if ((JXTaskPane.EXPANDED_CHANGED_KEY.equals(evt.getPropertyName())
  212.         && Boolean.TRUE.equals(evt.getNewValue()) && !group.isAnimated())
  213.         || (JXCollapsiblePane.ANIMATION_STATE_KEY.equals(evt.getPropertyName()) && "expanded"
  214.           .equals(evt.getNewValue()))) {
  215.         if (group.isScrollOnExpand()) {
  216.           ensureVisible();
  217.         }
  218.       }
  219.     }
  220.   }
  221.   
  222.   class ToggleListener extends MouseInputAdapter {
  223.     public void mouseEntered(MouseEvent e) {
  224.       if (isInBorder(e)) {
  225.         e.getComponent().setCursor(
  226.           Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
  227.       } else {
  228.         mouseOver = false;
  229.         group.repaint();
  230.       }
  231.     }
  232.     public void mouseExited(MouseEvent e) {
  233.       e.getComponent().setCursor(Cursor.getDefaultCursor());
  234.       mouseOver = false;
  235.       group.repaint();
  236.     }
  237.     public void mouseMoved(MouseEvent e) {
  238.       if (isInBorder(e)) {
  239.         e.getComponent().setCursor(
  240.           Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
  241.         mouseOver = true;
  242.         group.repaint();
  243.       } else {
  244.         e.getComponent().setCursor(Cursor.getDefaultCursor());
  245.         mouseOver = false;
  246.         group.repaint();
  247.       }
  248.     }
  249.     public void mouseReleased(MouseEvent e) {
  250.       if (isInBorder(e)) {
  251.         group.setExpanded(!group.isExpanded());
  252.       }
  253.     }
  254.   }
  255.   
  256.   class ToggleExpandedAction extends AbstractAction {
  257.     public ToggleExpandedAction() {
  258.       super("toggleExpanded");
  259.     }
  260.     public void actionPerformed(ActionEvent e) {
  261.       group.setExpanded(!group.isExpanded());
  262.     }
  263.     public boolean isEnabled() {
  264.       return group.isVisible();
  265.     }
  266.   }
  267.   protected static class ChevronIcon implements Icon {
  268.     boolean up = true;
  269.     public ChevronIcon(boolean up) {
  270.       this.up = up;
  271.     }
  272.     public int getIconHeight() {
  273.       return 3;
  274.     }
  275.     public int getIconWidth() {
  276.       return 6;
  277.     }
  278.     public void paintIcon(Component c, Graphics g, int x, int y) {
  279.       if (up) {
  280.         g.drawLine(x + 3, y, x, y + 3);
  281.         g.drawLine(x + 3, y, x + 6, y + 3);
  282.       } else {
  283.         g.drawLine(x, y, x + 3, y + 3);
  284.         g.drawLine(x + 3, y + 3, x + 6, y);
  285.       }
  286.     }
  287.   }
  288.   /**
  289.    * The border around the content pane
  290.    */
  291.   protected static class ContentPaneBorder implements Border {
  292.     Color color;
  293.     public ContentPaneBorder(Color color) {
  294.       this.color = color;
  295.     }
  296.     public Insets getBorderInsets(Component c) {
  297.       return new Insets(0, 1, 1, 1);
  298.     }
  299.     public boolean isBorderOpaque() {
  300.       return true;
  301.     }
  302.     public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
  303.       g.setColor(color);
  304.       g.drawLine(x, y, x, y + height - 1);
  305.       g.drawLine(x, y + height - 1, x + width - 1, y + height - 1);
  306.       g.drawLine(x + width - 1, y, x + width - 1, y + height - 1);
  307.     }
  308.   }
  309.   
  310.   /**
  311.    * The border of the taskpane group paints the "text", the "icon", the
  312.    * "expanded" status and the "special" type.
  313.    *  
  314.    */
  315.   protected class PaneBorder implements Border {
  316.     protected Color borderColor;
  317.     protected Color titleForeground;
  318.     protected Color specialTitleBackground;
  319.     protected Color specialTitleForeground;
  320.     protected Color titleBackgroundGradientStart;
  321.     protected Color titleBackgroundGradientEnd;
  322.     protected Color titleOver;
  323.     protected Color specialTitleOver;
  324.     
  325.     protected JLabel label;
  326.     
  327.     public PaneBorder() {
  328.       borderColor = UIManager.getColor("TaskPane.borderColor");      
  329.       titleForeground = UIManager.getColor("TaskPane.titleForeground");
  330.       specialTitleBackground = UIManager
  331.         .getColor("TaskPane.specialTitleBackground");
  332.       specialTitleForeground = UIManager
  333.         .getColor("TaskPane.specialTitleForeground");
  334.       titleBackgroundGradientStart = UIManager
  335.         .getColor("TaskPane.titleBackgroundGradientStart");
  336.       titleBackgroundGradientEnd = UIManager
  337.         .getColor("TaskPane.titleBackgroundGradientEnd");
  338.       
  339.       titleOver = UIManager.getColor("TaskPane.titleOver");
  340.       if (titleOver == null) {
  341.         titleOver = specialTitleBackground.brighter();
  342.       }
  343.       specialTitleOver = UIManager.getColor("TaskPane.specialTitleOver");
  344.       if (specialTitleOver == null) {
  345.         specialTitleOver = specialTitleBackground.brighter();
  346.       }
  347.       
  348.       label = new JLabel();
  349.       label.setOpaque(false);
  350.       label.setIconTextGap(8);
  351.     }
  352.     
  353.     public Insets getBorderInsets(Component c) {
  354.       return new Insets(getTitleHeight(), 0, 0, 0);
  355.     }
  356.     public boolean isBorderOpaque() {
  357.       return true;
  358.     }
  359.     /**
  360.      * Calculates the preferred border size, its size so all its content fits.
  361.      */
  362.     public Dimension getPreferredSize(JXTaskPane group) {
  363.       // calculate the title width so it is fully visible
  364.       // it starts with the title width
  365.       configureLabel(group);
  366.       Dimension dim = label.getPreferredSize();
  367.       // add the title left offset
  368.       dim.width += 3;
  369.       // add the controls width
  370.       dim.width += TITLE_HEIGHT;
  371.       // and some space between label and controls
  372.       dim.width += 3;
  373.       
  374.       dim.height = getTitleHeight();
  375.       return dim;
  376.     }
  377.     
  378.     protected void paintTitleBackground(JXTaskPane group, Graphics g) {
  379.       if (group.isSpecial()) {
  380.         g.setColor(specialTitleBackground);
  381.       } else {
  382.         g.setColor(titleBackgroundGradientStart);
  383.       }
  384.       g.fillRect(0, 0, group.getWidth(), getTitleHeight() - 1);
  385.     }
  386.     protected void paintTitle(
  387.       JXTaskPane group,
  388.       Graphics g,
  389.       Color textColor,
  390.       int x,
  391.       int y,
  392.       int width,
  393.       int height) {
  394.       configureLabel(group);
  395.       label.setForeground(textColor);
  396.       g.translate(x, y);
  397.       label.setBounds(0, 0, width, height);
  398.       label.paint(g);
  399.       g.translate(-x, -y);
  400.     }
  401.     protected void configureLabel(JXTaskPane group) {
  402.       label.applyComponentOrientation(group.getComponentOrientation());
  403.       label.setFont(group.getFont());
  404.       label.setText(group.getTitle());
  405.       label.setIcon(
  406.         group.getIcon() == null ? new EmptyIcon() : group.getIcon());      
  407.     }
  408.     
  409.     protected void paintExpandedControls(JXTaskPane group, Graphics g, int x,
  410.       int y, int width, int height) {}
  411.     protected Color getPaintColor(JXTaskPane group) {
  412.       Color paintColor;
  413.       if (isMouseOverBorder()) {
  414.         if (mouseOver) {
  415.           if (group.isSpecial()) {
  416.             paintColor = specialTitleOver;
  417.           } else {
  418.             paintColor = titleOver;
  419.           }
  420.         } else {
  421.           if (group.isSpecial()) {
  422.             paintColor = specialTitleForeground;
  423.           } else {
  424.             paintColor = titleForeground;
  425.           }
  426.         }
  427.       } else {
  428.         if (group.isSpecial()) {
  429.           paintColor = specialTitleForeground;
  430.         } else {
  431.           paintColor = titleForeground;
  432.         }
  433.       }
  434.       return paintColor;
  435.     }
  436.     
  437.     public void paintBorder(
  438.       Component c,
  439.       Graphics g,
  440.       int x,
  441.       int y,
  442.       int width,
  443.       int height) {
  444.       JXTaskPane group = (JXTaskPane)c;
  445.       // calculate position of title and toggle controls
  446.       int controlWidth = TITLE_HEIGHT - 2 * ROUND_HEIGHT;
  447.       int controlX = group.getWidth() - TITLE_HEIGHT;
  448.       int controlY = ROUND_HEIGHT - 1;
  449.       int titleX = 3;
  450.       int titleY = 0;
  451.       int titleWidth = group.getWidth() - getTitleHeight() - 3;
  452.       int titleHeight = getTitleHeight();
  453.       
  454.       if (!group.getComponentOrientation().isLeftToRight()) {
  455.         controlX = group.getWidth() - controlX - controlWidth;        
  456.         titleX = group.getWidth() - titleX - titleWidth;
  457.       }
  458.       
  459.       // paint the title background
  460.       paintTitleBackground(group, g);
  461.       // paint the the toggles
  462.       paintExpandedControls(group, g, controlX, controlY, controlWidth,
  463.         controlWidth);
  464.       // paint the title text and icon
  465.       Color paintColor = getPaintColor(group);
  466.       // focus painted same color as text
  467.       if (group.hasFocus()) {
  468.         g.setColor(paintColor);
  469.         BasicGraphicsUtils.drawDashedRect(
  470.           g,
  471.           3,
  472.           3,
  473.           width - 6,
  474.           getTitleHeight() - 6);
  475.       }
  476.       paintTitle(
  477.         group,
  478.         g,
  479.         paintColor,
  480.         titleX,
  481.         titleY,
  482.         titleWidth,
  483.         titleHeight);
  484.     }
  485.     
  486.     protected void paintRectAroundControls(JXTaskPane group, Graphics g, int x,
  487.       int y, int width, int height, Color highColor, Color lowColor) {      
  488.       if (mouseOver) {
  489.         int x2 = x + width;
  490.         int y2 = y + height;
  491.         g.setColor(highColor);
  492.         g.drawLine(x, y, x2, y);
  493.         g.drawLine(x, y, x, y2);
  494.         g.setColor(lowColor);
  495.         g.drawLine(x2, y, x2, y2);
  496.         g.drawLine(x, y2, x2, y2);
  497.       }
  498.     }
  499.     
  500.     protected void paintOvalAroundControls(JXTaskPane group, Graphics g, int x,
  501.       int y, int width, int height) {      
  502.       if (group.isSpecial()) {
  503.         g.setColor(specialTitleBackground.brighter());
  504.         g.drawOval(
  505.           x,
  506.           y,
  507.           width,
  508.           height);
  509.       } else {
  510.         g.setColor(titleBackgroundGradientStart);
  511.         g.fillOval(
  512.           x,
  513.           y,
  514.           width,
  515.           height);
  516.         g.setColor(titleBackgroundGradientEnd.darker());
  517.         g.drawOval(
  518.           x,
  519.           y,
  520.           width,
  521.           width);
  522.       }
  523.     }
  524.     
  525.     protected void paintChevronControls(JXTaskPane group, Graphics g, int x,
  526.       int y, int width, int height) {      
  527.       ChevronIcon chevron;
  528.       if (group.isExpanded()) {
  529.         chevron = new ChevronIcon(true);
  530.       } else {
  531.         chevron = new ChevronIcon(false);
  532.       }
  533.       int chevronX = x + width / 2 - chevron.getIconWidth() / 2;
  534.       int chevronY = y + (height / 2 - chevron.getIconHeight());
  535.       chevron.paintIcon(group, g, chevronX, chevronY);
  536.       chevron.paintIcon(
  537.         group,
  538.         g,
  539.         chevronX,
  540.         chevronY + chevron.getIconHeight() + 1);
  541.     }
  542.     
  543.     /**
  544.      * Default implementation returns false.
  545.      *  
  546.      * @return true if this border wants to display things differently when the
  547.      *         mouse is over it
  548.      */
  549.     protected boolean isMouseOverBorder() {
  550.       return false;
  551.     }
  552.   }
  553. }