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