|
1 /* |
|
2 * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
22 * CA 95054 USA or visit www.sun.com if you need additional information or |
|
23 * have any 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 */ |
|
47 private SheetDialog() { |
|
48 } |
|
49 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
210 public void setGrayLevel(int gray) { |
|
211 gray = gray * 255 / 100; |
|
212 setBackground(new Color(0, 0, 0, gray)); |
|
213 } |
|
214 |
|
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 { |
|
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 |
|
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 |
|
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 } |