/* * NodeShapeController.java * * Copyright (C) 2006-2014 Andrew Rambaut * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package figtree.treeviewer.painters; import figtree.treeviewer.AttributeColourController; import figtree.treeviewer.TreeViewer; import figtree.treeviewer.decorators.Decorator; import jam.controlpalettes.AbstractController; import jam.panels.OptionsPanel; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Map; import java.util.prefs.Preferences; import figtree.treeviewer.ControllerOptionsPanel; /** * @author Andrew Rambaut * @version $Id$ * * $HeadURL$ * * $LastChangedBy$ * $LastChangedDate$ * $LastChangedRevision$ */ public class NodeShapeController extends AbstractController { public enum NodeType { INTERNAL, EXTERNAL, BOTH } private static Preferences PREFS = Preferences.userNodeForPackage(TreeViewer.class); private static final String IS_EXTERNAL = "isExternal"; private static final String IS_INTERNAL = "isInternal"; private static final String NODE_SHAPE_KEY = "nodeShape"; public static final String SHAPE_TYPE_KEY = "shapeType"; public static final String SCALE_TYPE_KEY = "scaleType"; public static final String SIZE_ATTRIBUTE_KEY = "sizeAttribute"; public static final String COLOUR_ATTRIBUTE_KEY = "colourAttribute"; private static final String SHAPE_SIZE_KEY = "size"; private static final String SHAPE_MIN_SIZE_KEY = "minSize"; public NodeShapeController(final String title, final NodeType type, final NodeShapePainter nodeShapePainter, final AttributeColourController colourController, final TreeViewer treeViewer) { this.title = title; this.type = type; final float defaultShapeSize = PREFS.getFloat(SHAPE_SIZE_KEY, (float)NodeShapePainter.MAX_SIZE); optionsPanel = new ControllerOptionsPanel(2, 2); titleCheckBox = new JCheckBox(getTitle()); titleCheckBox.setSelected(nodeShapePainter.isVisible()); titleCheckBox.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent changeEvent) { final boolean selected = titleCheckBox.isSelected(); nodeShapePainter.setVisible(selected); } }); final ControllerOptionsPanel nodeCheckPanel; if (type == NodeType.BOTH) { externalNodeCheck = new JCheckBox("external"); internalNodeCheck = new JCheckBox("internal"); ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent event) { nodeShapePainter.setNodeType(externalNodeCheck.isSelected(), internalNodeCheck.isSelected()); } }; externalNodeCheck.addActionListener(listener); internalNodeCheck.addActionListener(listener); nodeCheckPanel = new ControllerOptionsPanel(2, 2); nodeCheckPanel.setBorder(BorderFactory.createEmptyBorder()); nodeCheckPanel.addSpanningComponent(externalNodeCheck); nodeCheckPanel.addSpanningComponent(internalNodeCheck); externalNodeCheck.setSelected(nodeShapePainter.isExternal()); internalNodeCheck.setSelected(nodeShapePainter.isInternal()); } else { nodeCheckPanel = null; externalNodeCheck = null; internalNodeCheck = null; if (type == NodeType.EXTERNAL) { nodeShapePainter.setNodeType(true, false); } else if (type == NodeType.INTERNAL) { nodeShapePainter.setNodeType(false, true); } } shapeTypeCombo = new JComboBox(NodeShapePainter.ShapeType.values()); shapeTypeCombo.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { nodeShapePainter.setShapeType((NodeShapePainter.ShapeType) shapeTypeCombo.getSelectedItem()); } }); scaleTypeCombo = new JComboBox(NodeShapePainter.ScaleType.values()); scaleTypeCombo.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { nodeShapePainter.setScaleType((NodeShapePainter.ScaleType) scaleTypeCombo.getSelectedItem()); } }); sizeAttributeCombo = new JComboBox(); // AttributeComboHelper & listener set after other controls are created... colourAttributeCombo = new JComboBox(); JButton setupColourButton = new JButton("Colour"); colourController.setupControls(colourAttributeCombo, setupColourButton); shapeSizeSpinner = new JSpinner(new SpinnerNumberModel(defaultShapeSize, 0.0, 100.0, 1.0)); shapeSizeSpinner.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent changeEvent) { double shapeSize = ((Double)shapeSizeSpinner.getValue()); nodeShapePainter.setMaxSize(shapeSize); } }); shapeMinSizeSpinner = new JSpinner(new SpinnerNumberModel(10.0, 0.0, 100.0, 1.0)); shapeMinSizeSpinner.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent changeEvent) { double minSize = ((Double)shapeMinSizeSpinner.getValue()); nodeShapePainter.setMinSize(minSize); } }); outlineStrokeCombo = new JComboBox(new String[] {"None", "0.25", "0.5", "1.0", "2.0", "3.0", "4.0", "5.0"}); outlineStrokeCombo.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { nodeShapePainter.setOutline((outlineStrokeCombo.getSelectedIndex() == 0 ? 0.0f : Float.parseFloat(outlineStrokeCombo.getSelectedItem().toString())), (Paint)outlinePaintCombo.getSelectedItem() ); } }); final Paint[] outlinePaints = {Color.black, Color.white}; outlinePaintCombo = new JComboBox(new String[] {"black", "white"}); outlinePaintCombo.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { nodeShapePainter.setOutline((outlineStrokeCombo.getSelectedIndex() == 0 ? 0.0f : Float.parseFloat(outlineStrokeCombo.getSelectedItem().toString())), outlinePaints[outlinePaintCombo.getSelectedIndex()] ); } }); final JLabel label8; if (type == NodeType.BOTH) { label8 = optionsPanel.addComponentWithLabel("Show:", nodeCheckPanel); } else { label8 = null; } final JLabel label1 = optionsPanel.addComponentWithLabel("Shape:", shapeTypeCombo); final JLabel label2 = optionsPanel.addComponentWithLabel("Max size:", shapeSizeSpinner); final JLabel label3 = optionsPanel.addComponentWithLabel("Size by:", sizeAttributeCombo); final JLabel label4 = optionsPanel.addComponentWithLabel("Min size:", shapeMinSizeSpinner); final JLabel label5 = optionsPanel.addComponentWithLabel("Using:", scaleTypeCombo); optionsPanel.addSeparator(); final JLabel label6 = optionsPanel.addComponentWithLabel("Colour by:", colourAttributeCombo); final JLabel label7 = optionsPanel.addComponentWithLabel("Setup:", setupColourButton); final JLabel label9 = optionsPanel.addComponentWithLabel("Outline width:", outlineStrokeCombo); final JLabel label10 = optionsPanel.addComponentWithLabel("Outline colour:", outlinePaintCombo); new AttributeComboHelper(colourAttributeCombo, treeViewer, "User selection").addListener(new AttributeComboHelperListener() { @Override public void attributeComboChanged() { Decorator colourDecorator = colourController.getColourDecorator(colourAttributeCombo, null); nodeShapePainter.setColourDecorator(colourDecorator); } }); new AttributeComboHelper(sizeAttributeCombo, treeViewer, NodeShapePainter.FIXED, true, false).addListener(new AttributeComboHelperListener() { @Override public void attributeComboChanged() { String attribute = (String) sizeAttributeCombo.getSelectedItem(); nodeShapePainter.setSizeAttribute(attribute); if (attribute != null) { boolean isSelected = !attribute.equals(NodeShapePainter.FIXED); label4.setEnabled(isSelected); shapeMinSizeSpinner.setEnabled(isSelected); label5.setEnabled(isSelected); scaleTypeCombo.setEnabled(isSelected); } } }); // only needed if we want to change the options depending on // the choice of shapeTypeCombo // shapeTypeCombo.addActionListener(new ActionListener() { // public void actionPerformed(ActionEvent event) { // setupOptions(); // optionsPanel.validate(); // } // }); addComponent(label1); addComponent(shapeTypeCombo); if (type == NodeType.BOTH) { addComponent(label8); addComponent(externalNodeCheck); addComponent(internalNodeCheck); } addComponent(label2); addComponent(shapeSizeSpinner); addComponent(label3); addComponent(sizeAttributeCombo); addComponent(label4); addComponent(shapeMinSizeSpinner); addComponent(label5); addComponent(scaleTypeCombo); addComponent(label6); addComponent(colourAttributeCombo); addComponent(label7); addComponent(setupColourButton); addComponent(label9); addComponent(outlineStrokeCombo); addComponent(label10); addComponent(outlinePaintCombo); enableComponents(titleCheckBox.isSelected()); titleCheckBox.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent changeEvent) { enableComponents(titleCheckBox.isSelected()); } }); } private void setupOptions() { // optionsPanel.removeAll(); fireControllerChanged(); } public JComponent getTitleComponent() { return titleCheckBox; } public JPanel getPanel() { return optionsPanel; } public boolean isInitiallyVisible() { return false; } public void initialize() { // nothing to do } public void setSettings(Map<String,Object> settings) { String key = NODE_SHAPE_KEY + (type == NodeType.INTERNAL ? "Internal" : (type == NodeType.EXTERNAL ? "External" : "")); titleCheckBox.setSelected((Boolean)settings.get(key + "." + IS_SHOWN)); if (type == NodeType.BOTH) { externalNodeCheck.setSelected((Boolean) settings.get(key + "." + IS_EXTERNAL)); internalNodeCheck.setSelected((Boolean) settings.get(key + "." + IS_INTERNAL)); } shapeTypeCombo.setSelectedItem((NodeShapePainter.ShapeType.valueOf(settings.get(key + "." + SHAPE_TYPE_KEY).toString().toUpperCase()))); scaleTypeCombo.setSelectedItem((NodeShapePainter.ScaleType.valueOf(settings.get(key + "." + SCALE_TYPE_KEY).toString().toUpperCase()))); colourAttributeCombo.setSelectedItem((String) settings.get(key + "." + COLOUR_ATTRIBUTE_KEY)); sizeAttributeCombo.setSelectedItem((String) settings.get(key + "." + SIZE_ATTRIBUTE_KEY)); shapeSizeSpinner.setValue((Double)settings.get(key + "." + SHAPE_SIZE_KEY)); shapeMinSizeSpinner.setValue((Double) settings.get(key + "." + SHAPE_MIN_SIZE_KEY)); } public void getSettings(Map<String, Object> settings) { String key = NODE_SHAPE_KEY + (type == NodeType.INTERNAL ? "Internal" : (type == NodeType.EXTERNAL ? "External" : "")); settings.put(key + "." + IS_SHOWN, titleCheckBox.isSelected()); if (type == NodeType.BOTH) { settings.put(key + "." + IS_EXTERNAL, externalNodeCheck.isSelected()); settings.put(key + "." + IS_INTERNAL, internalNodeCheck.isSelected()); } settings.put(key + "." + SHAPE_TYPE_KEY, shapeTypeCombo.getSelectedItem()); settings.put(key + "." + SCALE_TYPE_KEY, scaleTypeCombo.getSelectedItem()); settings.put(key + "." + COLOUR_ATTRIBUTE_KEY, colourAttributeCombo.getSelectedItem()); settings.put(key + "." + SIZE_ATTRIBUTE_KEY, sizeAttributeCombo.getSelectedItem()); settings.put(key + "." + SHAPE_SIZE_KEY, shapeSizeSpinner.getValue()); settings.put(key + "." + SHAPE_MIN_SIZE_KEY, shapeMinSizeSpinner.getValue()); } private final JCheckBox titleCheckBox; private final OptionsPanel optionsPanel; private final JCheckBox externalNodeCheck; private final JCheckBox internalNodeCheck; private final JComboBox shapeTypeCombo; private final JComboBox scaleTypeCombo; private final JComboBox sizeAttributeCombo; private final JComboBox colourAttributeCombo; private final JSpinner shapeSizeSpinner; private final JSpinner shapeMinSizeSpinner; private final JComboBox outlineStrokeCombo; private final JComboBox outlinePaintCombo; public String getTitle() { return title; } private final String title; private final NodeType type; }