1 /*
2  * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package javax.swing.plaf.metal;
27 
28 import java.awt.*;
29 import java.awt.event.*;
30 import javax.swing.*;
31 import javax.swing.event.*;
32 import javax.swing.border.*;
33 import javax.swing.plaf.basic.*;
34 import java.beans.PropertyChangeListener;
35 import java.beans.PropertyChangeEvent;
36 import javax.swing.plaf.*;
37 
38 /**
39  * Metal implementation of JInternalFrame.
40  *
41  * @author Steve Wilson
42  */
43 public class MetalInternalFrameUI extends BasicInternalFrameUI {
44 
45   private static final PropertyChangeListener metalPropertyChangeListener =
46         new MetalPropertyChangeHandler();
47 
48   private static final Border handyEmptyBorder = new EmptyBorder(0,0,0,0);
49 
50   /**
51    * The property {@code JInternalFrame.isPalette}.
52    */
53   protected static String IS_PALETTE   = "JInternalFrame.isPalette";
54   private static String IS_PALETTE_KEY = "JInternalFrame.isPalette";
55   private static String FRAME_TYPE     = "JInternalFrame.frameType";
56   private static String NORMAL_FRAME   = "normal";
57   private static String PALETTE_FRAME  = "palette";
58   private static String OPTION_DIALOG  = "optionDialog";
59 
60 
61   /**
62    * Constructs a new {@code MetalInternalFrameUI} instance.
63    *
64    * @param b an internal frame
65    */
MetalInternalFrameUI(JInternalFrame b)66   public MetalInternalFrameUI(JInternalFrame b)   {
67     super(b);
68   }
69 
70   /**
71    * Constructs a new {@code MetalInternalFrameUI} instance.
72    *
73    * @param c a component
74    * @return a new {@code MetalInternalFrameUI} instance
75    */
createUI(JComponent c)76   public static ComponentUI createUI(JComponent c)    {
77       return new MetalInternalFrameUI( (JInternalFrame) c);
78   }
79 
installUI(JComponent c)80   public void installUI(JComponent c) {
81     super.installUI(c);
82 
83     Object paletteProp = c.getClientProperty(IS_PALETTE_KEY);
84     if ( paletteProp != null ) {
85         setPalette( ((Boolean)paletteProp).booleanValue() );
86     }
87 
88     Container content = frame.getContentPane();
89     stripContentBorder(content);
90     //c.setOpaque(false);
91   }
92 
uninstallUI(JComponent c)93   public void uninstallUI(JComponent c) {
94       frame = (JInternalFrame)c;
95 
96       Container cont = ((JInternalFrame)(c)).getContentPane();
97       if (cont instanceof JComponent) {
98         JComponent content = (JComponent)cont;
99         if ( content.getBorder() == handyEmptyBorder) {
100           content.setBorder(null);
101         }
102       }
103       super.uninstallUI(c);
104   }
105 
installListeners()106     protected void installListeners() {
107         super.installListeners();
108         frame.addPropertyChangeListener(metalPropertyChangeListener);
109     }
110 
uninstallListeners()111     protected void uninstallListeners() {
112         frame.removePropertyChangeListener(metalPropertyChangeListener);
113         super.uninstallListeners();
114     }
115 
installKeyboardActions()116   protected void installKeyboardActions(){
117       super.installKeyboardActions();
118       ActionMap map = SwingUtilities.getUIActionMap(frame);
119       if (map != null) {
120           // BasicInternalFrameUI creates an action with the same name, we override
121           // it as Metal frames do not have system menus.
122           map.remove("showSystemMenu");
123       }
124   }
125 
uninstallKeyboardActions()126   protected void uninstallKeyboardActions(){
127       super.uninstallKeyboardActions();
128   }
129 
uninstallComponents()130     protected void uninstallComponents() {
131         titlePane = null;
132         super.uninstallComponents();
133     }
134 
stripContentBorder(Object c)135   private void stripContentBorder(Object c) {
136         if ( c instanceof JComponent ) {
137             JComponent contentComp = (JComponent)c;
138             Border contentBorder = contentComp.getBorder();
139             if (contentBorder == null || contentBorder instanceof UIResource) {
140                 contentComp.setBorder( handyEmptyBorder );
141             }
142         }
143   }
144 
145 
createNorthPane(JInternalFrame w)146   protected JComponent createNorthPane(JInternalFrame w) {
147       return new MetalInternalFrameTitlePane(w);
148   }
149 
150 
setFrameType( String frameType )151   private void setFrameType( String frameType )
152   {
153       if ( frameType.equals( OPTION_DIALOG ) )
154       {
155           LookAndFeel.installBorder(frame, "InternalFrame.optionDialogBorder");
156           ((MetalInternalFrameTitlePane)titlePane).setPalette( false );
157       }
158       else if ( frameType.equals( PALETTE_FRAME ) )
159       {
160           LookAndFeel.installBorder(frame, "InternalFrame.paletteBorder");
161           ((MetalInternalFrameTitlePane)titlePane).setPalette( true );
162       }
163       else
164       {
165           LookAndFeel.installBorder(frame, "InternalFrame.border");
166           ((MetalInternalFrameTitlePane)titlePane).setPalette( false );
167       }
168   }
169 
170   /**
171    * If {@code isPalette} is {@code true}, sets palette border and title
172    *
173    * @param isPalette if {@code true}, sets palette border and title
174    */
175   // this should be deprecated - jcs
setPalette(boolean isPalette)176   public void setPalette(boolean isPalette) {
177     if (isPalette) {
178         LookAndFeel.installBorder(frame, "InternalFrame.paletteBorder");
179     } else {
180         LookAndFeel.installBorder(frame, "InternalFrame.border");
181     }
182     ((MetalInternalFrameTitlePane)titlePane).setPalette(isPalette);
183 
184   }
185 
186   private static class MetalPropertyChangeHandler implements
187         PropertyChangeListener
188   {
propertyChange(PropertyChangeEvent e)189       public void propertyChange(PropertyChangeEvent e)
190       {
191           String name = e.getPropertyName();
192           JInternalFrame jif = (JInternalFrame)e.getSource();
193 
194           if (!(jif.getUI() instanceof MetalInternalFrameUI)) {
195               return;
196           }
197 
198           MetalInternalFrameUI ui = (MetalInternalFrameUI)jif.getUI();
199 
200           if ( name.equals( FRAME_TYPE ) )
201           {
202               if ( e.getNewValue() instanceof String )
203               {
204                   ui.setFrameType( (String) e.getNewValue() );
205               }
206           }
207           else if ( name.equals(IS_PALETTE_KEY) )
208           {
209               if ( e.getNewValue() != null )
210               {
211                   ui.setPalette( ((Boolean)e.getNewValue()).booleanValue() );
212               }
213               else
214               {
215                   ui.setPalette( false );
216               }
217           } else if ( name.equals( JInternalFrame.CONTENT_PANE_PROPERTY ) ) {
218               ui.stripContentBorder(e.getNewValue());
219           }
220       }
221   } // end class MetalPropertyChangeHandler
222 
223 
224     private class BorderListener1 extends BorderListener implements SwingConstants
225     {
226 
getIconBounds()227         Rectangle getIconBounds() {
228             boolean leftToRight = MetalUtils.isLeftToRight(frame);
229             int xOffset = leftToRight ? 5 : titlePane.getWidth() - 5;
230             Rectangle rect = null;
231 
232             Icon icon = frame.getFrameIcon();
233             if ( icon != null ) {
234                 if ( !leftToRight ) {
235                     xOffset -= icon.getIconWidth();
236                 }
237                 int iconY = ((titlePane.getHeight() / 2) - (icon.getIconHeight() /2));
238                 rect = new Rectangle(xOffset, iconY,
239                     icon.getIconWidth(), icon.getIconHeight());
240             }
241             return rect;
242         }
243 
mouseClicked(MouseEvent e)244         public void mouseClicked(MouseEvent e) {
245             if (e.getClickCount() == 2 && e.getSource() == getNorthPane() &&
246                 frame.isClosable() && !frame.isIcon()) {
247                 Rectangle rect = getIconBounds();
248                 if ((rect != null) && rect.contains(e.getX(), e.getY())) {
249                     frame.doDefaultCloseAction();
250                 }
251                 else {
252                     super.mouseClicked(e);
253                 }
254             }
255             else {
256                 super.mouseClicked(e);
257             }
258         }
259     };    /// End BorderListener Class
260 
261 
262     /**
263      * Returns the <code>MouseInputAdapter</code> that will be installed
264      * on the TitlePane.
265      *
266      * @param w the <code>JInternalFrame</code>
267      * @return the <code>MouseInputAdapter</code> that will be installed
268      * on the TitlePane.
269      * @since 1.6
270      */
createBorderListener(JInternalFrame w)271     protected MouseInputAdapter createBorderListener(JInternalFrame w) {
272         return new BorderListener1();
273     }
274 }
275