blob: ce41a11076916b3863015f3089f57f50ed7612ba [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
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
26package sun.tools.jconsole;
27
28import java.awt.*;
29import java.awt.event.*;
30import java.beans.*;
31
32import javax.swing.*;
33import javax.swing.border.*;
34import javax.swing.text.*;
35
36import static javax.swing.JOptionPane.*;
37
38@SuppressWarnings("serial")
39public 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}