1 /* 2 * Copyright (c) 2005, 2006, 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 sun.tools.jconsole; 27 28 import java.awt.*; 29 import java.awt.event.*; 30 import java.beans.*; 31 32 import javax.swing.*; 33 import javax.swing.border.*; 34 import javax.swing.text.*; 35 36 import static javax.swing.JOptionPane.*; 37 38 @SuppressWarnings("serial") 39 public final class SheetDialog { 40 // Reusable objects 41 private static Rectangle iconR = new Rectangle(); 42 private static Rectangle textR = new Rectangle(); 43 private static Rectangle viewR = new Rectangle(); 44 private static Insets viewInsets = new Insets(0, 0, 0, 0); 45 46 /** Don't let anyone instantiate this class */ SheetDialog()47 private SheetDialog() { 48 } 49 showOptionDialog(final VMPanel vmPanel, Object message, int optionType, int messageType, Icon icon, Object[] options, Object initialValue)50 static JOptionPane showOptionDialog(final VMPanel vmPanel, Object message, 51 int optionType, int messageType, 52 Icon icon, Object[] options, Object initialValue) { 53 54 JRootPane rootPane = SwingUtilities.getRootPane(vmPanel); 55 JPanel glassPane = (JPanel)rootPane.getGlassPane(); 56 57 if (!(glassPane instanceof SlideAndFadeGlassPane)) { 58 glassPane = new SlideAndFadeGlassPane(); 59 glassPane.setName(rootPane.getName()+".glassPane"); 60 rootPane.setGlassPane(glassPane); 61 rootPane.revalidate(); 62 } 63 64 final SlideAndFadeGlassPane safGlassPane = (SlideAndFadeGlassPane)glassPane; 65 66 // Workaround for the fact that JOptionPane does not handle 67 // limiting the width when using multi-line html messages. 68 // See Swing bug 5074006 and JConsole bug 6426317 69 message = fixWrapping(message, rootPane.getWidth() - 75); // Leave room for icon 70 71 final SheetOptionPane optionPane = new SheetOptionPane(message, messageType, optionType, 72 icon, options, initialValue); 73 74 optionPane.setComponentOrientation(vmPanel.getComponentOrientation()); 75 optionPane.addPropertyChangeListener(new PropertyChangeListener() { 76 public void propertyChange(PropertyChangeEvent event) { 77 if (event.getPropertyName().equals(VALUE_PROPERTY) && 78 event.getNewValue() != null && 79 event.getNewValue() != UNINITIALIZED_VALUE) { 80 ((SlideAndFadeGlassPane)optionPane.getParent()).hide(optionPane); 81 } 82 } 83 }); 84 85 // Delay this (even though we're already on the EDT) 86 EventQueue.invokeLater(new Runnable() { 87 public void run() { 88 safGlassPane.show(optionPane); 89 } 90 }); 91 92 return optionPane; 93 } 94 fixWrapping(Object message, final int maxWidth)95 private static Object fixWrapping(Object message, final int maxWidth) { 96 if (message instanceof Object[]) { 97 Object[] arr = (Object[])message; 98 for (int i = 0; i < arr.length; i++) { 99 arr[i] = fixWrapping(arr[i], maxWidth); 100 } 101 } else if (message instanceof String && 102 ((String)message).startsWith("<html>")) { 103 message = new JLabel((String)message) { 104 public Dimension getPreferredSize() { 105 String text = getText(); 106 Insets insets = getInsets(viewInsets); 107 FontMetrics fm = getFontMetrics(getFont()); 108 Dimension pref = super.getPreferredSize(); 109 Dimension min = getMinimumSize(); 110 111 iconR.x = iconR.y = iconR.width = iconR.height = 0; 112 textR.x = textR.y = textR.width = textR.height = 0; 113 int dx = insets.left + insets.right; 114 int dy = insets.top + insets.bottom; 115 viewR.x = dx; 116 viewR.y = dy; 117 viewR.width = viewR.height = Short.MAX_VALUE; 118 119 View v = (View)getClientProperty("html"); 120 if (v != null) { 121 // Use pref width if less than 300, otherwise 122 // min width up to size of window. 123 int w = Math.min(maxWidth, 124 Math.min(pref.width, 125 Math.max(min.width, 300))); 126 v.setSize((float)w, 0F); 127 128 SwingUtilities.layoutCompoundLabel(this, fm, text, null, 129 getVerticalAlignment(), 130 getHorizontalAlignment(), 131 getVerticalTextPosition(), 132 getHorizontalTextPosition(), 133 viewR, iconR, textR, 134 getIconTextGap()); 135 return new Dimension(textR.width + dx, 136 textR.height + dy); 137 } else { 138 return pref; // Should not happen 139 } 140 } 141 }; 142 } 143 return message; 144 } 145 146 private static class SlideAndFadeGlassPane extends JPanel { 147 SheetOptionPane optionPane; 148 149 int fade = 20; 150 boolean slideIn = true; 151 SlideAndFadeGlassPane()152 SlideAndFadeGlassPane() { 153 super(null); 154 setVisible(false); 155 setOpaque(false); 156 157 // Grab mouse input, making the dialog modal 158 addMouseListener(new MouseAdapter() {}); 159 } 160 show(SheetOptionPane optionPane)161 public void show(SheetOptionPane optionPane) { 162 this.optionPane = optionPane; 163 removeAll(); 164 add(optionPane); 165 setVisible(true); 166 slideIn = true; 167 revalidate(); 168 repaint(); 169 doSlide(); 170 } 171 hide(SheetOptionPane optionPane)172 public void hide(SheetOptionPane optionPane) { 173 if (optionPane != this.optionPane) { 174 return; 175 } 176 177 slideIn = false; 178 revalidate(); 179 repaint(); 180 doSlide(); 181 } 182 doSlide()183 private void doSlide() { 184 if (optionPane.getParent() == null) { 185 return; 186 } 187 188 if (optionPane.getWidth() == 0) { 189 optionPane.setSize(optionPane.getPreferredSize()); 190 } 191 192 int glassPaneWidth = getWidth(); 193 if (glassPaneWidth == 0 && getParent() != null) { 194 glassPaneWidth = getParent().getWidth(); 195 } 196 197 int x = (glassPaneWidth - optionPane.getWidth()) / 2; 198 199 if (!slideIn) { 200 remove(optionPane); 201 setVisible(false); 202 return; 203 } else { 204 optionPane.setLocation(x, 0); 205 setGrayLevel(fade); 206 return; 207 } 208 } 209 setGrayLevel(int gray)210 public void setGrayLevel(int gray) { 211 gray = gray * 255 / 100; 212 setBackground(new Color(0, 0, 0, gray)); 213 } 214 paint(Graphics g)215 public void paint(Graphics g) { 216 g.setColor(getBackground()); 217 g.fillRect(0, 0, getWidth(), getHeight()); 218 super.paint(g); 219 } 220 } 221 222 223 224 static class SheetOptionPane extends JOptionPane { SheetOptionPane(Object message, int messageType, int optionType, Icon icon, Object[] options, Object initialValue)225 SheetOptionPane(Object message, int messageType, int optionType, 226 Icon icon, Object[] options, Object initialValue) { 227 super(message, messageType, optionType, icon, options, initialValue); 228 229 setBorder(new CompoundBorder(new LineBorder(new Color(204, 204, 204), 1), 230 new EmptyBorder(4, 4, 4, 4))); 231 } 232 233 234 private static Composite comp = 235 AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8F); 236 237 private static Color bgColor = new Color(241, 239, 239); 238 setVisible(boolean visible)239 public void setVisible(boolean visible) { 240 SlideAndFadeGlassPane glassPane = (SlideAndFadeGlassPane)getParent(); 241 if (glassPane != null) { 242 if (visible) { 243 glassPane.show(this); 244 } else { 245 glassPane.hide(this); 246 } 247 } 248 } 249 paint(Graphics g)250 public void paint(Graphics g) { 251 Graphics2D g2d = (Graphics2D)g; 252 Composite oldComp = g2d.getComposite(); 253 g2d.setComposite(comp); 254 Color oldColor = g2d.getColor(); 255 g2d.setColor(bgColor); 256 g2d.fillRect(0, 0, getWidth(), getHeight()); 257 g2d.setColor(oldColor); 258 g2d.setComposite(oldComp); 259 super.paint(g); 260 } 261 } 262 263 } 264