/*
* $Id$
*
* Copyright 2009 Sun Microsystems, Inc., 4150 Network Circle,
* Santa Clara, California 95054, U.S.A. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.jdesktop.swingx.demos.titledpanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.MutableComboBoxModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.FontUIResource;
import org.jdesktop.application.Action;
import org.jdesktop.beansbinding.BeanProperty;
import org.jdesktop.beansbinding.Binding;
import org.jdesktop.beansbinding.BindingGroup;
import org.jdesktop.beansbinding.Bindings;
import org.jdesktop.beansbinding.AutoBinding.UpdateStrategy;
import org.jdesktop.swingx.JXLabel;
import org.jdesktop.swingx.JXPanel;
import org.jdesktop.swingx.JXTitledPanel;
import org.jdesktop.swingx.JXTitledSeparator;
import org.jdesktop.swingx.binding.DisplayInfo;
import org.jdesktop.swingx.binding.DisplayInfoConverter;
import org.jdesktop.swingx.binding.LabelHandler;
import org.jdesktop.swingx.painter.CheckerboardPainter;
import org.jdesktop.swingx.painter.Painter;
import org.jdesktop.swingx.plaf.PainterUIResource;
import org.jdesktop.swingx.renderer.DefaultListRenderer;
import org.jdesktop.swingxset.util.DemoUtils;
import org.jdesktop.swingxset.util.DisplayValues;
import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.factories.Borders;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import com.sun.swingset3.DemoProperties;
import com.sun.swingset3.utilities.ArrowIcon;
/**
* A demo for the {@code JXTitledPanel}.
*
* @author Karl George Schaefer
*/
@DemoProperties(value = "JXTitledPanel Demo",
category = "Containers",
description = "Demonstrates JXTitledPanel, a container with a title display.",
sourceFiles = {
"org/jdesktop/swingx/demos/titledpanel/TitledPanelDemo.java",
"org/jdesktop/swingx/demos/titledpanel/resources/TitledPanelDemo.properties"
})
@SuppressWarnings("serial")
public class TitledPanelDemo extends JXPanel {
// PENDING JW: removed extending DefaultDemoPanel because fell into the pit
// of this.fields not yet initialized in overridden methods
// plus: should consider to not extend a panel at all - this class is-not-a view
// just a provider of a view :-)
@SuppressWarnings("unused")
private static final Logger LOG = Logger.getLogger(TitledPanelDemo.class
.getName());
// private JXTitledPanel panel1;
private JXTitledPanel titledPanel;
private JButton prevButton;
private JButton nextButton;
private JXTitledSeparator controlSeparator;
private JTextField titleField;
private JComboBox fontChooserCombo;
private JComboBox backgroundChooserCombo;
private List<JComponent> cards;
private JCheckBox visibleBox;
public TitledPanelDemo() {
initComponents();
configureComponents();
DemoUtils.injectResources(this);
bind();
}
//-------------------- Actions
@Action (enabledProperty = "trailing")
public void previousCard() {
if (!isTrailing()) return;
boolean oldTrailing = isTrailing();
boolean oldLeading = isLeading();
// <snip> JXTitledPanel use decoration components
// replace content with previous
int card = cards.indexOf(titledPanel.getContentContainer());
titledPanel.setContentContainer(cards.get(card - 1));
// </snip>
titledPanel.revalidate();
titledPanel.repaint();
firePropertyChange("trailing", oldTrailing, isTrailing());
firePropertyChange("leading", oldLeading, isLeading());
}
@Action (enabledProperty = "leading")
public void nextCard() {
if (!isLeading()) return;
boolean oldTrailing = isTrailing();
boolean oldLeading = isLeading();
// <snip> JXTitledPanel use decoration components
// replace content with next
int card = cards.indexOf(titledPanel.getContentContainer());
titledPanel.setContentContainer(cards.get(card + 1));
// </snip>
titledPanel.revalidate();
titledPanel.repaint();
firePropertyChange("leading", oldLeading, isLeading());
firePropertyChange("trailing", oldTrailing, isTrailing());
}
public boolean isTrailing() {
return titledPanel.getContentContainer() != cards.get(0);
}
public boolean isLeading() {
return titledPanel.getContentContainer() != cards.get(cards.size() - 1);
}
@Action (selectedProperty = "navigatorVisible")
public void toggleNavigatorVisible() {
// do nothing - action happens in setter of selectedProperty
}
public boolean isNavigatorVisible() {
return titledPanel.getLeftDecoration() != null;
}
public void setNavigatorVisible(boolean visible) {
// <snip> JXTitledPanel configure title properties
// Show/Hide left and right decoration options
if (isNavigatorVisible() == visible) return;
boolean old = isNavigatorVisible();
titledPanel.setLeftDecoration(visible ? prevButton : null);
titledPanel.setRightDecoration(visible ? nextButton : null);
// </snip>
titledPanel.revalidate();
titledPanel.repaint();
firePropertyChange("navigatorVisible", old, isNavigatorVisible());
}
//------------------- bind/configure
private ComboBoxModel createFontModel() {
MutableComboBoxModel model = new DefaultComboBoxModel();
// <snip> JXTitledPanel configure title properties
// Font options (based on default)
Font baseFont = UIManager.getFont("JXTitledPanel.titleFont");
model.addElement(new DisplayInfo<Font>("Default ", baseFont));
Font italicFont = new FontUIResource(baseFont.deriveFont(Font.ITALIC));
model.addElement(new DisplayInfo<Font>("Derived (Italic)" , italicFont));
Font bigFont = new FontUIResource(baseFont.deriveFont(baseFont.getSize2D() * 2));
model.addElement(new DisplayInfo<Font>("Derived (Doubled Size) ", bigFont));
// </snip>
return model;
}
private ComboBoxModel createBackgroundModel() {
MutableComboBoxModel model = new DefaultComboBoxModel();
// <snip> JXTitledPanel configure title properties
// Background Painter options
Painter<?> baseFont = (Painter<?>) UIManager.get("JXTitledPanel.titlePainter");
model.addElement(new DisplayInfo<Painter<?>>("Default ", baseFont));
model.addElement(new DisplayInfo<Painter<?>>("Checkerboard",
new PainterUIResource<JComponent>(new CheckerboardPainter())));
// PENDING JW: add more options - image, gradient, animated...
// </snip>
return model;
}
@SuppressWarnings("unchecked")
private void bind() {
// set actions
prevButton.setAction(DemoUtils.getAction(this, "previousCard"));
nextButton.setAction(DemoUtils.getAction(this, "nextCard"));
// re-set action-independent Icons
applyNavigationDefaults();
visibleBox.setAction(DemoUtils.getAction(this, "toggleNavigatorVisible"));
DefaultListRenderer renderer = new DefaultListRenderer(DisplayValues.DISPLAY_INFO_DESCRIPTION);
fontChooserCombo.setRenderer(renderer);
backgroundChooserCombo.setRenderer(renderer);
BindingGroup group = new BindingGroup();
// <snip> JXTitledPanel configure title properties
// edit title text
group.addBinding(Bindings.createAutoBinding(UpdateStrategy.READ,
titleField, BeanProperty.create("text"),
titledPanel, BeanProperty.create("title")));
// </snip>
Binding fontBinding = Bindings.createAutoBinding(UpdateStrategy.READ,
fontChooserCombo, BeanProperty.create("selectedItem"),
titledPanel, BeanProperty.create("titleFont"));
fontBinding.setConverter(new DisplayInfoConverter<Font>());
group.addBinding(fontBinding);
Binding backgroundBinding = Bindings.createAutoBinding(UpdateStrategy.READ,
backgroundChooserCombo, BeanProperty.create("selectedItem"),
titledPanel, BeanProperty.create("titlePainter"));
backgroundBinding.setConverter(new DisplayInfoConverter<Painter>());
group.addBinding(backgroundBinding);
group.bind();
updateUIProperties();
installUIListener();
}
// <snip> JXTitledPanel configure title properties
// reset to ui-defaults on changing LAF
private void updateUIProperties() {
fontChooserCombo.setModel(createFontModel());
backgroundChooserCombo.setModel(createBackgroundModel());
// applyNavigationDefaults();
}
private void installUIListener() {
PropertyChangeListener listener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
updateUIProperties();
}
};
UIManager.addPropertyChangeListener(listener);
}
// </snip>
//------------------- init view
private void configureComponents() {
// JW: default bevel border is ugly - should change?
titledPanel.setBorder(BorderFactory.createEmptyBorder());
// demo specifics
DemoUtils.setSnippet("JXTitledPanel use decoration components", titledPanel);
DemoUtils.setSnippet("JXTitledPanel configure title properties",
titleField, fontChooserCombo, backgroundChooserCombo, visibleBox);
}
private void initComponents() {
setLayout(new BorderLayout());
titledPanel = new JXTitledPanel() {
/**
* @inherited <p>
*
* Overridden to adjust to size requirements of invisible cards.
*/
@Override
public Dimension getPreferredSize() {
Dimension dim = super.getPreferredSize();
Dimension child = getContentContainer().getPreferredSize();
int width = child.width;
for (JComponent card : cards) {
if (card != getContentContainer()) {
Dimension cardDim = card.getPreferredSize();
width = Math.max(width, cardDim.width);
}
}
if (width > child.width) {
dim.width += width - child.width;
}
return dim;
}
};
titledPanel.setName("titledPanel");
prevButton = new JButton();
prevButton.setName("previousButton");
nextButton = new JButton();
nextButton.setName("nextButton");
JComponent firstCard = createFirstCard();
firstCard.setName("firstCard");
titledPanel.setContentContainer(firstCard);
JComponent secondCard = createSecondCard();
secondCard.setName("secondCard");
JComponent thirdCard = createThirdCard();
thirdCard.setName("thirdCard");
cards = new ArrayList<JComponent>();
cards.add(firstCard);
cards.add(secondCard);
cards.add(thirdCard);
add(titledPanel);
// panel4 = new JXTitledPanel("Image");
// //TODO add image
// add(panel4);
}
private JXPanel createFirstCard() {
JXPanel control = new JXPanel();
FormLayout formLayout = new FormLayout(
"5dlu, r:d:n, l:4dlu:n, f:d:g", // columns
"c:d:n " +
", t:4dlu:n, c:d:n " +
", t:4dlu:n, c:d:n" +
", t:4dlu:n, c:d:n" +
", t:4dlu:n, c:d:n" +
", t:4dlu:n, c:d:n"
); // rows
PanelBuilder builder = new PanelBuilder(formLayout, control);
builder.setBorder(Borders.DIALOG_BORDER);
CellConstraints cl = new CellConstraints();
CellConstraints cc = new CellConstraints();
controlSeparator = new JXTitledSeparator();
controlSeparator.setName("controlSeparator");
builder.add(controlSeparator, cc.xywh(1, 1, 4, 1));
int labelColumn = 2;
int widgetColumn = labelColumn + 2;
int currentRow = 3;
titleField = new JTextField(20);
titleField.setName("titleField");
JLabel titleLabel = builder.addLabel("", cl.xywh(labelColumn, currentRow, 1, 1),
titleField, cc.xywh(widgetColumn, currentRow, 1, 1));
currentRow += 2;
titleLabel.setName("titleLabel");
LabelHandler.bindLabelFor(titleLabel, titleField);
fontChooserCombo = new JComboBox();
fontChooserCombo.setName("fontChooserCombo");
JLabel fontLabel = builder.addLabel("", cl.xywh(labelColumn, currentRow, 1, 1),
fontChooserCombo, cc.xywh(widgetColumn, currentRow, 1, 1));
currentRow += 2;
fontLabel.setName("fontChooserLabel");
LabelHandler.bindLabelFor(fontLabel, fontChooserCombo);
backgroundChooserCombo = new JComboBox();
backgroundChooserCombo.setName("backgroundChooserCombo");
JLabel backgroundLabel = builder.addLabel("", cl.xywh(labelColumn, currentRow, 1, 1),
backgroundChooserCombo, cc.xywh(widgetColumn, currentRow, 1, 1));
currentRow += 2;
backgroundLabel.setName("backgroundChooserLabel");
LabelHandler.bindLabelFor(backgroundLabel, backgroundChooserCombo);
visibleBox = new JCheckBox();
visibleBox.setName("visibleBox");
builder.add(visibleBox, cc.xywh(widgetColumn, currentRow, 1, 1));
currentRow += 2;
return control;
}
private JComponent createThirdCard() {
JComponent thirdCard = new JXPanel();
thirdCard.add(new
JXLabel("The quick brown fox\n jumped over the lazy dog."));
return thirdCard;
}
private JXPanel createSecondCard() {
JXPanel content = new JXPanel();
content.add(new JButton("Button 1"));
content.add(new JButton("Button 2"));
content.add(new JButton("Button 3"));
return content;
}
/**
* @param prevButton
* @param orientation
* @param arrowSize
*/
private void applyNavigationDefaults(JButton prevButton, int orientation) {
int arrowSize = 10;
Color arrowColor = UIManager.getColor("Label.foreground");
Color inactiveColor = UIManager.getColor("Label.disabledText");
Dimension buttonSize = new Dimension(arrowSize + 12 ,
arrowSize + 12);
prevButton.setIcon(new ArrowIcon(orientation, arrowSize, arrowColor));
prevButton.setDisabledIcon(new ArrowIcon(orientation, arrowSize, inactiveColor));
prevButton.setPreferredSize(buttonSize);
prevButton.setFocusable(false);
}
/**
*
*/
private void applyNavigationDefaults() {
applyNavigationDefaults(prevButton, ArrowIcon.WEST);
applyNavigationDefaults(nextButton, ArrowIcon.EAST);
}
/**
* main method allows us to run as a standalone demo.
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame(TitledPanelDemo.class.getAnnotation(
DemoProperties.class).value());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new TitledPanelDemo());
frame.setPreferredSize(new Dimension(800, 600));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}