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