/*
* $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.painter;
import static org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Insets;
import java.awt.LinearGradientPaint;
import java.awt.Paint;
import java.awt.Point;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeModel;
import org.jdesktop.application.Application;
import org.jdesktop.beans.AbstractBean;
import org.jdesktop.beansbinding.AutoBinding.UpdateStrategy;
import org.jdesktop.beansbinding.BeanProperty;
import org.jdesktop.beansbinding.Binding;
import org.jdesktop.beansbinding.BindingGroup;
import org.jdesktop.beansbinding.Bindings;
import org.jdesktop.beansbinding.Converter;
import org.jdesktop.beansbinding.ELProperty;
import org.jdesktop.swingx.JXCollapsiblePane;
import org.jdesktop.swingx.JXPanel;
import org.jdesktop.swingx.JXTitledSeparator;
import org.jdesktop.swingx.JXTree;
import org.jdesktop.swingx.binding.DisplayInfo;
import org.jdesktop.swingx.binding.DisplayInfoArrayConverter;
import org.jdesktop.swingx.binding.DisplayInfoConverter;
import org.jdesktop.swingx.binding.LabelHandler;
import org.jdesktop.swingx.combobox.EnumComboBoxModel;
import org.jdesktop.swingx.painter.AbstractAreaPainter;
import org.jdesktop.swingx.painter.AbstractAreaPainter.Style;
import org.jdesktop.swingx.painter.AbstractLayoutPainter;
import org.jdesktop.swingx.painter.AbstractLayoutPainter.HorizontalAlignment;
import org.jdesktop.swingx.painter.AbstractLayoutPainter.VerticalAlignment;
import org.jdesktop.swingx.painter.AbstractPainter;
import org.jdesktop.swingx.painter.AbstractPainter.Interpolation;
import org.jdesktop.swingx.painter.CompoundPainter;
import org.jdesktop.swingx.painter.GlossPainter;
import org.jdesktop.swingx.painter.GlossPainter.GlossPosition;
import org.jdesktop.swingx.painter.ImagePainter;
import org.jdesktop.swingx.painter.MattePainter;
import org.jdesktop.swingx.painter.Painter;
import org.jdesktop.swingx.painter.PinstripePainter;
import org.jdesktop.swingx.painter.RectanglePainter;
import org.jdesktop.swingx.painter.ShapePainter;
import org.jdesktop.swingx.painter.TextPainter;
import org.jdesktop.swingx.painter.effects.AreaEffect;
import org.jdesktop.swingx.painter.effects.GlowPathEffect;
import org.jdesktop.swingx.painter.effects.InnerGlowPathEffect;
import org.jdesktop.swingx.painter.effects.InnerShadowPathEffect;
import org.jdesktop.swingx.painter.effects.NeonBorderEffect;
import org.jdesktop.swingx.painter.effects.ShadowPathEffect;
import org.jdesktop.swingx.renderer.DefaultListRenderer;
import org.jdesktop.swingx.renderer.DefaultTreeRenderer;
import org.jdesktop.swingx.renderer.StringValue;
import org.jdesktop.swingx.util.PaintUtils;
import org.jdesktop.swingx.util.ShapeUtils;
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.jhlabs.image.AverageFilter;
import com.jhlabs.image.BlockFilter;
import com.jhlabs.image.BlurFilter;
import com.jhlabs.image.BorderFilter;
import com.jhlabs.image.BoxBlurFilter;
import com.jhlabs.image.BumpFilter;
import com.jhlabs.image.ChromeFilter;
import com.jhlabs.image.ContrastFilter;
import com.jhlabs.image.CrystallizeFilter;
import com.jhlabs.image.DespeckleFilter;
import com.jhlabs.image.DiffuseFilter;
import com.jhlabs.image.DiffusionFilter;
import com.jhlabs.image.DilateFilter;
import com.jhlabs.image.DisplaceFilter;
import com.jhlabs.image.DitherFilter;
import com.jhlabs.image.EdgeFilter;
import com.jhlabs.image.EmbossFilter;
import com.jhlabs.image.EqualizeFilter;
import com.jhlabs.image.ErodeFilter;
import com.jhlabs.image.FlareFilter;
import com.jhlabs.image.GainFilter;
import com.jhlabs.image.GammaFilter;
import com.jhlabs.image.GaussianFilter;
import com.jhlabs.image.GlintFilter;
import com.jhlabs.image.GlowFilter;
import com.jhlabs.image.GrayFilter;
import com.jhlabs.image.InvertAlphaFilter;
import com.jhlabs.image.InvertFilter;
import com.jhlabs.image.LensBlurFilter;
import com.jhlabs.image.LevelsFilter;
import com.jhlabs.image.LifeFilter;
import com.jhlabs.image.MarbleFilter;
import com.jhlabs.image.MarbleTexFilter;
import com.jhlabs.image.MedianFilter;
import com.jhlabs.image.MinimumFilter;
import com.jhlabs.image.MirrorFilter;
import com.jhlabs.image.MotionBlurFilter;
import com.jhlabs.image.NoiseFilter;
import com.jhlabs.image.OilFilter;
import com.jhlabs.image.OpacityFilter;
import com.jhlabs.image.OutlineFilter;
import com.jhlabs.image.PointillizeFilter;
import com.jhlabs.image.PosterizeFilter;
import com.jhlabs.image.QuantizeFilter;
import com.jhlabs.image.RaysFilter;
import com.jhlabs.image.ReduceNoiseFilter;
import com.jhlabs.image.RippleFilter;
import com.jhlabs.image.ShadowFilter;
import com.jhlabs.image.SharpenFilter;
import com.jhlabs.image.SkeletonFilter;
import com.jhlabs.image.SmearFilter;
import com.jhlabs.image.SolarizeFilter;
import com.jhlabs.image.SparkleFilter;
import com.jhlabs.image.SphereFilter;
import com.jhlabs.image.SwimFilter;
import com.jhlabs.image.ThresholdFilter;
import com.jhlabs.image.TwirlFilter;
import com.jhlabs.image.UnsharpFilter;
import com.jhlabs.image.WaterFilter;
import com.sun.swingset3.DemoProperties;
/**
* A demo for {@code Painter}.
*
* @author Karl George Schaefer
* @author joshy (original PainterDemoSet)
*/
@DemoProperties(
value = "Painter Demo",
category = "Decorators",
description = "Demonstrates Painters, a painting delegate.",
sourceFiles = {
"org/jdesktop/swingx/demos/painter/PainterDemo.java",
"org/jdesktop/swingx/demos/painter/PainterDemoUtils.java",
"org/jdesktop/swingx/binding/DisplayInfo.java",
"org/jdesktop/swingx/binding/DisplayInfoConverter.java",
"org/jdesktop/swingx/demos/painter/resources/PainterDemo.properties"
}
)
@SuppressWarnings("serial")
public class PainterDemo extends JPanel {
@SuppressWarnings("unused")
private static final Logger LOG = Logger.getLogger(PainterDemo.class
.getName());
private JXTree painterDemos;
private JXPanel painterDisplay;
private JComboBox horizontalAlignmentBox;
private JComboBox verticalAlignmentBox;
private PainterControl painterControl;
private JSlider insetSlider;
private JCheckBox fillHorizontal;
private JCheckBox fillVertical;
private JXCollapsiblePane layoutPainterControlPanel;
private JXCollapsiblePane basePainterControlPanel;
// private JComponent painterControlPanel;
private JComboBox filterBox;
private JComboBox interpolationBox;
private JCheckBox visibleBox;
private JCheckBox antialiasBox;
private JXTitledSeparator layoutSeparator;
private JXTitledSeparator baseSeparator;
private JComponent areaSeparator;
private JComboBox styleBox;
private JXCollapsiblePane areaPainterControlPanel;
private JComboBox effectBox;
private JCheckBox paintStretchedBox;
private JSlider borderWidthSlider;
/**
* 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(PainterDemo.class.getAnnotation(DemoProperties.class).value());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new PainterDemo());
frame.setPreferredSize(new Dimension(800, 600));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public PainterDemo() {
super(new BorderLayout());
createPainterDemo();
Application.getInstance().getContext().getResourceMap(getClass()).injectComponents(this);
bind();
}
//---------------------------- Painters
/**
* @return
*/
private TreeModel createPainters() {
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
root.add(createImagePainterDemos());
root.add(createShapePainterDemos());
root.add(createTextPainterDemos());
root.add(createRectanglePainterDemos());
root.add(createTransformPainterDemos());
root.add(createGlossPainterDemos());
root.add(createPinstripePainterDemos());
root.add(createMattePainterDemos());
root.add(createCompoundPainterDemos());
return new DefaultTreeModel(root);
}
@SuppressWarnings("unchecked")
private DefaultMutableTreeNode createInfoNode(String desc, Painter painter) {
DefaultMutableTreeNode pin = new DefaultMutableTreeNode(
new DisplayInfo<Painter>(desc, painter));
return pin;
}
//TODO all this ImageIO stuff should be off EDT
private MutableTreeNode createImagePainterDemos() {
DefaultMutableTreeNode node = createInfoNode("Image Painter Demos", null);
try {
BufferedImage img = ImageIO.read(getClass().getResourceAsStream("border.gif"));
node.add(createInfoNode("small image", new ImagePainter(img)));
} catch (Exception ex) {
ex.printStackTrace();
}
try {
BufferedImage img = ImageIO.read(getClass().getResourceAsStream("moon.jpg"));
node.add(createInfoNode("big image", new ImagePainter(img)));
} catch (Exception ex) {
ex.printStackTrace();
}
try {
BufferedImage img = ImageIO.read(getClass().getResourceAsStream("border.gif"));
ImagePainter ip = new ImagePainter(img);
ip.setHorizontalRepeat(true);
node.add(createInfoNode("horizontal repeat", ip));
} catch (Exception ex) {
ex.printStackTrace();
}
try {
BufferedImage img = ImageIO.read(getClass().getResourceAsStream("border.gif"));
ImagePainter ip = new ImagePainter(img);
ip.setVerticalRepeat(true);
node.add(createInfoNode("vertical repeat", ip));
} catch (Exception ex) {
ex.printStackTrace();
}
try {
BufferedImage img = ImageIO.read(getClass().getResourceAsStream("border.gif"));
ImagePainter ip = new ImagePainter(img);
ip.setBorderPaint(Color.BLACK);
node.add(createInfoNode("image with black border", ip));
} catch (Exception ex) {
ex.printStackTrace();
}
try {
BufferedImage img = ImageIO.read(getClass().getResourceAsStream("a-glyph.png"));
node.add(createInfoNode("An image of 'A' with transparent parts",
new ImagePainter(img)));
} catch (Exception ex) {
ex.printStackTrace();
}
try {
BufferedImage img = ImageIO.read(getClass().getResourceAsStream("a-glyph.png"));
ImagePainter ip = new ImagePainter(img);
ip.setFillPaint(Color.RED);
node.add(createInfoNode("red background visible through transparent parts", ip));
} catch (Exception ex) {
ex.printStackTrace();
}
//FIXME need a way to background load the image, cf. SwingX #1099
// try {
// ImagePainter ip = new ImagePainter();
// ip.setImageString("http://java.sun.com/developer/techDocs/hi/repository/graphicsRepository/toolbarButtonGraphics/general/Delete24.gif");
//
// DefaultMutableTreeNode pin = createInfoNode("image loaded from remote URL", ip);
// node.add(pin);
// } catch (Exception ex) {
// ex.printStackTrace();
// }
return node;
}
private MutableTreeNode createShapePainterDemos() {
DefaultMutableTreeNode node = createInfoNode("Shape Painter Demos", null);
// build a star shape with 5 points and 30 degree angles
Shape starShape = ShapeUtils.generatePolygon(5,30,15,true);
ShapePainter sp = new ShapePainter(starShape, Color.RED);
node.add(createInfoNode("Star style", sp));
return node;
}
private MutableTreeNode createTextPainterDemos() {
DefaultMutableTreeNode node = createInfoNode("Text Painter Demos", null);
Font font = new Font("SansSerif", Font.BOLD, 80);
TextPainter tp = new TextPainter("Neon", font, Color.RED);
node.add(createInfoNode("Text", tp));
tp = new TextPainter("Neon",font,Color.BLACK);
tp.setFillPaint(PaintUtils.AERITH);
node.add(createInfoNode("Text with gradient", tp));
return node;
}
private MutableTreeNode createRectanglePainterDemos() {
DefaultMutableTreeNode node = createInfoNode("Rectangle Painter Demos", null);
RectanglePainter rp = new RectanglePainter(20, 20, 20, 20, 30, 30, true,
Color.GREEN, 3, Color.GREEN.darker());
node.add(createInfoNode("Rectangle, green on gray", rp));
rp = new RectanglePainter(50, 50, 30, Color.GREEN);
rp.setBorderPaint(Color.GREEN.darker());
node.add(createInfoNode("Rectangle, 100x100", rp));
rp = new RectanglePainter(5, 5, 5, 5, 10, 10, true, Color.RED, 3, Color.BLACK);
node.add(createInfoNode("Red Rectangle w/ black border", rp));
rp = new RectanglePainter(Color.BLACK,Color.RED);
rp.setRoundHeight(10);
rp.setRoundWidth(10);
rp.setRounded(true);
node.add(createInfoNode("Plain round rect for sizing bugs", rp));
return node;
}
//TODO some transforms moving painter outside of visible region
private MutableTreeNode createTransformPainterDemos() {
DefaultMutableTreeNode node = createInfoNode("Compound Painter Transform Demos", null);
Font font = new Font("SansSerif", Font.BOLD, 80);
TextPainter tp = new TextPainter("Text", font);
CompoundPainter<Object> cp = new CompoundPainter<Object>(tp);
node.add(createInfoNode("Normal Text", cp));
tp = new TextPainter("Text", font);
cp = new CompoundPainter<Object>(tp);
cp.setTransform(AffineTransform.getRotateInstance(-Math.PI * 2 / 8, 100, 100));
node.add(createInfoNode("Rotated Text", cp));
tp = new TextPainter("Text", font);
cp = new CompoundPainter<Object>(tp);
cp.setTransform(AffineTransform.getShearInstance(-0.2, 0));
node.add(createInfoNode("Sheared Text", cp));
tp = new TextPainter("Text", font);
cp = new CompoundPainter<Object>(tp);
cp.setTransform(AffineTransform.getScaleInstance(2, 2));
node.add(createInfoNode("Scaled Text", cp));
RectanglePainter rp = new RectanglePainter(30, 30, 30, 30, 30, 30,
true, Color.RED, 4f, Color.RED.darker());
tp = new TextPainter("Text", font);
cp = new CompoundPainter<Object>(rp, tp);
cp.setTransform(AffineTransform.getRotateInstance(-Math.PI * 2 / 8, 100, 100));
node.add(createInfoNode("Rotated Text w/ effects on rect", cp));
return node;
}
private MutableTreeNode createGlossPainterDemos() {
DefaultMutableTreeNode node = createInfoNode("Gloss Painter Demos",
null);
RectanglePainter rp = new RectanglePainter(20, 20, 20,
20, 20, 20);
rp.setFillPaint(Color.RED);
rp.setBorderPaint(Color.RED.darker());
rp.setStyle(RectanglePainter.Style.BOTH);
rp.setBorderWidth(5);
rp.setAntialiasing(true);
CompoundPainter<Object> cp = new CompoundPainter<Object>(rp, new GlossPainter());
node.add(createInfoNode("Gloss on top of rectangle", cp));
rp = new RectanglePainter(20, 20, 20, 20, 20, 20, true,
Color.RED, 5f, Color.RED.darker());
rp.setAntialiasing(true);
cp = new CompoundPainter<Object>(rp, new GlossPainter(GlossPosition.BOTTOM));
node.add(createInfoNode("Gloss on bottom of rectangle", cp));
return node;
}
private MutableTreeNode createPinstripePainterDemos() {
DefaultMutableTreeNode node = createInfoNode("Pinstripe Painter Demos", null);
MattePainter black = new MattePainter(Color.BLACK);
PinstripePainter pp = new PinstripePainter(Color.WHITE, 45, 1, 10);
CompoundPainter<Object> cp = new CompoundPainter<Object>(black, pp);
node.add(createInfoNode("45deg white pinstripe on black", cp));
pp = new PinstripePainter(Color.WHITE, 0, 1, 10);
pp.setAntialiasing(true);
cp = new CompoundPainter<Object>(black, pp);
node.add(createInfoNode("vertical white pinstripe on black", cp));
pp = new PinstripePainter(Color.WHITE, 90, 1, 10);
pp.setAntialiasing(true);
cp = new CompoundPainter<Object>(black, pp);
node.add(createInfoNode("horizontal white pinstripe on black", cp));
pp = new PinstripePainter(Color.WHITE, 45, 3, 10);
pp.setAntialiasing(true);
cp = new CompoundPainter<Object>(black, pp);
node.add(createInfoNode("3px wide white pinstripe on black", cp));
pp = new PinstripePainter(Color.WHITE, 45, 10, 2);
pp.setAntialiasing(true);
cp = new CompoundPainter<Object>(black, pp);
node.add(createInfoNode("10px wide pinstripe w/ 2px spacing on black", cp));
pp = new PinstripePainter(Color.WHITE, 45, 3, 15);
pp.setAntialiasing(true);
pp.setPaint(
new GradientPaint(new Point(0, 0), Color.WHITE, new Point(10, 10), Color.BLACK));
cp = new CompoundPainter<Object>(black, pp);
node.add(createInfoNode("pinstripe w/ 10px gradient", cp));
pp = new PinstripePainter(Color.WHITE, 45, 3, 15);
pp.setAntialiasing(true);
pp.setPaint(
new GradientPaint(new Point(0, 0), Color.WHITE, new Point(200, 200), Color.BLACK));
cp = new CompoundPainter<Object>(black, pp);
node.add(createInfoNode("pinstripe w/ 200px gradient", cp));
return node;
}
private MutableTreeNode createMattePainterDemos() {
DefaultMutableTreeNode node = createInfoNode("Matte Painter Gradient Demos", null);
Paint gradient = new GradientPaint(new Point(30, 30), Color.RED,
new Point(80, 30), Color.GREEN);
MattePainter mp = new MattePainter(gradient);
node.add(createInfoNode("single stop, horiz", mp));
gradient = new GradientPaint(new Point(30, 30), Color.RED,
new Point(30, 80), Color.GREEN);
node.add(createInfoNode("single stop, vert", new MattePainter(gradient)));
gradient = new GradientPaint(new Point(30, 30), Color.RED,
new Point(80, 80), Color.GREEN);
node.add(createInfoNode("single stop, diag", new MattePainter(gradient)));
gradient = new LinearGradientPaint(new Point(30,30), new Point(80,30),
new float[] {0f, 0.5f, 1f},
new Color[] {Color.RED, Color.GREEN, Color.BLUE} );
node.add(createInfoNode("multi stop horiz", new MattePainter(gradient)));
gradient = new LinearGradientPaint(new Point(30,30), new Point(30,80),
new float[] {0f, 0.5f, 1f},
new Color[] {Color.RED, Color.GREEN, Color.BLUE} );
node.add(createInfoNode("multi stop vert", new MattePainter(gradient)));
gradient = new LinearGradientPaint(new Point(30,30), new Point(30,80),
new float[] {0f, 0.5f, 1f},
new Color[] {Color.RED, Color.GREEN, Color.BLUE} );
node.add(createInfoNode("multi stop diag", new MattePainter(gradient)));
return node;
}
private MutableTreeNode createCompoundPainterDemos() {
DefaultMutableTreeNode node = createInfoNode("Compound Painter Gradient Demos", null);
MattePainter mp = new MattePainter(Color.GREEN);
PinstripePainter pp = new PinstripePainter(Color.BLUE);
CompoundPainter<Object> cp = new CompoundPainter<Object>(mp, pp);
node.add(createInfoNode("panel w/ blue pinstripe fg, green matte bg", cp));
mp = new MattePainter(Color.GREEN);
RectanglePainter rp = new RectanglePainter(new Insets(20, 20, 20, 20), 50,
50, 10, 10, true, Color.RED, 5, Color.RED.darker());
pp = new PinstripePainter(Color.BLUE);
cp = new CompoundPainter<Object>(mp, rp, pp);
node.add(createInfoNode("panel, blue stripe fg, green bg, red rect comp", cp));
rp = new RectanglePainter(20, 20, 5, Color.BLUE);
TextPainter tp = new TextPainter("Some Text");
cp = new CompoundPainter<Object>(rp, tp);
node.add(createInfoNode("text on blue", cp));
mp = new MattePainter(Color.BLACK);
tp = new TextPainter("Neon");
tp.setFont(new Font("SansSerif", Font.BOLD, 100));
tp.setFillPaint(Color.BLACK);
NeonBorderEffect effect = new NeonBorderEffect(Color.BLACK, Color.RED.brighter(), 10);
effect.setBorderPosition(NeonBorderEffect.BorderPosition.Centered);
tp.setAreaEffects(effect);
cp = new CompoundPainter<Object>(mp, tp);
node.add(createInfoNode("A Cool Logo", cp));
mp = new MattePainter(Color.GRAY);
ShapePainter sp = new ShapePainter(
ShapeUtils.generatePolygon(30, 50, 45, true), Color.RED);
sp.setStyle(ShapePainter.Style.FILLED);
sp.setBorderPaint(Color.BLUE);
ShadowPathEffect starShadow = new ShadowPathEffect();
starShadow.setOffset(new Point(1,1));
starShadow.setEffectWidth(5);
sp.setAreaEffects(starShadow);
tp = new TextPainter("Coming Soon!", new Font("SansSerif", Font.PLAIN, 12), Color.WHITE);
cp = new CompoundPainter<Object>(mp, sp, tp);
node.add(createInfoNode("Coming Soon badge", cp));
return node;
}
/**
* Create and return model for filter selection combobox.
*
* @return
*/
private ComboBoxModel createFilterList() {
DefaultComboBoxModel model = new DefaultComboBoxModel();
model.addElement(new DisplayInfo<BufferedImageOp>("- none - ", null));
model.addElement(new DisplayInfo<BufferedImageOp>(new AverageFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new BlockFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new BlurFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new BorderFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new BoxBlurFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new BumpFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new ChromeFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new ContrastFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new CrystallizeFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new DespeckleFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new DiffuseFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new DiffusionFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new DilateFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new DisplaceFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new DitherFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new EdgeFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new EmbossFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new EqualizeFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new ErodeFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new FlareFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new GainFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new GammaFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new GaussianFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new GlintFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new GlowFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new GrayFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new InvertFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new InvertAlphaFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new LensBlurFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new LevelsFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new LifeFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new MarbleFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new MarbleTexFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new MedianFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new MinimumFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new MirrorFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new MotionBlurFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new NoiseFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new OilFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new OpacityFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new OutlineFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new PointillizeFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new PosterizeFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new QuantizeFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new RaysFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new ReduceNoiseFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new RippleFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new ShadowFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new SharpenFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new SkeletonFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new SmearFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new SolarizeFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new SparkleFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new SphereFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new SwimFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new ThresholdFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new TwirlFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new UnsharpFilter()));
model.addElement(new DisplayInfo<BufferedImageOp>(new WaterFilter()));
return model;
}
/**
* Create and returns model for effects selection combobox
* @return
*/
private ComboBoxModel createAreaEffectsList() {
DefaultComboBoxModel model = new DefaultComboBoxModel();
model.addElement(new DisplayInfo<AreaEffect>(" - none -", null));
model.addElement(new DisplayInfo<AreaEffect>(new GlowPathEffect()));
model.addElement(new DisplayInfo<AreaEffect>(new InnerGlowPathEffect()));
model.addElement(new DisplayInfo<AreaEffect>(new InnerShadowPathEffect()));
model.addElement(new DisplayInfo<AreaEffect>(new NeonBorderEffect()));
model.addElement(new DisplayInfo<AreaEffect>(new ShadowPathEffect()));
return model;
}
//------------------------------- Binding
@SuppressWarnings("unchecked")
private void bind() {
// fill and configure painter tree
painterDemos.setModel(createPainters());
// create the painter property controller
painterControl = new PainterControl();
// bind selection of node
bindSelection(painterDisplay, painterControl);
// bindEnabled
bindEnabled("areaEnabled", areaSeparator, styleBox, effectBox,
borderWidthSlider, paintStretchedBox);
bindEnabled("alignEnabled", layoutSeparator, horizontalAlignmentBox,
verticalAlignmentBox, insetSlider, fillHorizontal, fillVertical);
bindEnabled("baseEnabled", baseSeparator, interpolationBox,
visibleBox, antialiasBox);
// bind collapsed
bindInversCollapsed("baseEnabled", layoutPainterControlPanel,
basePainterControlPanel, areaPainterControlPanel);
}
@SuppressWarnings("unchecked")
private void bindSelection(Object... components) {
painterDemos.setCellRenderer(new DefaultTreeRenderer(
DisplayValues.DISPLAY_INFO_DESCRIPTION));
Converter<?, ?> painterConverter = new DisplayInfoConverter<Painter>();
BindingGroup group = new BindingGroup();
for (int i = 0; i < components.length; i++) {
BeanProperty p = BeanProperty.create(
i == 0 ? "backgroundPainter" : "painter");
Binding b = Bindings.createAutoBinding(READ,
painterDemos, BeanProperty.create("selectedElement_UNWRAP_NODE"),
components[i], p);
b.setConverter(painterConverter);
group.addBinding(b);
}
group.bind();
}
/**
* @param property
*/
private void bindInversCollapsed(String property, JComponent... components ) {
BindingGroup group = new BindingGroup();
for (JComponent comp : components) {
group.addBinding(Bindings.createAutoBinding(READ,
painterControl, ELProperty.create("${!" + property + "}"),
comp, BeanProperty.create("collapsed")));
}
group.bind();
}
/**
* @param string
*/
private void bindEnabled(String property, JComponent... components ) {
BindingGroup group = new BindingGroup();
for (JComponent comp : components) {
group.addBinding(Bindings.createAutoBinding(READ,
painterControl, BeanProperty.create(property),
comp, BeanProperty.create("enabled")));
}
group.bind();
}
/**
* Controller of bindings to Painter properties.
*/
public class PainterControl extends AbstractBean {
private Painter<?> painter;
private boolean alignEnabled;
private boolean baseEnabled;
private boolean areaEnabled;
private BindingGroup alignGroup;
private BindingGroup baseGroup;
private BindingGroup areaGroup;
public PainterControl() {
StringValue effectInfo = DisplayValues.DISPLAY_INFO_DESCRIPTION;
// effects
effectBox.setRenderer(new DefaultListRenderer(effectInfo));
effectBox.setModel(createAreaEffectsList());
styleBox.setModel(
new EnumComboBoxModel<Style>(Style.class));
// base
interpolationBox.setModel(
new EnumComboBoxModel<Interpolation>(Interpolation.class));
filterBox.setModel(createFilterList());
filterBox.setRenderer(new DefaultListRenderer(effectInfo));
// layout data
horizontalAlignmentBox.setModel(
new EnumComboBoxModel<HorizontalAlignment>(HorizontalAlignment.class));
verticalAlignmentBox.setModel(
new EnumComboBoxModel<VerticalAlignment>(VerticalAlignment.class));
}
/**
* @return the areaEnabled
*/
public boolean isAreaEnabled() {
return areaEnabled;
}
/**
* @param areaEnabled the areaEnabled to set
*/
public void setAreaEnabled(boolean areaEnabled) {
boolean old = isAreaEnabled();
this.areaEnabled = areaEnabled;
updateAreaBindings();
firePropertyChange("areaEnabled", old, isAreaEnabled());
}
public boolean isBaseEnabled() {
return baseEnabled;
}
public void setBaseEnabled(boolean baseEnabled) {
boolean old = isBaseEnabled();
this.baseEnabled = baseEnabled;
updateBaseBindings();
firePropertyChange("baseEnabled", old, isBaseEnabled());
}
public boolean isAlignEnabled() {
return alignEnabled;
}
public void setAlignEnabled(boolean alignEnabled) {
boolean old = isAlignEnabled();
this.alignEnabled = alignEnabled;
updateAlignBindings();
firePropertyChange("alignEnabled", old, isAlignEnabled());
}
@SuppressWarnings("unchecked")
private void updateAreaBindings() {
if (areaEnabled) {
areaGroup = new BindingGroup();
areaGroup.addBinding(Bindings.createAutoBinding(READ,
paintStretchedBox, BeanProperty.create("selected"),
painter, BeanProperty.create("paintStretched")));
areaGroup.addBinding(Bindings.createAutoBinding(UpdateStrategy.READ,
styleBox, BeanProperty.create("selectedItem"),
painter, BeanProperty.create("style")));
Binding effectsBinding = (Bindings.createAutoBinding(READ,
effectBox, BeanProperty.create("selectedItem"),
painter, BeanProperty.create("areaEffects")));
effectsBinding.setConverter(new DisplayInfoArrayConverter(AreaEffect.class));
areaGroup.addBinding(effectsBinding);
Binding borderWidthBinding = (Bindings.createAutoBinding(READ,
borderWidthSlider, BeanProperty.create("value"),
painter, BeanProperty.create("borderWidth")));
borderWidthBinding.setConverter(PainterDemoUtils.SLIDER_TO_FLOAT);
areaGroup.addBinding(borderWidthBinding);
areaGroup.bind();
}
}
/**
*
*/
@SuppressWarnings("unchecked")
private void updateBaseBindings() {
if (baseEnabled) {
baseGroup = new BindingGroup();
baseGroup.addBinding(Bindings.createAutoBinding(UpdateStrategy.READ,
interpolationBox, BeanProperty.create("selectedItem"),
painter, BeanProperty.create("interpolation")));
baseGroup.addBinding(Bindings.createAutoBinding(READ,
visibleBox, BeanProperty.create("selected"),
painter, BeanProperty.create("visible")));
baseGroup.addBinding(Bindings.createAutoBinding(READ,
antialiasBox, BeanProperty.create("selected"),
painter, BeanProperty.create("antialiasing")));
Binding filterBinding = (Bindings.createAutoBinding(READ,
filterBox, BeanProperty.create("selectedItem"),
painter, BeanProperty.create("filters")));
filterBinding.setConverter(new DisplayInfoArrayConverter(BufferedImageOp.class));
baseGroup.addBinding(filterBinding);
baseGroup.bind();
}
}
/**
*
*/
@SuppressWarnings("unchecked")
private void updateAlignBindings() {
if (alignEnabled) {
alignGroup = new BindingGroup();
alignGroup.addBinding(Bindings.createAutoBinding(UpdateStrategy.READ,
horizontalAlignmentBox, BeanProperty.create("selectedItem"),
painter, BeanProperty.create("horizontalAlignment")));
alignGroup.addBinding(Bindings.createAutoBinding(READ,
verticalAlignmentBox, BeanProperty.create("selectedItem"),
painter, BeanProperty.create("verticalAlignment")));
alignGroup.addBinding(Bindings.createAutoBinding(READ,
fillHorizontal, BeanProperty.create("selected"),
painter, BeanProperty.create("fillHorizontal")));
alignGroup.addBinding(Bindings.createAutoBinding(READ,
fillVertical, BeanProperty.create("selected"),
painter, BeanProperty.create("fillVertical")));
Binding insetBinding = (Bindings.createAutoBinding(READ,
insetSlider, BeanProperty.create("value"),
painter, BeanProperty.create("insets")));
insetBinding.setConverter(PainterDemoUtils.SLIDER_TO_INSETS);
alignGroup.addBinding(insetBinding);
alignGroup.bind();
}
}
public Painter<?> getPainter() {
return painter;
}
public void setPainter(Painter<?> painter) {
releaseBaseBindings();
releaseAlignBindings();
releaseAreaBindings();
this.painter = painter;
setBaseEnabled(painter instanceof AbstractPainter<?>);
setAlignEnabled(painter instanceof AbstractLayoutPainter<?>);
setAreaEnabled(painter instanceof AbstractAreaPainter<?>);
}
/**
*
*/
private void releaseAreaBindings() {
if (areaGroup != null) {
areaGroup.unbind();
}
styleBox.setSelectedItem(Style.BOTH);
effectBox.setSelectedIndex(0);
paintStretchedBox.setSelected(false);
}
/**
*
*/
private void releaseBaseBindings() {
if (baseGroup != null) {
baseGroup.unbind();
}
interpolationBox.setSelectedItem(Interpolation.NearestNeighbor);
filterBox.setSelectedIndex(0);
visibleBox.setSelected(true);
antialiasBox.setSelected(true);
}
/**
*
*/
private void releaseAlignBindings() {
if (alignGroup != null) {
alignGroup.unbind();
}
// PENDING JW: reset defaults ... wrong place here?
verticalAlignmentBox.setSelectedItem(VerticalAlignment.CENTER);
horizontalAlignmentBox.setSelectedItem(HorizontalAlignment.CENTER);
insetSlider.setValue(0);
fillHorizontal.setSelected(false);
fillHorizontal.setSelected(false);
}
}
//------------------------------ Create UI
private void createPainterDemo() {
painterDisplay = createPainterDisplay();
JComponent painterControlPanel =new JXPanel(new BorderLayout());
painterControlPanel.add(painterDisplay);
painterControlPanel.add(createPainterPropertiesPanel(), BorderLayout.SOUTH);
painterDemos = new JXTree();
painterDemos.setRootVisible(false);
// PENDING JW: weird sizing in splitpane
JSplitPane contents = new JSplitPane();
contents.setDividerLocation(240);
contents.setContinuousLayout(true);
contents.setRightComponent(painterControlPanel);
contents.setLeftComponent(new JScrollPane(painterDemos));
add(contents);
}
/**
* @param painterControlPanel
* @return
*/
private JXPanel createPainterPropertiesPanel() {
basePainterControlPanel = createBasePainterControlPanel();
layoutPainterControlPanel = createLayoutPainterControl();
areaPainterControlPanel = createAreaPainterControlPanel();
JXPanel properties = new JXPanel();
FormLayout formLayout = new FormLayout(
" f:d:n, l:4dlu:n, f:d:n, l:4dlu:n, f:d:n ", // columns
"t:d:n "
); // rows
PanelBuilder builder = new PanelBuilder(formLayout, properties);
builder.setBorder(Borders.DLU4_BORDER);
CellConstraints cl = new CellConstraints();
// CellConstraints cc = new CellConstraints();
int currentColumn = 1;
builder.add(basePainterControlPanel, cl.xy(currentColumn, 1));
currentColumn +=2;
builder.add(layoutPainterControlPanel, cl.xy(currentColumn, 1));
currentColumn +=2;
builder.add(areaPainterControlPanel, cl.xy(currentColumn, 1));
currentColumn +=2;
return properties;
}
/**
* @return
*/
private JXCollapsiblePane createAreaPainterControlPanel() {
JXCollapsiblePane painterControl = new JXCollapsiblePane();
FormLayout formLayout = new FormLayout(
"5dlu, r:d:n, l:4dlu:n, f:d:n", // 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"
); // rows
PanelBuilder builder = new PanelBuilder(formLayout, painterControl);
builder.setBorder(Borders.DLU4_BORDER);
CellConstraints cl = new CellConstraints();
CellConstraints cc = new CellConstraints();
areaSeparator = new JXTitledSeparator();
areaSeparator.setName("areaPainterSeparator");
builder.add(areaSeparator, cc.xywh(1, 1, 4, 1));
int labelColumn = 2;
int widgetColumn = labelColumn + 2;
int currentRow = 3;
styleBox = new JComboBox();
styleBox.setName("styleBox");
JLabel styleBoxLabel = builder.addLabel("", cl.xywh(labelColumn, currentRow, 1, 1),
styleBox, cc.xywh(widgetColumn, currentRow, 1, 1));
currentRow += 2;
styleBoxLabel.setName("styleBoxLabel");
LabelHandler.bindLabelFor(styleBoxLabel, styleBox);
effectBox = new JComboBox();
effectBox.setName("areaEffectBox");
JLabel effectLabel = builder.addLabel("", cl.xywh(labelColumn, currentRow, 1, 1),
effectBox, cc.xywh(widgetColumn, currentRow, 1, 1));
currentRow += 2;
effectLabel.setName("effectLabel");
LabelHandler.bindLabelFor(effectLabel, effectBox);
borderWidthSlider = new JSlider(0, 100, 0);
borderWidthSlider.setPaintLabels(true);
borderWidthSlider.setPaintTicks(true);
borderWidthSlider.setMajorTickSpacing(50);
JLabel insets = builder.addLabel("", cl.xywh(labelColumn, currentRow, 1, 1), borderWidthSlider,
cc.xywh(widgetColumn, currentRow, 1, 1));
insets.setName("borderWidthLabel");
LabelHandler.bindLabelFor(insets, borderWidthSlider);
currentRow += 2;
paintStretchedBox = new JCheckBox();
paintStretchedBox.setName("paintStretchedBox");
builder.add(paintStretchedBox, cc.xywh(widgetColumn, currentRow, 1, 1));
currentRow += 2;
return painterControl;
}
/**
* @return
*/
private JXCollapsiblePane createBasePainterControlPanel() {
JXCollapsiblePane painterControl = new JXCollapsiblePane();
FormLayout formLayout = new FormLayout(
"5dlu, r:d:n, l:4dlu:n, f:d:n", // 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"
); // rows
PanelBuilder builder = new PanelBuilder(formLayout, painterControl);
builder.setBorder(Borders.DLU4_BORDER);
CellConstraints cl = new CellConstraints();
CellConstraints cc = new CellConstraints();
baseSeparator = new JXTitledSeparator();
baseSeparator.setName("basePainterSeparator");
builder.add(baseSeparator, cc.xywh(1, 1, 4, 1));
int labelColumn = 2;
int widgetColumn = labelColumn + 2;
int currentRow = 3;
interpolationBox = new JComboBox();
interpolationBox.setName("interpolationBox");
JLabel interpolationLabel = builder.addLabel("", cl.xywh(labelColumn, currentRow, 1, 1),
interpolationBox, cc.xywh(widgetColumn, currentRow, 1, 1));
currentRow += 2;
interpolationLabel.setName("interpolationLabel");
LabelHandler.bindLabelFor(interpolationLabel, interpolationBox);
filterBox = new JComboBox();
filterBox.setName("filterBox");
JLabel filterLabel = builder.addLabel("", cl.xywh(labelColumn, currentRow, 1, 1),
filterBox, cc.xywh(widgetColumn, currentRow, 1, 1));
currentRow += 2;
filterLabel.setName("filterLabel");
LabelHandler.bindLabelFor(filterLabel, filterBox);
visibleBox = new JCheckBox();
visibleBox.setName("visibleBox");
antialiasBox = new JCheckBox();
antialiasBox.setName("antialiasBox");
builder.add(visibleBox, cc.xywh(widgetColumn, currentRow, 1, 1));
currentRow += 2;
builder.add(antialiasBox, cc.xywh(widgetColumn, currentRow, 1, 1));
currentRow +=2;
return painterControl;
}
/**
* @return
*/
private JXCollapsiblePane createLayoutPainterControl() {
JXCollapsiblePane painterControl = new JXCollapsiblePane();//new JXPanel();
FormLayout formLayout = new FormLayout(
"5dlu, r:d:n, l:4dlu:n, f:d:n, l:4dlu:n, f:d:n", // 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, painterControl);
builder.setBorder(Borders.DLU4_BORDER);
CellConstraints cl = new CellConstraints();
CellConstraints cc = new CellConstraints();
layoutSeparator = new JXTitledSeparator();
layoutSeparator.setName("layoutPainterSeparator");
builder.add(layoutSeparator, cc.xywh(1, 1, 6, 1));
int labelColumn = 2;
int widgetColumn = labelColumn + 2;
int currentRow = 3;
horizontalAlignmentBox = new JComboBox();
verticalAlignmentBox = new JComboBox();
insetSlider = new JSlider(0, 100, 0);
insetSlider.setPaintLabels(true);
insetSlider.setPaintTicks(true);
insetSlider.setMajorTickSpacing(20);
fillHorizontal = new JCheckBox();
fillHorizontal.setName("fillHorizontalBox");
fillVertical = new JCheckBox();
fillVertical.setName("fillVerticalBox");
JLabel horAlign = builder.addLabel("", cl.xywh(labelColumn, currentRow, 1, 1),
horizontalAlignmentBox, cc.xywh(widgetColumn, currentRow, 3, 1));
currentRow += 2;
horAlign.setName("horizontalAlignmentLabel");
LabelHandler.bindLabelFor(horAlign, horizontalAlignmentBox);
JLabel vertAlign = builder.addLabel("", cl.xywh(labelColumn, currentRow, 1, 1),
verticalAlignmentBox, cc.xywh(widgetColumn, currentRow, 3, 1));
currentRow += 2;
vertAlign.setName("verticalAlignmentLabel");
LabelHandler.bindLabelFor(vertAlign, verticalAlignmentBox);
JLabel insets = builder.addLabel("", cl.xywh(labelColumn, currentRow, 1, 1), insetSlider,
cc.xywh(widgetColumn, currentRow, 3, 1));
currentRow += 2;
insets.setName("insetsLabel");
LabelHandler.bindLabelFor(insets, insetSlider);
JLabel fillLabel = builder.addLabel("", cl.xywh(labelColumn, currentRow, 1, 1),
fillHorizontal, cc.xywh(widgetColumn, currentRow, 1, 1));
fillLabel.setName("fillLabel");
LabelHandler.bindLabelFor(fillLabel, fillHorizontal);
builder.add(fillVertical, cc.xywh(widgetColumn + 2, currentRow, 1, 1));
currentRow += 2;
return painterControl;
}
/**
*/
private JXPanel createPainterDisplay() {
JXPanel painterDisplay = new JXPanel(new BorderLayout());
painterDisplay.setBorder(BorderFactory.createEtchedBorder());
painterDisplay.setPaintBorderInsets(false);
return painterDisplay;
}
}