Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.jconsole/share/classes/sun/tools/jconsole/BorderedComponent.java
40948 views
1
/*
2
* Copyright (c) 2004, 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 sun.tools.jconsole;
27
28
import java.awt.*;
29
import java.awt.event.*;
30
31
import javax.swing.*;
32
import javax.swing.border.*;
33
import javax.swing.plaf.*;
34
import javax.swing.plaf.basic.BasicGraphicsUtils;
35
36
37
import static javax.swing.SwingConstants.*;
38
39
import static sun.tools.jconsole.JConsole.*;
40
41
@SuppressWarnings("serial")
42
public class BorderedComponent extends JPanel implements ActionListener {
43
JButton moreOrLessButton;
44
String valueLabelStr;
45
JLabel label;
46
JComponent comp;
47
boolean collapsed = false;
48
49
private Icon collapseIcon;
50
private Icon expandIcon;
51
52
private static Image getImage(String name) {
53
Toolkit tk = Toolkit.getDefaultToolkit();
54
name = "resources/" + name + ".png";
55
return tk.getImage(BorderedComponent.class.getResource(name));
56
}
57
58
public BorderedComponent(String text) {
59
this(text, null, false);
60
}
61
62
public BorderedComponent(String text, JComponent comp) {
63
this(text, comp, false);
64
}
65
66
public BorderedComponent(String text, JComponent comp, boolean collapsible) {
67
super(null);
68
69
this.comp = comp;
70
71
// Only add border if text is not null
72
if (text != null) {
73
TitledBorder border;
74
if (collapsible) {
75
final JLabel textLabel = new JLabel(text);
76
JPanel borderLabel = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 0)) {
77
public int getBaseline(int w, int h) {
78
Dimension dim = textLabel.getPreferredSize();
79
return textLabel.getBaseline(dim.width, dim.height) + textLabel.getY();
80
}
81
};
82
borderLabel.add(textLabel);
83
border = new LabeledBorder(borderLabel);
84
textLabel.setForeground(border.getTitleColor());
85
86
if (IS_WIN) {
87
collapseIcon = new ImageIcon(getImage("collapse-winlf"));
88
expandIcon = new ImageIcon(getImage("expand-winlf"));
89
} else {
90
collapseIcon = new ArrowIcon(SOUTH, textLabel);
91
expandIcon = new ArrowIcon(EAST, textLabel);
92
}
93
94
moreOrLessButton = new JButton(collapseIcon);
95
moreOrLessButton.setContentAreaFilled(false);
96
moreOrLessButton.setBorderPainted(false);
97
moreOrLessButton.setMargin(new Insets(0, 0, 0, 0));
98
moreOrLessButton.addActionListener(this);
99
String toolTip =
100
Messages.BORDERED_COMPONENT_MORE_OR_LESS_BUTTON_TOOLTIP;
101
moreOrLessButton.setToolTipText(toolTip);
102
borderLabel.add(moreOrLessButton);
103
borderLabel.setSize(borderLabel.getPreferredSize());
104
add(borderLabel);
105
} else {
106
border = new TitledBorder(text);
107
}
108
setBorder(new CompoundBorder(new FocusBorder(this), border));
109
} else {
110
setBorder(new FocusBorder(this));
111
}
112
if (comp != null) {
113
add(comp);
114
}
115
}
116
117
public void setComponent(JComponent comp) {
118
if (this.comp != null) {
119
remove(this.comp);
120
}
121
this.comp = comp;
122
if (!collapsed) {
123
LayoutManager lm = getLayout();
124
if (lm instanceof BorderLayout) {
125
add(comp, BorderLayout.CENTER);
126
} else {
127
add(comp);
128
}
129
}
130
revalidate();
131
}
132
133
public void setValueLabel(String str) {
134
this.valueLabelStr = str;
135
if (label != null) {
136
label.setText(Resources.format(Messages.CURRENT_VALUE,
137
valueLabelStr));
138
}
139
}
140
141
public void actionPerformed(ActionEvent ev) {
142
if (collapsed) {
143
if (label != null) {
144
remove(label);
145
}
146
add(comp);
147
moreOrLessButton.setIcon(collapseIcon);
148
} else {
149
remove(comp);
150
if (valueLabelStr != null) {
151
if (label == null) {
152
label = new JLabel(Resources.format(Messages.CURRENT_VALUE,
153
valueLabelStr));
154
}
155
add(label);
156
}
157
moreOrLessButton.setIcon(expandIcon);
158
}
159
collapsed = !collapsed;
160
161
JComponent container = (JComponent)getParent();
162
if (container != null &&
163
container.getLayout() instanceof VariableGridLayout) {
164
165
((VariableGridLayout)container.getLayout()).setFillRow(this, !collapsed);
166
container.revalidate();
167
}
168
}
169
170
public Dimension getMinimumSize() {
171
if (getLayout() != null) {
172
// A layout manager has been set, so delegate to it
173
return super.getMinimumSize();
174
}
175
176
if (moreOrLessButton != null) {
177
Dimension d = moreOrLessButton.getMinimumSize();
178
Insets i = getInsets();
179
d.width += i.left + i.right;
180
d.height += i.top + i.bottom;
181
return d;
182
} else {
183
return super.getMinimumSize();
184
}
185
}
186
187
public void doLayout() {
188
if (getLayout() != null) {
189
// A layout manager has been set, so delegate to it
190
super.doLayout();
191
return;
192
}
193
194
Dimension d = getSize();
195
Insets i = getInsets();
196
197
if (collapsed) {
198
if (label != null) {
199
Dimension p = label.getPreferredSize();
200
label.setBounds(i.left,
201
i.top + (d.height - i.top - i.bottom - p.height) / 2,
202
p.width,
203
p.height);
204
}
205
} else {
206
if (comp != null) {
207
comp.setBounds(i.left,
208
i.top,
209
d.width - i.left - i.right,
210
d.height - i.top - i.bottom);
211
}
212
}
213
}
214
215
private static class ArrowIcon implements Icon {
216
private int direction;
217
private JLabel textLabel;
218
219
public ArrowIcon(int direction, JLabel textLabel) {
220
this.direction = direction;
221
this.textLabel = textLabel;
222
}
223
224
public void paintIcon(Component c, Graphics g, int x, int y) {
225
int w = getIconWidth();
226
int h = w;
227
Polygon p = new Polygon();
228
switch (direction) {
229
case EAST:
230
p.addPoint(x + 2, y);
231
p.addPoint(x + w - 2, y + h / 2);
232
p.addPoint(x + 2, y + h - 1);
233
break;
234
235
case SOUTH:
236
p.addPoint(x, y + 2);
237
p.addPoint(x + w / 2, y + h - 2);
238
p.addPoint(x + w - 1, y + 2);
239
break;
240
}
241
g.fillPolygon(p);
242
}
243
244
public int getIconWidth() {
245
return getIconHeight();
246
}
247
248
public int getIconHeight() {
249
Graphics g = textLabel.getGraphics();
250
if (g != null) {
251
int h = g.getFontMetrics(textLabel.getFont()).getAscent() * 6/10;
252
if (h % 2 == 0) {
253
h += 1; // Make it odd
254
}
255
return h;
256
} else {
257
return 7;
258
}
259
}
260
}
261
262
263
/**
264
* A subclass of <code>TitledBorder</code> which implements an arbitrary border
265
* with the addition of a JComponent (JLabel, JPanel, etc) in the
266
* default position.
267
* <p>
268
* If the border property value is not
269
* specified in the constructor or by invoking the appropriate
270
* set method, the property value will be defined by the current
271
* look and feel, using the following property name in the
272
* Defaults Table:
273
* <ul>
274
* <li>&quot;TitledBorder.border&quot;
275
* </ul>
276
*/
277
protected static class LabeledBorder extends TitledBorder {
278
protected JComponent label;
279
280
private Point compLoc = new Point();
281
282
/**
283
* Creates a LabeledBorder instance.
284
*
285
* @param label the label the border should display
286
*/
287
public LabeledBorder(JComponent label) {
288
this(null, label);
289
}
290
291
/**
292
* Creates a LabeledBorder instance with the specified border
293
* and an empty label.
294
*
295
* @param border the border
296
*/
297
public LabeledBorder(Border border) {
298
this(border, null);
299
}
300
301
/**
302
* Creates a LabeledBorder instance with the specified border and
303
* label.
304
*
305
* @param border the border
306
* @param label the label the border should display
307
*/
308
public LabeledBorder(Border border, JComponent label) {
309
super(border);
310
311
this.label = label;
312
313
if (label instanceof JLabel &&
314
label.getForeground() instanceof ColorUIResource) {
315
316
label.setForeground(getTitleColor());
317
}
318
319
}
320
321
/**
322
* Paints the border for the specified component with the
323
* specified position and size.
324
* @param c the component for which this border is being painted
325
* @param g the paint graphics
326
* @param x the x position of the painted border
327
* @param y the y position of the painted border
328
* @param width the width of the painted border
329
* @param height the height of the painted border
330
*/
331
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
332
333
Border border = getBorder();
334
335
if (label == null) {
336
if (border != null) {
337
border.paintBorder(c, g, x, y, width, height);
338
}
339
return;
340
}
341
342
Rectangle grooveRect = new Rectangle(x + EDGE_SPACING, y + EDGE_SPACING,
343
width - (EDGE_SPACING * 2),
344
height - (EDGE_SPACING * 2));
345
346
Dimension labelDim = label.getPreferredSize();
347
int baseline = label.getBaseline(labelDim.width, labelDim.height);
348
int ascent = Math.max(0, baseline);
349
int descent = labelDim.height - ascent;
350
int diff;
351
Insets insets;
352
353
if (border != null) {
354
insets = border.getBorderInsets(c);
355
} else {
356
insets = new Insets(0, 0, 0, 0);
357
}
358
359
diff = Math.max(0, ascent/2 + TEXT_SPACING - EDGE_SPACING);
360
grooveRect.y += diff;
361
grooveRect.height -= diff;
362
compLoc.y = grooveRect.y + insets.top/2 - (ascent + descent) / 2 - 1;
363
364
int justification;
365
if (c.getComponentOrientation().isLeftToRight()) {
366
justification = LEFT;
367
} else {
368
justification = RIGHT;
369
}
370
371
switch (justification) {
372
case LEFT:
373
compLoc.x = grooveRect.x + TEXT_INSET_H + insets.left;
374
break;
375
case RIGHT:
376
compLoc.x = (grooveRect.x + grooveRect.width
377
- (labelDim.width + TEXT_INSET_H + insets.right));
378
break;
379
}
380
381
// If title is positioned in middle of border AND its fontsize
382
// is greater than the border's thickness, we'll need to paint
383
// the border in sections to leave space for the component's background
384
// to show through the title.
385
//
386
if (border != null) {
387
if (grooveRect.y > compLoc.y - ascent) {
388
Rectangle clipRect = new Rectangle();
389
390
// save original clip
391
Rectangle saveClip = g.getClipBounds();
392
393
// paint strip left of text
394
clipRect.setBounds(saveClip);
395
if (computeIntersection(clipRect, x, y, compLoc.x-1-x, height)) {
396
g.setClip(clipRect);
397
border.paintBorder(c, g, grooveRect.x, grooveRect.y,
398
grooveRect.width, grooveRect.height);
399
}
400
401
// paint strip right of text
402
clipRect.setBounds(saveClip);
403
if (computeIntersection(clipRect, compLoc.x+ labelDim.width +1, y,
404
x+width-(compLoc.x+ labelDim.width +1), height)) {
405
g.setClip(clipRect);
406
border.paintBorder(c, g, grooveRect.x, grooveRect.y,
407
grooveRect.width, grooveRect.height);
408
}
409
410
// paint strip below text
411
clipRect.setBounds(saveClip);
412
if (computeIntersection(clipRect,
413
compLoc.x - 1, compLoc.y + ascent + descent,
414
labelDim.width + 2,
415
y + height - compLoc.y - ascent - descent)) {
416
g.setClip(clipRect);
417
border.paintBorder(c, g, grooveRect.x, grooveRect.y,
418
grooveRect.width, grooveRect.height);
419
}
420
421
// restore clip
422
g.setClip(saveClip);
423
424
} else {
425
border.paintBorder(c, g, grooveRect.x, grooveRect.y,
426
grooveRect.width, grooveRect.height);
427
}
428
429
label.setLocation(compLoc);
430
label.setSize(labelDim);
431
}
432
}
433
434
/**
435
* Reinitialize the insets parameter with this Border's current Insets.
436
* @param c the component for which this border insets value applies
437
* @param insets the object to be reinitialized
438
*/
439
public Insets getBorderInsets(Component c, Insets insets) {
440
Border border = getBorder();
441
if (border != null) {
442
if (border instanceof AbstractBorder) {
443
((AbstractBorder)border).getBorderInsets(c, insets);
444
} else {
445
// Can't reuse border insets because the Border interface
446
// can't be enhanced.
447
Insets i = border.getBorderInsets(c);
448
insets.top = i.top;
449
insets.right = i.right;
450
insets.bottom = i.bottom;
451
insets.left = i.left;
452
}
453
} else {
454
insets.left = insets.top = insets.right = insets.bottom = 0;
455
}
456
457
insets.left += EDGE_SPACING + TEXT_SPACING;
458
insets.right += EDGE_SPACING + TEXT_SPACING;
459
insets.top += EDGE_SPACING + TEXT_SPACING;
460
insets.bottom += EDGE_SPACING + TEXT_SPACING;
461
462
if (c == null || label == null) {
463
return insets;
464
}
465
466
insets.top += label.getHeight();
467
468
return insets;
469
}
470
471
/**
472
* Returns the label of the labeled border.
473
*/
474
public JComponent getLabel() {
475
return label;
476
}
477
478
479
/**
480
* Sets the title of the titled border.
481
* param title the title for the border
482
*/
483
public void setLabel(JComponent label) {
484
this.label = label;
485
}
486
487
488
489
/**
490
* Returns the minimum dimensions this border requires
491
* in order to fully display the border and title.
492
* @param c the component where this border will be drawn
493
*/
494
public Dimension getMinimumSize(Component c) {
495
Insets insets = getBorderInsets(c);
496
Dimension minSize = new Dimension(insets.right + insets.left,
497
insets.top + insets.bottom);
498
minSize.width += label.getWidth();
499
500
return minSize;
501
}
502
503
504
private static boolean computeIntersection(Rectangle dest,
505
int rx, int ry, int rw, int rh) {
506
int x1 = Math.max(rx, dest.x);
507
int x2 = Math.min(rx + rw, dest.x + dest.width);
508
int y1 = Math.max(ry, dest.y);
509
int y2 = Math.min(ry + rh, dest.y + dest.height);
510
dest.x = x1;
511
dest.y = y1;
512
dest.width = x2 - x1;
513
dest.height = y2 - y1;
514
515
if (dest.width <= 0 || dest.height <= 0) {
516
return false;
517
}
518
return true;
519
}
520
}
521
522
523
protected static class FocusBorder extends AbstractBorder implements FocusListener {
524
private Component comp;
525
private Color focusColor;
526
private boolean focusLostTemporarily = false;
527
528
public FocusBorder(Component comp) {
529
this.comp = comp;
530
531
comp.addFocusListener(this);
532
533
// This is the best guess for a L&F specific color
534
focusColor = UIManager.getColor("TabbedPane.focus");
535
}
536
537
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
538
if (comp.hasFocus() || focusLostTemporarily) {
539
Color color = g.getColor();
540
g.setColor(focusColor);
541
BasicGraphicsUtils.drawDashedRect(g, x, y, width, height);
542
g.setColor(color);
543
}
544
}
545
546
public Insets getBorderInsets(Component c, Insets insets) {
547
insets.set(2, 2, 2, 2);
548
return insets;
549
}
550
551
552
public void focusGained(FocusEvent e) {
553
comp.repaint();
554
}
555
556
public void focusLost(FocusEvent e) {
557
// We will still paint focus even if lost temporarily
558
focusLostTemporarily = e.isTemporary();
559
if (!focusLostTemporarily) {
560
comp.repaint();
561
}
562
}
563
}
564
}
565
566