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