/* * $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; } }