001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: * The Original Software is NetBeans. The Initial Developer of the Original
026: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
027: * Microsystems, Inc. All Rights Reserved.
028: *
029: * If you wish your version of this file to be governed by only the CDDL
030: * or only the GPL Version 2, indicate your decision by adding
031: * "[Contributor] elects to include this software in this distribution
032: * under the [CDDL or GPL Version 2] license." If you do not indicate a
033: * single choice of license, a recipient has the option to distribute
034: * your version of this file under either the CDDL, the GPL Version 2 or
035: * to extend the choice of license to its licensees as provided above.
036: * However, if you add GPL Version 2 code and therefore, elected the GPL
037: * Version 2 license, then the option applies only if the new code is
038: * made subject to such option by the copyright holder.
039: */
040:
041: package org.netbeans.lib.profiler.ui.components;
042:
043: import java.awt.BorderLayout;
044: import java.awt.Color;
045: import java.awt.Component;
046: import java.awt.Dimension;
047: import java.awt.FlowLayout;
048: import java.awt.Graphics;
049: import java.awt.GridBagConstraints;
050: import java.awt.GridBagLayout;
051: import java.awt.Insets;
052: import java.awt.LayoutManager;
053: import java.awt.MenuComponent;
054: import java.awt.PopupMenu;
055: import java.awt.Toolkit;
056: import java.awt.event.ActionEvent;
057: import java.awt.event.ActionListener;
058: import java.awt.event.ComponentAdapter;
059: import java.awt.event.ComponentEvent;
060: import java.awt.event.InputEvent;
061: import java.awt.event.MouseAdapter;
062: import java.awt.event.MouseEvent;
063: import java.awt.event.MouseListener;
064: import java.awt.image.FilteredImageSource;
065: import java.awt.image.ImageProducer;
066: import java.beans.PropertyChangeEvent;
067: import java.beans.PropertyChangeListener;
068: import java.util.Vector;
069: import javax.swing.AbstractButton;
070: import javax.swing.BorderFactory;
071: import javax.swing.GrayFilter;
072: import javax.swing.Icon;
073: import javax.swing.ImageIcon;
074: import javax.swing.JButton;
075: import javax.swing.JLabel;
076: import javax.swing.JPanel;
077: import javax.swing.JToggleButton;
078: import javax.swing.UIManager;
079: import javax.swing.border.BevelBorder;
080: import javax.swing.border.Border;
081:
082: /**
083: *
084: * @author Jiri Sedlacek
085: */
086: public class JTitledPanel extends JPanel {
087: //~ Inner Classes ------------------------------------------------------------------------------------------------------------
088:
089: private static class ThinBevelBorder extends BevelBorder {
090: //~ Constructors ---------------------------------------------------------------------------------------------------------
091:
092: public ThinBevelBorder(int bevelType, Color highlight,
093: Color shadow) {
094: super (bevelType, highlight.brighter(), highlight, shadow,
095: shadow.brighter());
096: }
097:
098: //~ Methods --------------------------------------------------------------------------------------------------------------
099:
100: public Insets getBorderInsets(Component c) {
101: return new Insets(1, 1, 1, 1);
102: }
103:
104: public Insets getBorderInsets(Component c, Insets insets) {
105: insets.left = insets.top = insets.right = insets.bottom = 1;
106:
107: return insets;
108: }
109:
110: protected void paintLoweredBevel(Component c, Graphics g,
111: int x, int y, int width, int height) {
112: if (!c.isEnabled()) {
113: return;
114: }
115:
116: Color oldColor = g.getColor();
117: int h = height;
118: int w = width;
119:
120: g.translate(x, y);
121:
122: g.setColor(getShadowOuterColor(c));
123: g.drawLine(0, 0, 0, h - 1);
124: g.drawLine(1, 0, w - 1, 0);
125:
126: g.setColor(getHighlightInnerColor(c));
127: g.drawLine(1, h - 1, w - 1, h - 1);
128: g.drawLine(w - 1, 1, w - 1, h - 2);
129:
130: g.translate(-x, -y);
131: g.setColor(oldColor);
132: }
133:
134: protected void paintRaisedBevel(Component c, Graphics g, int x,
135: int y, int width, int height) {
136: if (!c.isEnabled()) {
137: return;
138: }
139:
140: Color oldColor = g.getColor();
141: int h = height;
142: int w = width;
143:
144: g.translate(x, y);
145:
146: g.setColor(getHighlightInnerColor(c));
147: g.drawLine(0, 0, 0, h - 1);
148: g.drawLine(1, 0, w - 1, 0);
149:
150: g.setColor(getShadowOuterColor(c));
151: g.drawLine(0, h - 1, w - 1, h - 1);
152: g.drawLine(w - 1, 0, w - 1, h - 2);
153:
154: g.translate(-x, -y);
155: g.setColor(oldColor);
156: }
157: }
158:
159: private class DoubleClickListener extends MouseAdapter {
160: //~ Methods --------------------------------------------------------------------------------------------------------------
161:
162: public void mouseClicked(MouseEvent e) {
163: if ((e.getModifiers() == InputEvent.BUTTON1_MASK)
164: && (e.getClickCount() == 2)) {
165: if (isMaximized()) {
166: restore();
167: } else {
168: maximize();
169: }
170: }
171:
172: ;
173: }
174: }
175:
176: private class ImageIconButton extends JButton implements
177: MouseListener {
178: //~ Instance fields ------------------------------------------------------------------------------------------------------
179:
180: private Border emptyBorder = BorderFactory.createEmptyBorder(1,
181: 1, 1, 1);
182: private Border loweredBorder = new ThinBevelBorder(
183: BevelBorder.LOWERED, Color.WHITE, Color.GRAY);
184: private Border raisedBorder = new ThinBevelBorder(
185: BevelBorder.RAISED, Color.WHITE, Color.GRAY);
186: private boolean focused = false;
187: private boolean pressed = false;
188:
189: //~ Constructors ---------------------------------------------------------------------------------------------------------
190:
191: public ImageIconButton(ImageIcon icon) {
192: super ();
193:
194: GrayFilter enabledFilter = new GrayFilter(true, 35);
195: ImageProducer prod = new FilteredImageSource(icon
196: .getImage().getSource(), enabledFilter);
197: Icon grayIcon = new ImageIcon(Toolkit.getDefaultToolkit()
198: .createImage(prod));
199: GrayFilter disabledFilter = new GrayFilter(true, 60);
200: prod = new FilteredImageSource(icon.getImage().getSource(),
201: disabledFilter);
202:
203: Icon disabledIcon = new ImageIcon(Toolkit
204: .getDefaultToolkit().createImage(prod));
205:
206: setIcon(grayIcon);
207: setRolloverIcon(icon);
208: setPressedIcon(icon);
209: setDisabledIcon(disabledIcon);
210: setIconTextGap(0);
211: setBorder(emptyBorder);
212: setFocusable(false);
213: setContentAreaFilled(false);
214:
215: setPreferredSize(new Dimension(icon.getIconWidth() + 8,
216: icon.getIconHeight() + 8));
217:
218: addMouseListener(this );
219: }
220:
221: //~ Methods --------------------------------------------------------------------------------------------------------------
222:
223: public void mouseClicked(MouseEvent e) {
224: }
225:
226: public void mouseEntered(MouseEvent e) {
227: focused = true;
228:
229: if (pressed) {
230: setBorder(loweredBorder);
231: } else {
232: setBorder(raisedBorder);
233: }
234: }
235:
236: public void mouseExited(MouseEvent e) {
237: focused = false;
238: setBorder(emptyBorder);
239: }
240:
241: public void mousePressed(MouseEvent e) {
242: pressed = true;
243: setBorder(loweredBorder);
244: }
245:
246: public void mouseReleased(MouseEvent e) {
247: pressed = false;
248:
249: if (focused) {
250: setBorder(raisedBorder);
251: } else {
252: setBorder(emptyBorder);
253: }
254: }
255: }
256:
257: // --- Presenter -------------------------------------------------------------
258: private class Presenter extends JToggleButton {
259: //~ Constructors ---------------------------------------------------------------------------------------------------------
260:
261: public Presenter() {
262: super ();
263:
264: if (JTitledPanel.this .getIcon() == null) {
265: setText(JTitledPanel.this .getTitle());
266: setToolTipText(JTitledPanel.this .getTitle());
267: } else {
268: setIcon(JTitledPanel.this .getIcon());
269: setToolTipText(JTitledPanel.this .getTitle());
270: }
271:
272: setSelected(JTitledPanel.this .isVisible());
273: addActionListener(new ActionListener() {
274: public void actionPerformed(ActionEvent e) {
275: JTitledPanel.this .setVisible(isSelected());
276: }
277: });
278: JTitledPanel.this
279: .addComponentListener(new ComponentAdapter() {
280: public void componentShown(ComponentEvent e) {
281: setSelected(true);
282: }
283:
284: public void componentHidden(ComponentEvent e) {
285: setSelected(false);
286: }
287: });
288: addPropertyChangeListener(new PropertyChangeListener() {
289: public void propertyChange(PropertyChangeEvent evt) {
290: if ("enabled".equals(evt.getPropertyName())) {
291: JTitledPanel.this
292: .setButtonsEnabled(isEnabled()); // NOI18N
293: }
294: }
295: });
296: }
297: }
298:
299: //~ Static fields/initializers -----------------------------------------------------------------------------------------------
300:
301: private static final ImageIcon closePanelIcon = new ImageIcon(
302: JTitledPanel.class
303: .getResource("/org/netbeans/lib/profiler/ui/resources/closePanel.png")); // NOI18N
304: private static final ImageIcon maximizePanelIcon = new ImageIcon(
305: JTitledPanel.class
306: .getResource("/org/netbeans/lib/profiler/ui/resources/maximizePanel.png")); // NOI18N
307: private static final ImageIcon restorePanelIcon = new ImageIcon(
308: JTitledPanel.class
309: .getResource("/org/netbeans/lib/profiler/ui/resources/restorePanel.png")); // NOI18N
310: private static final ImageIcon minimizePanelIcon = new ImageIcon(
311: JTitledPanel.class
312: .getResource("/org/netbeans/lib/profiler/ui/resources/minimizePanel.png")); // NOI18N
313: public static final int STATE_CLOSED = 1000;
314: public static final int STATE_RESTORED = 1001;
315: public static final int STATE_MAXIMIZED = 1002;
316: public static final int STATE_MINIMIZED = 1003;
317:
318: //~ Instance fields ----------------------------------------------------------------------------------------------------------
319:
320: private AbstractButton presenter;
321: private Icon icon;
322: private JButton closePanelButton;
323: private JButton maximizePanelButton;
324: private JButton minimizePanelButton;
325: private JButton restorePanelButton;
326: private JPanel contentPanel;
327: private JPanel titlePanel;
328: private String title;
329: private Vector actionListeners;
330: private boolean showButtons;
331: private int state;
332:
333: //~ Constructors -------------------------------------------------------------------------------------------------------------
334:
335: public JTitledPanel(String title) {
336: this (title, null);
337: }
338:
339: public JTitledPanel(String title, Icon icon) {
340: this (title, icon, false);
341: }
342:
343: public JTitledPanel(String title, Icon icon, boolean showButtons) {
344: super ();
345: actionListeners = new Vector();
346: this .title = title;
347: this .icon = icon;
348: this .showButtons = showButtons;
349: initComponents();
350: restore();
351: }
352:
353: //~ Methods ------------------------------------------------------------------------------------------------------------------
354:
355: public void setButtonsEnabled(boolean enabled) {
356: closePanelButton.setEnabled(enabled);
357: maximizePanelButton.setEnabled(enabled);
358: restorePanelButton.setEnabled(enabled);
359: minimizePanelButton.setEnabled(enabled);
360: }
361:
362: public boolean isClosed() {
363: return getState() == STATE_CLOSED;
364: }
365:
366: public JPanel getContentPanel() {
367: if (contentPanel == null) {
368: contentPanel = new JPanel();
369: }
370:
371: return contentPanel;
372: }
373:
374: public Icon getIcon() {
375: return icon;
376: }
377:
378: public void setLayout(LayoutManager mgr) {
379: getContentPanel().setLayout(mgr);
380: }
381:
382: public LayoutManager getLayout() {
383: return getContentPanel().getLayout();
384: }
385:
386: public boolean isMaximized() {
387: return getState() == STATE_MAXIMIZED;
388: }
389:
390: public boolean isMinimized() {
391: return getState() == STATE_MINIMIZED;
392: }
393:
394: public Dimension getMinimumSize() {
395: return new Dimension(0, titlePanel.getPreferredSize().height);
396: }
397:
398: public AbstractButton getPresenter() {
399: if (presenter == null) {
400: presenter = new Presenter();
401: }
402:
403: return presenter;
404: }
405:
406: public boolean isRestored() {
407: return getState() == STATE_RESTORED;
408: }
409:
410: public int getState() {
411: if (!isVisible()) {
412: state = STATE_CLOSED;
413: }
414:
415: if (isVisible() && (state == STATE_CLOSED)) {
416: state = STATE_RESTORED;
417: }
418:
419: return state;
420: }
421:
422: public String getTitle() {
423: return title;
424: }
425:
426: public Component add(Component comp) {
427: return getContentPanel().add(comp);
428: }
429:
430: public Component add(Component comp, int index) {
431: return getContentPanel().add(comp, index);
432: }
433:
434: public void add(Component comp, Object constraints) {
435: getContentPanel().add(comp, constraints);
436: }
437:
438: public void add(Component comp, Object constraints, int index) {
439: getContentPanel().add(comp, constraints, index);
440: }
441:
442: public Component add(String name, Component comp) {
443: return getContentPanel().add(name, comp);
444: }
445:
446: public void add(PopupMenu popup) {
447: getContentPanel().add(popup);
448: }
449:
450: public void addActionListener(ActionListener listener) {
451: if (!actionListeners.contains(listener)) {
452: actionListeners.add(listener);
453: }
454: }
455:
456: public boolean areButtonsEnabled() {
457: return closePanelButton.isEnabled();
458: }
459:
460: public void close() {
461: if (isClosed()) {
462: return;
463: }
464:
465: setVisible(false);
466: state = STATE_CLOSED;
467: fireActionPerformed();
468: }
469:
470: public void maximize() {
471: if (isMaximized()) {
472: return;
473: }
474:
475: maximizePanelButton.setVisible(false);
476: restorePanelButton.setVisible(true);
477: minimizePanelButton.setVisible(true);
478: contentPanel.setVisible(true);
479: state = STATE_MAXIMIZED;
480: fireActionPerformed();
481: }
482:
483: public void minimize() {
484: if (isMinimized()) {
485: return;
486: }
487:
488: maximizePanelButton.setVisible(true);
489: restorePanelButton.setVisible(true);
490: minimizePanelButton.setVisible(false);
491: contentPanel.setVisible(false);
492: state = STATE_MINIMIZED;
493: fireActionPerformed();
494: }
495:
496: public void remove(Component component) {
497: getContentPanel().remove(component);
498: }
499:
500: public void remove(MenuComponent component) {
501: getContentPanel().remove(component);
502: }
503:
504: public void remove(int index) {
505: getContentPanel().remove(index);
506: }
507:
508: public void removeActionListener(ActionListener listener) {
509: actionListeners.remove(listener);
510: }
511:
512: public void removeAll() {
513: getContentPanel().removeAll();
514: }
515:
516: public void restore() {
517: if (isRestored()) {
518: return;
519: }
520:
521: maximizePanelButton.setVisible(true);
522: restorePanelButton.setVisible(false);
523: minimizePanelButton.setVisible(true);
524: contentPanel.setVisible(true);
525: state = STATE_RESTORED;
526: fireActionPerformed();
527: }
528:
529: private void fireActionPerformed() {
530: for (int i = 0; i < actionListeners.size(); i++) {
531: ((ActionListener) actionListeners.get(i))
532: .actionPerformed(new ActionEvent(this , getState(),
533: ""));
534: }
535: }
536:
537: private void initComponents() {
538: DoubleClickListener dblClickListener = new DoubleClickListener();
539: titlePanel = new JPanel();
540: titlePanel.addMouseListener(dblClickListener);
541:
542: super .setLayout(new BorderLayout());
543:
544: JLabel titleLabel = new JLabel(title) {
545: public Dimension getMinimumSize() {
546: return new Dimension(0, super .getMinimumSize().height);
547: }
548: };
549:
550: if (icon != null) {
551: titleLabel.setIcon(icon);
552: }
553:
554: titleLabel.setForeground(UIManager
555: .getColor("ToolTip.foreground")); // NOI18N
556: titleLabel.setFont(UIManager.getFont("ToolTip.font")); // NOI18N
557: titleLabel.setOpaque(false);
558: titleLabel.addMouseListener(dblClickListener);
559:
560: closePanelButton = new ImageIconButton(closePanelIcon);
561: closePanelButton.addActionListener(new ActionListener() {
562: public void actionPerformed(ActionEvent e) {
563: close();
564: };
565: });
566:
567: maximizePanelButton = new ImageIconButton(maximizePanelIcon);
568: maximizePanelButton.addActionListener(new ActionListener() {
569: public void actionPerformed(ActionEvent e) {
570: maximize();
571: };
572: });
573:
574: restorePanelButton = new ImageIconButton(restorePanelIcon);
575: restorePanelButton.setVisible(false);
576: restorePanelButton.addActionListener(new ActionListener() {
577: public void actionPerformed(ActionEvent e) {
578: restore();
579: };
580: });
581:
582: minimizePanelButton = new ImageIconButton(minimizePanelIcon);
583: minimizePanelButton.addActionListener(new ActionListener() {
584: public void actionPerformed(ActionEvent e) {
585: minimize();
586: };
587: });
588:
589: JPanel buttonsContainer = new JPanel(new FlowLayout(
590: FlowLayout.TRAILING, 0, 0));
591: buttonsContainer.setOpaque(false);
592: // buttonsContainer.add(minimizePanelButton);
593: // buttonsContainer.add(restorePanelButton);
594: // buttonsContainer.add(maximizePanelButton);
595: buttonsContainer.add(closePanelButton);
596:
597: JPanel buttonsPanel = new JPanel(new GridBagLayout());
598: buttonsPanel.setOpaque(false);
599: buttonsPanel.add(buttonsContainer, new GridBagConstraints());
600:
601: titlePanel.setLayout(new BorderLayout());
602: titlePanel.add(titleLabel, BorderLayout.WEST);
603:
604: if (showButtons) {
605: titlePanel.add(buttonsPanel, BorderLayout.EAST);
606: }
607:
608: titlePanel.setBorder(BorderFactory.createCompoundBorder(
609: BorderFactory.createLineBorder(UIManager
610: .getLookAndFeel().getID().equals("Metal") ? // NOI18N
611: UIManager.getColor("Button.darkShadow")
612: : // NOI18N
613: UIManager.getColor("Button.shadow")), // NOI18N
614: BorderFactory.createEmptyBorder(2, 5, 2, 2)));
615: titlePanel.setOpaque(true);
616: // titlePanel.setBackground(UIManager.getColor("ToolTip.background"));
617: titlePanel.setBackground(new Color(245, 245, 245));
618:
619: super.add(titlePanel, BorderLayout.NORTH);
620: super.add(contentPanel, BorderLayout.CENTER);
621: }
622: }
|