1 /* 2 * Copyright (c) 1997, 2014, 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 com.sun.java.swing.plaf.motif; 27 28 import java.awt.*; 29 import java.awt.event.*; 30 import javax.swing.*; 31 import javax.swing.border.*; 32 import javax.swing.event.InternalFrameEvent; 33 import javax.swing.plaf.basic.*; 34 import java.util.EventListener; 35 import java.beans.PropertyChangeListener; 36 import java.beans.PropertyChangeEvent; 37 import java.beans.VetoableChangeListener; 38 import java.beans.PropertyVetoException; 39 40 /** 41 * Class that manages a Motif title bar 42 * 43 * @since 1.3 44 */ 45 @SuppressWarnings("serial") // Superclass is not serializable across versions 46 public class MotifInternalFrameTitlePane 47 extends BasicInternalFrameTitlePane implements LayoutManager, ActionListener, PropertyChangeListener 48 { 49 SystemButton systemButton; 50 MinimizeButton minimizeButton; 51 MaximizeButton maximizeButton; 52 JPopupMenu systemMenu; 53 Title title; 54 Color color; 55 Color highlight; 56 Color shadow; 57 58 // The width and height of a title pane button 59 public final static int BUTTON_SIZE = 19; // 17 + 1 pixel border 60 61 62 public MotifInternalFrameTitlePane(JInternalFrame frame) { 63 super(frame); 64 } 65 66 protected void installDefaults() { 67 setFont(UIManager.getFont("InternalFrame.titleFont")); 68 setPreferredSize(new Dimension(100, BUTTON_SIZE)); 69 } 70 71 protected void uninstallListeners() { 72 // Get around protected method in superclass 73 super.uninstallListeners(); 74 } 75 76 protected PropertyChangeListener createPropertyChangeListener() { 77 return this; 78 } 79 80 protected LayoutManager createLayout() { 81 return this; 82 } 83 84 JPopupMenu getSystemMenu() { 85 return systemMenu; 86 } 87 88 protected void assembleSystemMenu() { 89 systemMenu = new JPopupMenu(); 90 JMenuItem mi = systemMenu.add(restoreAction); 91 mi.setMnemonic(getButtonMnemonic("restore")); 92 mi = systemMenu.add(moveAction); 93 mi.setMnemonic(getButtonMnemonic("move")); 94 mi = systemMenu.add(sizeAction); 95 mi.setMnemonic(getButtonMnemonic("size")); 96 mi = systemMenu.add(iconifyAction); 97 mi.setMnemonic(getButtonMnemonic("minimize")); 98 mi = systemMenu.add(maximizeAction); 99 mi.setMnemonic(getButtonMnemonic("maximize")); 100 systemMenu.add(new JSeparator()); 101 mi = systemMenu.add(closeAction); 102 mi.setMnemonic(getButtonMnemonic("close")); 103 104 systemButton = new SystemButton(); 105 systemButton.addActionListener(new ActionListener() { 106 public void actionPerformed(ActionEvent e) { 107 systemMenu.show(systemButton, 0, BUTTON_SIZE); 108 } 109 }); 110 111 systemButton.addMouseListener(new MouseAdapter() { 112 public void mousePressed(MouseEvent evt) { 113 try { 114 frame.setSelected(true); 115 } catch (PropertyVetoException pve) { 116 } 117 if ((evt.getClickCount() == 2)) { 118 closeAction.actionPerformed(new 119 ActionEvent(evt.getSource(), 120 ActionEvent.ACTION_PERFORMED, 121 null, evt.getWhen(), 0)); 122 systemMenu.setVisible(false); 123 } 124 } 125 }); 126 } 127 128 private static int getButtonMnemonic(String button) { 129 try { 130 return Integer.parseInt(UIManager.getString( 131 "InternalFrameTitlePane." + button + "Button.mnemonic")); 132 } catch (NumberFormatException e) { 133 return -1; 134 } 135 } 136 137 protected void createButtons() { 138 minimizeButton = new MinimizeButton(); 139 minimizeButton.addActionListener(iconifyAction); 140 141 maximizeButton = new MaximizeButton(); 142 maximizeButton.addActionListener(maximizeAction); 143 } 144 145 146 protected void addSubComponents() { 147 title = new Title(frame.getTitle()); 148 title.setFont(getFont()); 149 150 add(systemButton); 151 add(title); 152 add(minimizeButton); 153 add(maximizeButton); 154 } 155 156 public void paintComponent(Graphics g) { 157 } 158 159 void setColors(Color c, Color h, Color s) { 160 color = c; 161 highlight = h; 162 shadow = s; 163 } 164 165 public void actionPerformed(ActionEvent e) { 166 } 167 168 public void propertyChange(PropertyChangeEvent evt) { 169 String prop = evt.getPropertyName(); 170 JInternalFrame f = (JInternalFrame)evt.getSource(); 171 boolean value = false; 172 if (JInternalFrame.IS_SELECTED_PROPERTY.equals(prop)) { 173 repaint(); 174 } else if (prop.equals("maximizable")) { 175 if ((Boolean)evt.getNewValue() == Boolean.TRUE) 176 add(maximizeButton); 177 else 178 remove(maximizeButton); 179 revalidate(); 180 repaint(); 181 } else if (prop.equals("iconable")) { 182 if ((Boolean)evt.getNewValue() == Boolean.TRUE) 183 add(minimizeButton); 184 else 185 remove(minimizeButton); 186 revalidate(); 187 repaint(); 188 } else if (prop.equals(JInternalFrame.TITLE_PROPERTY)) { 189 repaint(); 190 } 191 enableActions(); 192 } 193 194 public void addLayoutComponent(String name, Component c) {} 195 public void removeLayoutComponent(Component c) {} 196 public Dimension preferredLayoutSize(Container c) { 197 return minimumLayoutSize(c); 198 } 199 200 public Dimension minimumLayoutSize(Container c) { 201 return new Dimension(100, BUTTON_SIZE); 202 } 203 204 public void layoutContainer(Container c) { 205 int w = getWidth(); 206 systemButton.setBounds(0, 0, BUTTON_SIZE, BUTTON_SIZE); 207 int x = w - BUTTON_SIZE; 208 209 if(frame.isMaximizable()) { 210 maximizeButton.setBounds(x, 0, BUTTON_SIZE, BUTTON_SIZE); 211 x -= BUTTON_SIZE; 212 } else if(maximizeButton.getParent() != null) { 213 maximizeButton.getParent().remove(maximizeButton); 214 } 215 216 if(frame.isIconifiable()) { 217 minimizeButton.setBounds(x, 0, BUTTON_SIZE, BUTTON_SIZE); 218 x -= BUTTON_SIZE; 219 } else if(minimizeButton.getParent() != null) { 220 minimizeButton.getParent().remove(minimizeButton); 221 } 222 223 title.setBounds(BUTTON_SIZE, 0, x, BUTTON_SIZE); 224 } 225 226 protected void showSystemMenu(){ 227 systemMenu.show(systemButton, 0, BUTTON_SIZE); 228 } 229 230 protected void hideSystemMenu(){ 231 systemMenu.setVisible(false); 232 } 233 234 static Dimension buttonDimension = new Dimension(BUTTON_SIZE, BUTTON_SIZE); 235 236 @SuppressWarnings("serial") // Superclass is not serializable across versions 237 private abstract class FrameButton extends JButton { 238 239 FrameButton() { 240 super(); 241 setFocusPainted(false); 242 setBorderPainted(false); 243 } 244 245 public boolean isFocusTraversable() { 246 return false; 247 } 248 249 public void requestFocus() { 250 // ignore request. 251 } 252 253 public Dimension getMinimumSize() { 254 return buttonDimension; 255 } 256 257 public Dimension getPreferredSize() { 258 return buttonDimension; 259 } 260 261 public void paintComponent(Graphics g) { 262 Dimension d = getSize(); 263 int maxX = d.width - 1; 264 int maxY = d.height - 1; 265 266 // draw background 267 g.setColor(color); 268 g.fillRect(1, 1, d.width, d.height); 269 270 // draw border 271 boolean pressed = getModel().isPressed(); 272 g.setColor(pressed ? shadow : highlight); 273 g.drawLine(0, 0, maxX, 0); 274 g.drawLine(0, 0, 0, maxY); 275 g.setColor(pressed ? highlight : shadow); 276 g.drawLine(1, maxY, maxX, maxY); 277 g.drawLine(maxX, 1, maxX, maxY); 278 } 279 } 280 281 @SuppressWarnings("serial") // Superclass is not serializable across versions 282 private class MinimizeButton extends FrameButton { 283 public void paintComponent(Graphics g) { 284 super.paintComponent(g); 285 g.setColor(highlight); 286 g.drawLine(7, 8, 7, 11); 287 g.drawLine(7, 8, 10, 8); 288 g.setColor(shadow); 289 g.drawLine(8, 11, 10, 11); 290 g.drawLine(11, 9, 11, 11); 291 } 292 } 293 294 @SuppressWarnings("serial") // Superclass is not serializable across versions 295 private class MaximizeButton extends FrameButton { 296 public void paintComponent(Graphics g) { 297 super.paintComponent(g); 298 int max = BUTTON_SIZE - 5; 299 boolean isMaxed = frame.isMaximum(); 300 g.setColor(isMaxed ? shadow : highlight); 301 g.drawLine(4, 4, 4, max); 302 g.drawLine(4, 4, max, 4); 303 g.setColor(isMaxed ? highlight : shadow); 304 g.drawLine(5, max, max, max); 305 g.drawLine(max, 5, max, max); 306 } 307 } 308 309 @SuppressWarnings("serial") // Superclass is not serializable across versions 310 private class SystemButton extends FrameButton { 311 public boolean isFocusTraversable() { return false; } 312 public void requestFocus() {} 313 314 public void paintComponent(Graphics g) { 315 super.paintComponent(g); 316 g.setColor(highlight); 317 g.drawLine(4, 8, 4, 11); 318 g.drawLine(4, 8, BUTTON_SIZE - 5, 8); 319 g.setColor(shadow); 320 g.drawLine(5, 11, BUTTON_SIZE - 5, 11); 321 g.drawLine(BUTTON_SIZE - 5, 9, BUTTON_SIZE - 5, 11); 322 } 323 } 324 325 @SuppressWarnings("serial") // Superclass is not serializable across versions 326 private class Title extends FrameButton { 327 Title(String title) { 328 super(); 329 setText(title); 330 setHorizontalAlignment(SwingConstants.CENTER); 331 setBorder(BorderFactory.createBevelBorder( 332 BevelBorder.RAISED, 333 UIManager.getColor("activeCaptionBorder"), 334 UIManager.getColor("inactiveCaptionBorder"))); 335 336 // Forward mouse events to titlebar for moves. 337 addMouseMotionListener(new MouseMotionListener() { 338 public void mouseDragged(MouseEvent e) { 339 forwardEventToParent(e); 340 } 341 public void mouseMoved(MouseEvent e) { 342 forwardEventToParent(e); 343 } 344 }); 345 addMouseListener(new MouseListener() { 346 public void mouseClicked(MouseEvent e) { 347 forwardEventToParent(e); 348 } 349 public void mousePressed(MouseEvent e) { 350 forwardEventToParent(e); 351 } 352 public void mouseReleased(MouseEvent e) { 353 forwardEventToParent(e); 354 } 355 public void mouseEntered(MouseEvent e) { 356 forwardEventToParent(e); 357 } 358 public void mouseExited(MouseEvent e) { 359 forwardEventToParent(e); 360 } 361 }); 362 } 363 364 void forwardEventToParent(MouseEvent e) { 365 getParent().dispatchEvent(new MouseEvent( 366 getParent(), e.getID(), e.getWhen(), e.getModifiers(), 367 e.getX(), e.getY(), e.getXOnScreen(), 368 e.getYOnScreen(), e.getClickCount(), 369 e.isPopupTrigger(), MouseEvent.NOBUTTON)); 370 } 371 372 public void paintComponent(Graphics g) { 373 super.paintComponent(g); 374 if (frame.isSelected()) { 375 g.setColor(UIManager.getColor("activeCaptionText")); 376 } else { 377 g.setColor(UIManager.getColor("inactiveCaptionText")); 378 } 379 Dimension d = getSize(); 380 String frameTitle = frame.getTitle(); 381 if (frameTitle != null) { 382 MotifGraphicsUtils.drawStringInRect(frame, g, frameTitle, 383 0, 0, d.width, d.height, 384 SwingConstants.CENTER); 385 } 386 } 387 } 388 }