001    /* MetalToolBarUI.java
002       Copyright (C) 2005 Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    
039    package javax.swing.plaf.metal;
040    
041    import java.awt.Graphics;
042    import java.awt.Point;
043    import java.awt.event.ContainerListener;
044    import java.awt.event.MouseEvent;
045    
046    import java.beans.PropertyChangeListener;
047    
048    import javax.swing.JComponent;
049    import javax.swing.JToolBar;
050    import javax.swing.SwingConstants;
051    import javax.swing.UIManager;
052    import javax.swing.border.Border;
053    import javax.swing.event.MouseInputListener;
054    import javax.swing.plaf.ComponentUI;
055    import javax.swing.plaf.basic.BasicToolBarUI;
056    
057    /**
058     * A UI delegate for the {@link JToolBar} component.
059     */
060    public class MetalToolBarUI extends BasicToolBarUI
061    {
062      
063      /**
064       * A listener (no longer used) that responds when components are added to or 
065       * removed from the {@link JToolBar}.  The required behaviour is now
066       * handled in the super class. 
067       * 
068       * @see MetalToolBarUI#createContainerListener()
069       */
070      protected class MetalContainerListener
071        extends BasicToolBarUI.ToolBarContListener
072      {
073        /**
074         * Creates a new instance.
075         */
076        protected MetalContainerListener()
077        {
078          // Nothing to do here.
079        }
080      }
081    
082      /**
083       * A listener (no longer used) that responds to property change events in a
084       * {@link JToolBar} component.  The required behaviour is now handled in the 
085       * super class. 
086       * 
087       * @see MetalToolBarUI#createRolloverListener()
088       */
089      protected class MetalRolloverListener
090        extends BasicToolBarUI.PropertyListener
091      {
092        /**
093         * Creates a new instance.
094         */
095        protected MetalRolloverListener()
096        {
097          // Nothing to do here.
098        }
099      }
100      
101      /** 
102       * The container listener (an implementation specific field, according to the
103       * spec, and not used in GNU Classpath).
104       */
105      protected ContainerListener contListener;
106      
107      /** 
108       * The rollover listener (an implementation specific field, according to the
109       * spec, and not used in GNU Classpath). 
110       */
111      protected PropertyChangeListener rolloverListener;
112    
113      /**
114       * Creates a new instance of this UI delegate.
115       */
116      public MetalToolBarUI()
117      {
118        super();
119      }
120    
121      /**
122       * Returns a new instance of <code>MetalToolBarUI</code>.
123       *
124       * @param component  the component for which we return an UI instance
125       *
126       * @return A new instance of <code>MetalToolBarUI</code>.
127       */
128      public static ComponentUI createUI(JComponent component)
129      {
130        return new MetalToolBarUI();
131      }
132      
133      /**
134       * Returns <code>null</code> as permitted by recent versions of the API
135       * specification.  Originally it seems this method returned a new instance of 
136       * {@link MetalRolloverListener}, but this is now redundant.
137       * 
138       * @return <code>null</code>.
139       */
140      protected PropertyChangeListener createRolloverListener()
141      {
142        return null;
143      }
144      
145      /**
146       * Returns <code>null</code> as permitted by recent versions of the API
147       * specification.  Originally it seems this method returned a new instance of 
148       * {@link MetalContainerListener}, but this is now redundant.
149       * 
150       * @return <code>null</code>.
151       */
152      protected ContainerListener createContainerListener()
153      {
154        return null;
155      }
156      
157      /**
158       * Returns a border with no rollover effect for buttons in the tool bar.
159       * 
160       * @return A border.
161       * 
162       * @see MetalBorders#getToolbarButtonBorder()
163       */
164      protected Border createNonRolloverBorder()
165      {
166        return MetalBorders.getToolbarButtonBorder();   
167      }
168      
169      /**
170       * Sets the offset for the window used for dragging the toolbar.
171       * It is set as long as the window is not null (it has been installed).
172       */
173      protected void setDragOffset(Point p)
174      {
175        if (dragWindow != null)
176          dragWindow.setOffset(p);
177      }
178      
179      /** 
180       * Creates and returns an instance of MetalDockingListener.
181       * 
182       * @return an instance of MetalDockingListener.
183       */
184      protected MouseInputListener createDockingListener()
185      {
186        return new MetalDockingListener(toolBar);
187      }
188      
189      /**
190       * This is the MouseHandler class that allows the user to drag the JToolBar
191       * in and out of the parent and dock it if it can.
192       */
193      protected class MetalDockingListener extends BasicToolBarUI.DockingListener
194      {    
195        /**
196         * Creates a new DockingListener object.
197         *
198         * @param t The JToolBar this DockingListener is being used for.
199         */
200        public MetalDockingListener(JToolBar t)
201        {
202          super(t);
203        }
204        
205        /**
206         * This method is called when the mouse is pressed in the JToolBar. If the
207         * press doesn't occur in a place where it causes the JToolBar to be
208         * dragged, it returns. Otherwise, it starts a drag session.
209         *
210         * @param e The MouseEvent.
211         */
212        public void mousePressed(MouseEvent e)
213        {
214          super.mousePressed(e);
215          setDragOffset(new Point(e.getX(), e.getY()));
216        }
217        
218        /**
219         * This method is called when the mouse is dragged. It delegates the drag
220         * painting to the dragTo method.
221         *
222         * @param e The MouseEvent.
223         */
224        public void mouseDragged(MouseEvent e)
225        {
226          // Does not do anything differently than dragging 
227          // BasicToolBarUI.DockingListener
228          super.mouseDragged(e);
229        }
230      }
231    
232      /**
233       * Installs the UI on the toolbar. This calls super and sets the rollover
234       * property according to the <code>UIManager</code> property
235       * &quot;ToolBar.isRollover&quot;.
236       *
237       * @param c the component to install the UI on
238       */
239      public void installUI(JComponent c)
240      {
241        super.installUI(c);
242        if (c instanceof JToolBar)
243          {
244            JToolBar tb = (JToolBar) c;
245            tb.setRollover(UIManager.getBoolean("ToolBar.isRollover"));
246          }
247      }
248    
249      /**
250       * Uninstalls the UI from the toolbar. This calls super and resets the
251       * rollover property.
252       *
253       * @param c the component to uninstall the UI from
254       */
255      public void uninstallUI(JComponent c)
256      {
257        if (c instanceof JToolBar)
258          {
259            JToolBar tb = (JToolBar) c;
260            tb.setRollover(false);
261          }
262        super.uninstallUI(c);
263      }
264    
265      /**
266       * Paints the background of the component if necessary and then calls
267       * <code>paint(g, c)</code>.
268       *
269       * This is overridden to implement the OceanTheme gradient when an OceanTheme
270       * is installed.
271       *
272       * @param g the graphics to use
273       * @param c the component to paint.
274       *
275       * @since 1.5
276       */
277      public void update(Graphics g, JComponent c)
278      {
279        // TODO: Sun's implementation uses the MenuBar.gradient here.
280        // I would consider this a bug, but implement it like this
281        // for compatibility.
282        if (MetalLookAndFeel.getCurrentTheme() instanceof OceanTheme
283            && UIManager.get("MenuBar.gradient") != null)
284          {
285            if (c.isOpaque())
286              {
287                MetalUtils.paintGradient(g, 0, 0, c.getWidth(), c.getHeight(),
288                                         SwingConstants.VERTICAL,
289                                         "MenuBar.gradient");
290              }
291            paint(g, c);
292          }
293        else
294          {
295            super.update(g, c);
296          }
297      }
298    }