History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/tools/jconsole/BorderedComponent.java (1 of 18352 files). Show all

Unified · Split

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