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
26package javax.swing.plaf.metal;
27
28import java.awt.*;
29import java.awt.event.*;
30import javax.swing.*;
31import javax.swing.event.*;
32import javax.swing.border.*;
33import javax.swing.plaf.basic.*;
34import java.beans.PropertyChangeListener;
35import java.beans.PropertyChangeEvent;
36import javax.swing.plaf.*;
37
38/**
39 * Metal implementation of JInternalFrame.
40 *
41 * @author Steve Wilson
42 */
43public 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   */
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   */
76  public static ComponentUI createUI(JComponent c)    {
77      return new MetalInternalFrameUI( (JInternalFrame) c);
78  }
79
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
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
106    protected void installListeners() {
107        super.installListeners();
108        frame.addPropertyChangeListener(metalPropertyChangeListener);
109    }
110
111    protected void uninstallListeners() {
112        frame.removePropertyChangeListener(metalPropertyChangeListener);
113        super.uninstallListeners();
114    }
115
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
126  protected void uninstallKeyboardActions(){
127      super.uninstallKeyboardActions();
128  }
129
130    protected void uninstallComponents() {
131        titlePane = null;
132        super.uninstallComponents();
133    }
134
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
146  protected JComponent createNorthPane(JInternalFrame w) {
147      return new MetalInternalFrameTitlePane(w);
148  }
149
150
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
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  {
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
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
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     */
271    protected MouseInputAdapter createBorderListener(JInternalFrame w) {
272        return new BorderListener1();
273    }
274}
275