Java tutorial
/* * This class is based on code from PlugableRendererDemo from JUNG framework * * Copyright by Neuroph Project (c) 2004, the JUNG Project and the Regents of the University of * California All rights reserved. * * This software is open-source under the BSD license; see either "license.txt" * or http://jung.sourceforge.net/license.txt for a description. * * Authors: Danyel Fisher, Joshua O'Madadhain, Tom Nelson * Created on Nov 7, 2004 * * Zoran Sevarac */ package org.neuroph.netbeans.main.easyneurons; import org.neuroph.core.*; import org.neuroph.util.NeuralNetworkType; import org.neuroph.netbeans.main.easyneurons.view.RowLayersLayout; import org.neuroph.netbeans.main.easyneurons.view.SquareLayersLayout; import org.neuroph.netbeans.main.easyneurons.view.KohonenLayout; import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.GradientPaint; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.Paint; import java.awt.Shape; import java.awt.Stroke; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.geom.Point2D; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.swing.AbstractAction; import javax.swing.AbstractButton; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.ButtonGroup; import javax.swing.DefaultListCellRenderer; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JRadioButton; import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.GradientPaint; import java.awt.GridLayout; import java.awt.Paint; import java.awt.Shape; import java.awt.Stroke; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.geom.Point2D; import java.awt.Point; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.swing.AbstractAction; import javax.swing.AbstractButton; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JRadioButton; import org.apache.commons.collections15.Factory; import org.apache.commons.collections15.Predicate; import org.apache.commons.collections15.Transformer; import org.apache.commons.collections15.functors.ConstantTransformer; import org.apache.commons.collections15.functors.MapTransformer; import edu.uci.ics.jung.algorithms.generators.random.MixedRandomGraphGenerator; import edu.uci.ics.jung.algorithms.layout.FRLayout; import edu.uci.ics.jung.algorithms.layout.GraphElementAccessor; import edu.uci.ics.jung.algorithms.layout.Layout; import edu.uci.ics.jung.algorithms.layout.DAGLayout; import edu.uci.ics.jung.algorithms.layout.KKLayout; import edu.uci.ics.jung.algorithms.layout.SpringLayout; import edu.uci.ics.jung.algorithms.layout.CircleLayout; import edu.uci.ics.jung.algorithms.layout.TreeLayout; import edu.uci.ics.jung.algorithms.layout.StaticLayout; import edu.uci.ics.jung.algorithms.scoring.VoltageScorer; import edu.uci.ics.jung.algorithms.scoring.util.VertexScoreTransformer; import edu.uci.ics.jung.algorithms.util.SelfLoopEdgePredicate; import edu.uci.ics.jung.graph.Graph; import edu.uci.ics.jung.graph.DirectedSparseGraph; import edu.uci.ics.jung.graph.DirectedGraph; import edu.uci.ics.jung.graph.util.Context; import edu.uci.ics.jung.graph.util.EdgeType; import edu.uci.ics.jung.visualization.GraphZoomScrollPane; import edu.uci.ics.jung.visualization.RenderContext; import edu.uci.ics.jung.visualization.VisualizationViewer; import edu.uci.ics.jung.visualization.control.AbstractPopupGraphMousePlugin; import edu.uci.ics.jung.visualization.control.CrossoverScalingControl; import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse; import edu.uci.ics.jung.visualization.control.EditingModalGraphMouse; import edu.uci.ics.jung.visualization.control.EditingPopupGraphMousePlugin; import edu.uci.ics.jung.visualization.control.ScalingControl; import edu.uci.ics.jung.visualization.decorators.AbstractVertexShapeTransformer; import edu.uci.ics.jung.visualization.decorators.EdgeShape; import edu.uci.ics.jung.visualization.decorators.GradientEdgePaintTransformer; import edu.uci.ics.jung.visualization.decorators.NumberFormattingTransformer; import edu.uci.ics.jung.visualization.decorators.PickableEdgePaintTransformer; import edu.uci.ics.jung.visualization.decorators.ToStringLabeller; import edu.uci.ics.jung.visualization.picking.PickedInfo; import edu.uci.ics.jung.visualization.picking.PickedState; import edu.uci.ics.jung.visualization.renderers.Renderer; import edu.uci.ics.jung.visualization.layout.LayoutTransition; import edu.uci.ics.jung.visualization.util.Animator; import edu.uci.ics.jung.graph.DelegateForest; import edu.uci.ics.jung.graph.DelegateTree; import edu.uci.ics.jung.graph.Tree; import java.text.NumberFormat; import java.text.DecimalFormat; import org.neuroph.netbeans.main.easyneurons.view.NetworkLayout; /** * @author Zoran Sevarac */ public class NeuralGraphRenderer implements ActionListener { protected JCheckBox v_color; protected JCheckBox e_color; protected JCheckBox v_stroke; protected JCheckBox e_uarrow_pred; protected JCheckBox e_darrow_pred; protected JCheckBox v_shape; protected JCheckBox v_size; protected JCheckBox v_aspect; protected JCheckBox v_labels; protected JRadioButton e_line; protected JRadioButton e_bent; protected JRadioButton e_wedge; protected JRadioButton e_quad; protected JRadioButton e_cubic; protected JCheckBox e_labels; protected JCheckBox font; protected JCheckBox e_show_d; protected JCheckBox e_show_u; protected JCheckBox v_small; protected JCheckBox zoom_at_mouse; protected JCheckBox fill_edges; protected JRadioButton layout_FR; protected JRadioButton layout_KK; protected JRadioButton layout_Circle; protected JComboBox layoutCombo; protected JRadioButton no_gradient; // protected JRadioButton gradient_absolute; protected JRadioButton gradient_relative; protected static final int GRADIENT_NONE = 0; protected static final int GRADIENT_RELATIVE = 1; // protected static final int GRADIENT_ABSOLUTE = 2; protected static int gradient_level = GRADIENT_NONE; protected SeedFillColor<Neuron> seedFillColor; protected SeedDrawColor<Neuron> seedDrawColor; protected EdgeWeightStrokeFunction<Connection> ewcs; protected VertexStrokeHighlight<Neuron, Connection> vsh; protected Transformer<Neuron, String> vs; protected Transformer<Neuron, String> vs_none; protected Transformer<Connection, String> es; protected Transformer<Connection, String> es_none; protected VertexFontTransformer<Neuron> vff; protected EdgeFontTransformer<Connection> eff; protected VertexShapeSizeAspect<Neuron, Connection> vssa; protected DirectionDisplayPredicate<Neuron, Connection> show_edge; protected DirectionDisplayPredicate<Neuron, Connection> show_arrow; protected VertexDisplayPredicate<Neuron, Connection> show_vertex; protected Predicate<Context<Graph<Neuron, Connection>, Connection>> self_loop; protected GradientPickedEdgePaintFunction<Neuron, Connection> edgeDrawPaint; protected GradientPickedEdgePaintFunction<Neuron, Connection> edgeFillPaint; protected final static Object ACTIVATION_KEY = "neuron_activation"; protected final static Object WEIGHT_KEY = "connection_weight"; protected final static Object TRANSPARENCY = "transparency"; protected VisualizationViewer vv; protected DefaultModalGraphMouse<Neuron, Connection> graphMouse; protected Set<Neuron> seedVertices = new HashSet<Neuron>(); //protected EditingModalGraphMouse<Neuron, Connection> graphMouse; protected Transformer affineTransformer; protected Transformer<Neuron, Double> voltages; protected Map<Neuron, Connection> transparency = new HashMap<Neuron, Connection>(); protected Map<Connection, Number> edge_weight = new HashMap<Connection, Number>(); protected Graph<Neuron, Connection> graph; protected NeuralNetwork neuralNet; protected JPanel graphPanel; protected Layout<Neuron, Connection> layout; protected Transformer<Neuron, Point2D> staticTranformer; private NetworkLayout netLayout; public NeuralGraphRenderer(NeuralNetwork neuralNet) { this.neuralNet = neuralNet; v_labels = new JCheckBox("show activation levels"); v_labels.addActionListener(this); e_labels = new JCheckBox("show weights"); e_labels.addActionListener(this); staticTranformer = new Transformer<Neuron, Point2D>() { int layerY = 70; @Override public Point2D transform(Neuron n) { int x, y; Dimension size = layout.getSize(); x = size.width / 2; y = layerY; Layer parentLayer = n.getParentLayer(); int parentLayerSize = parentLayer.getNeuronsCount(); int neuronIdx = parentLayer.indexOf(n); int layerIdx = parentLayer.getParentNetwork().indexOf(parentLayer); int layerLayout = netLayout.getLayerLayout(layerIdx); y = (layerIdx + 1) * 70; if (layerLayout == NetworkLayout.ROW_LAYOUT) { if (parentLayerSize % 2 != 0) { // neparni broj neurona if (neuronIdx <= (parentLayerSize / 2)) { x = size.width / 2 - 70 * ((parentLayerSize / 2) - neuronIdx) - 35; } else { x = size.width / 2 + 70 * (neuronIdx - (parentLayerSize / 2) - 1) + 35; } } else { // parni broj neurona if (neuronIdx < (parentLayerSize / 2)) { x = size.width / 2 - 70 * ((parentLayerSize / 2) - neuronIdx); } else { x = size.width / 2 + 70 * (neuronIdx - (parentLayerSize / 2)); } } if (y > layerY) layerY = y; } else { // NetworkLayout.SQUARE_LAYOUT int rowNeurons = (int) Math.sqrt(parentLayerSize); y = layerY + ((neuronIdx / rowNeurons) + 1) * 70; if (rowNeurons % 2 != 0) { // neparni broj neurona u redu if (((neuronIdx % rowNeurons) % 2) <= (rowNeurons / 2)) { x = size.width / 2 - 70 * ((rowNeurons / 2) - (neuronIdx % rowNeurons)) - 35; } else { x = size.width / 2 + 70 * ((rowNeurons / 2) - (neuronIdx % rowNeurons)) - 35; } } else { // parni broj neurona if (((neuronIdx % rowNeurons) % 2) <= (rowNeurons / 2)) { x = size.width / 2 - 70 * ((rowNeurons / 2) - (neuronIdx % rowNeurons)); } else { x = size.width / 2 + 70 * ((rowNeurons / 2) - (neuronIdx % rowNeurons)); } } } Point2D neuronLocation = new Point(x, y); return neuronLocation; } }; graph = createGraph(); layout = new StaticLayout<Neuron, Connection>(graph, staticTranformer); try { vv = new VisualizationViewer<Neuron, Connection>(layout); } catch (Exception ex) { ex.printStackTrace(); } createGraphPanel(); } public JPanel getGraphPanel() { return this.graphPanel; } public void createGraphPanel() { graph = createGraph(); setNetLayout(neuralNet.getNetworkType()); //layout = new FRLayout<Neuron, Connection>(graph); layout = new StaticLayout<Neuron, Connection>(graph, staticTranformer); vv = new VisualizationViewer<Neuron, Connection>(layout); // add Shape based pick support // vv.setPickSupport(new ShapePickSupport()); // PickedState picked_state = vv.getPickedState(); PickedState<Neuron> picked_state = vv.getPickedVertexState(); // affineTransformer = vv.getLayoutTransformer(); // create decorators seedFillColor = new SeedFillColor<Neuron>(picked_state); seedDrawColor = new SeedDrawColor<Neuron>(picked_state); ewcs = new EdgeWeightStrokeFunction<Connection>(edge_weight); vsh = new VertexStrokeHighlight<Neuron, Connection>(graph, picked_state); vff = new VertexFontTransformer<Neuron>(); eff = new EdgeFontTransformer<Connection>(); vs_none = new ConstantTransformer(null); es_none = new ConstantTransformer(null); vssa = new VertexShapeSizeAspect<Neuron, Connection>(graph, voltages); show_edge = new DirectionDisplayPredicate<Neuron, Connection>(true, true); show_arrow = new DirectionDisplayPredicate<Neuron, Connection>(true, false); show_vertex = new VertexDisplayPredicate<Neuron, Connection>(false); vv.getRenderContext().setVertexFontTransformer(vff); vv.getRenderContext().setVertexShapeTransformer(vssa); vv.getRenderContext().setVertexStrokeTransformer(vsh); vv.getRenderContext().setEdgeFontTransformer(eff); vv.getRenderContext().setEdgeStrokeTransformer(ewcs); vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line<Neuron, Connection>()); this.graphPanel = new JPanel(); graphPanel.setLayout(new BorderLayout()); vv.setBackground(Color.white); GraphZoomScrollPane scrollPane = new GraphZoomScrollPane(vv); scrollPane.setPreferredSize(new Dimension(500, 400)); graphPanel.add(scrollPane); // Factory<Neuron> vertexFactory = new VertexFactory(); // Factory<Connection> edgeFactory = new EdgeFactory(); // // graphMouse = new EditingModalGraphMouse(vv.getRenderContext(), // vertexFactory, edgeFactory); graphMouse = new DefaultModalGraphMouse<Neuron, Connection>(); vv.setGraphMouse(graphMouse); graphMouse.add(new PopupGraphMousePlugin()); vssa.setScaling(false); vv.setVertexToolTipTransformer(new VoltageTips<Number>()); addControls(graphPanel); } /** * Generates a mixed-mode random graph, runs VoltageRanker on it, and * returns the resultant graph. */ public Graph createGraph() { Graph<Neuron, Connection> g = new DirectedSparseGraph<Neuron, Connection>(); // Iterator<Layer> li = this.neuralNet.getLayersIterator(); // while (li.hasNext()) { for (Layer layer : this.neuralNet.getLayers()) { // Layer layer = li.next(); // Iterator<Neuron> ni = layer.getNeuronsIterator(); // while (ni.hasNext()) { // Neuron neuron = ni.next(); for (Neuron neuron : layer.getNeurons()) { g.addVertex(neuron); // Iterator<Connection> ci = neuron.getInputConnections().iterator(); // while (ci.hasNext()) { // Connection connection = ci.next(); for (Connection connection : neuron.getInputConnections()) { Neuron fromNeuron = connection.getFromNeuron(); // .getConnectedNeuron(); g.addEdge(connection, fromNeuron, neuron); // used for highlighting weights edge_weight.put(connection, connection.getWeight().getValue()); } } } voltages = new Transformer<Neuron, Double>() { @Override public Double transform(Neuron n) { return n.getOutput(); } }; vs = new Transformer<Neuron, String>() { @Override public String transform(Neuron n) { NumberFormat numberFormat = DecimalFormat.getNumberInstance(); numberFormat.setMaximumFractionDigits(4); return numberFormat.format(n.getOutput()); } }; es = new Transformer<Connection, String>() { @Override public String transform(Connection c) { NumberFormat numberFormat = DecimalFormat.getNumberInstance(); numberFormat.setMaximumFractionDigits(5); return numberFormat.format(c.getWeight().getValue()); } }; return g; } /** * @param jp * panel to which controls will be added */ protected void addControls(final JPanel jp) { final JPanel control_panel = new JPanel(); jp.add(control_panel, BorderLayout.EAST); control_panel.setLayout(new GridBagLayout()); java.awt.GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.insets = new java.awt.Insets(5, 5, 0, 5); gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; // control_panel.setBackground(new Color(00, 255, 00)); final Box vertex_panel = Box.createVerticalBox(); vertex_panel.setBorder(BorderFactory.createTitledBorder("Neurons")); final Box edge_panel = Box.createVerticalBox(); edge_panel.setBorder(BorderFactory.createTitledBorder("Connections")); final Box edges_and_vertex_panel = Box.createVerticalBox(); // Box zoom_and_mode_panel = Box.createVerticalBox(); // zoom_and_mode_panel.setBorder(BorderFactory.createTitledBorder("Other controls")); // final Box layout_panel = Box.createVerticalBox(); // layout_panel.setBorder(BorderFactory.createTitledBorder("Layout")); // JPanel zoom_and_mode_panel = new JPanel(); // zoom_and_mode_panel.setLayout(new GridBagLayout() ); // //GridLayout(3,1) // zoom_and_mode_panel.setBackground(new Color(0,255,0)); edges_and_vertex_panel.add(vertex_panel); edges_and_vertex_panel.add(edge_panel); // edges_and_vertex_panel.add(layout_panel); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; control_panel.add(edges_and_vertex_panel, gridBagConstraints); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; // control_panel.add(layout_panel, gridBagConstraints); // originalni layout // control_panel.add(vertex_panel, BorderLayout.WEST); // control_panel.add(edge_panel, BorderLayout.EAST); // control_panel.add(edges_and_vertex_panel, BorderLayout.CENTER); // set up vertex controls v_color = new JCheckBox("vertex seed coloring"); v_color.addActionListener(this); // v_stroke = new JCheckBox("<html>stroke highlight selected</html>"); // v_stroke.addActionListener(this); v_shape = new JCheckBox("vertex degree shapes"); v_shape.addActionListener(this); v_size = new JCheckBox("activation size"); v_size.addActionListener(this); v_size.setSelected(false); v_aspect = new JCheckBox("vertex degree ratio stretch"); v_aspect.addActionListener(this); v_small = new JCheckBox("filter vertices of degree < " + VertexDisplayPredicate.MIN_DEGREE); v_small.addActionListener(this); // vertex_panel.add(v_color); vertex_panel.add(v_labels); // vertex_panel.add(v_shape); vertex_panel.add(v_size); // vertex_panel.add(v_aspect); // vertex_panel.add(v_small); // vertex_panel.add(v_stroke); // set up edge controls // JPanel gradient_panel = new JPanel(new GridLayout(1, 0)); // gradient_panel.setBorder(BorderFactory.createTitledBorder("Edge paint")); // no_gradient = new JRadioButton("Solid color"); // no_gradient.addActionListener(this); // no_gradient.setSelected(true); // // gradient_absolute = new JRadioButton("Absolute gradient"); // // gradient_absolute.addActionListener(this); // gradient_relative = new JRadioButton("Gradient"); // gradient_relative.addActionListener(this); // ButtonGroup bg_grad = new ButtonGroup(); // bg_grad.add(no_gradient); // bg_grad.add(gradient_relative); // //bg_grad.add(gradient_absolute); // gradient_panel.add(no_gradient); // //gradientGrid.add(gradient_absolute); // gradient_panel.add(gradient_relative); // JPanel shape_panel = new JPanel(new GridLayout(3, 2)); // shape_panel.setBorder(BorderFactory // .createTitledBorder("Connection shape")); // e_line = new JRadioButton("line"); // e_line.addActionListener(this); // e_line.setSelected(true); // // e_bent = new JRadioButton("bent line"); // // e_bent.addActionListener(this); // e_wedge = new JRadioButton("wedge"); // e_wedge.addActionListener(this); // e_quad = new JRadioButton("quad curve"); // e_quad.addActionListener(this); // e_cubic = new JRadioButton("cubic curve"); // e_cubic.addActionListener(this); // ButtonGroup bg_shape = new ButtonGroup(); // bg_shape.add(e_line); // // bg.add(e_bent); // bg_shape.add(e_wedge); // bg_shape.add(e_quad); // bg_shape.add(e_cubic); // shape_panel.add(e_line); // // shape_panel.add(e_bent); // // shape_panel.add(e_wedge); // shape_panel.add(e_quad); // shape_panel.add(e_cubic); // // fill_edges = new JCheckBox("fill edge shapes"); // // fill_edges.setSelected(false); // // fill_edges.addActionListener(this); // // shape_panel.add(fill_edges); // shape_panel.setOpaque(true); e_color = new JCheckBox("weight highlighting"); e_color.addActionListener(this); e_uarrow_pred = new JCheckBox("undirected"); e_uarrow_pred.addActionListener(this); e_darrow_pred = new JCheckBox("directed"); e_darrow_pred.addActionListener(this); e_darrow_pred.setSelected(true); // JPanel arrow_panel = new JPanel(new GridLayout(1,0)); // arrow_panel.setBorder(BorderFactory.createTitledBorder("Show arrows")); // arrow_panel.add(e_uarrow_pred); // arrow_panel.add(e_darrow_pred); e_show_d = new JCheckBox("directed"); e_show_d.addActionListener(this); e_show_d.setSelected(true); e_show_u = new JCheckBox("undirected"); e_show_u.addActionListener(this); e_show_u.setSelected(true); JPanel show_edge_panel = new JPanel(new GridLayout(1, 0)); show_edge_panel.setBorder(BorderFactory.createTitledBorder("Show edges")); show_edge_panel.add(e_show_u); show_edge_panel.add(e_show_d); // shape_panel.setAlignmentX(Component.LEFT_ALIGNMENT); // edge_panel.add(shape_panel); // gradient_panel.setAlignmentX(Component.LEFT_ALIGNMENT); // edge_panel.add(gradient_panel); // show_edge_panel.setAlignmentX(Component.LEFT_ALIGNMENT); // edge_panel.add(show_edge_panel); // arrow_panel.setAlignmentX(Component.LEFT_ALIGNMENT); // edge_panel.add(arrow_panel); e_color.setAlignmentX(Component.LEFT_ALIGNMENT); edge_panel.add(e_color); e_labels.setAlignmentX(Component.LEFT_ALIGNMENT); edge_panel.add(e_labels); // Class<?>[] combos = getLayoutOptions(); // final JComboBox layoutCombo = new JComboBox(combos); // // use a renderer to shorten the layout name presentation // layoutCombo.setRenderer(new DefaultListCellRenderer() { // public Component getListCellRendererComponent(JList list, // Object value, int index, boolean isSelected, // boolean cellHasFocus) { // String valueString = value.toString(); // valueString = valueString.substring(valueString // .lastIndexOf('.') + 1); // return super.getListCellRendererComponent(list, valueString, // index, isSelected, cellHasFocus); // } // }); // layoutCombo.addActionListener(new LayoutChooser(layoutCombo, vv)); //// UNDO: layoutCombo.setSelectedItem(FRLayout.class); // layout_panel.add(layoutCombo); // set up zoom controls zoom_at_mouse = new JCheckBox("<html><center>zoom at mouse<p>(wheel only)</center></html>"); zoom_at_mouse.addActionListener(this); final ScalingControl scaler = new CrossoverScalingControl(); JButton plus = new JButton("+"); plus.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { scaler.scale(vv, 1.1f, vv.getCenter()); } }); JButton minus = new JButton("-"); minus.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { scaler.scale(vv, 1 / 1.1f, vv.getCenter()); } }); JPanel zoomPanel = new JPanel(); zoomPanel.setAlignmentX(Component.RIGHT_ALIGNMENT); zoomPanel.setBorder(BorderFactory.createTitledBorder("Zoom")); zoomPanel.add(plus); zoomPanel.add(minus); gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.insets = new java.awt.Insets(5, 5, 0, 5); gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; JComboBox modeBox = graphMouse.getModeComboBox(); modeBox.setAlignmentX(Component.RIGHT_ALIGNMENT); JPanel modePanel = new JPanel(new BorderLayout()) { @Override public Dimension getMaximumSize() { return getPreferredSize(); } }; modePanel.setBorder(BorderFactory.createTitledBorder("Mouse Mode")); modePanel.add(modeBox); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 2; control_panel.add(modePanel, gridBagConstraints); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 3; control_panel.add(zoomPanel, gridBagConstraints); // add font control to center panel font = new JCheckBox("bold text"); font.addActionListener(this); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 4; control_panel.add(font, gridBagConstraints); } private void setNetLayout(NeuralNetworkType type) { if (type == null) { this.netLayout = new RowLayersLayout(); return; } switch (type) { case ADALINE: this.netLayout = new RowLayersLayout(); break; case PERCEPTRON: this.netLayout = new RowLayersLayout(); break; case MULTI_LAYER_PERCEPTRON: this.netLayout = new RowLayersLayout(); break; case HOPFIELD: this.netLayout = new SquareLayersLayout(); break; case KOHONEN: this.netLayout = new KohonenLayout(); break; case NEURO_FUZZY_REASONER: this.netLayout = new RowLayersLayout(); break; default: this.netLayout = new RowLayersLayout(); break; } } private static Class<?>[] getLayoutOptions() { List<Class<?>> layouts = new ArrayList<Class<?>>(); layouts.add(DAGLayout.class); layouts.add(KKLayout.class); layouts.add(FRLayout.class); layouts.add(CircleLayout.class); layouts.add(TreeLayout.class); return layouts.toArray(new Class[0]); } private final static class VertexFontTransformer<V> implements Transformer<V, Font> { protected boolean bold = false; Font f = new Font("Helvetica", Font.PLAIN, 12); Font b = new Font("Helvetica", Font.BOLD, 12); public void setBold(boolean bold) { this.bold = bold; } @Override public Font transform(V v) { if (bold) return b; else return f; } } private final static class EdgeFontTransformer<E> implements Transformer<E, Font> { protected boolean bold = false; Font f = new Font("Helvetica", Font.PLAIN, 12); Font b = new Font("Helvetica", Font.BOLD, 12); public void setBold(boolean bold) { this.bold = bold; } @Override public Font transform(E e) { if (bold) return b; else return f; } } @Override public void actionPerformed(ActionEvent e) { AbstractButton source = (AbstractButton) e.getSource(); if (source == e_line) { if (source.isSelected()) { vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line<Neuron, Connection>()); } } else if (source == e_quad) { if (source.isSelected()) { vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.QuadCurve<Neuron, Connection>()); } } else if (source == e_cubic) { if (source.isSelected()) { vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.CubicCurve<Neuron, Connection>()); } } else if (source == v_labels) { if (source.isSelected()) vv.getRenderContext().setVertexLabelTransformer(vs); else vv.getRenderContext().setVertexLabelTransformer(vs_none); } else if (source == e_labels) { if (source.isSelected()) vv.getRenderContext().setEdgeLabelTransformer(es); else vv.getRenderContext().setEdgeLabelTransformer(es_none); } else if (source == font) { vff.setBold(source.isSelected()); eff.setBold(source.isSelected()); } else if (source == e_color) { ewcs.setWeighted(source.isSelected()); } else if (source == v_size) { vssa.setScaling(source.isSelected()); } else if (source == v_stroke) { vsh.setHighlight(source.isSelected()); } vv.repaint(); } /** * a GraphMousePlugin that offers popup * menu support */ protected class PopupGraphMousePlugin extends AbstractPopupGraphMousePlugin implements MouseListener { public PopupGraphMousePlugin() { this(MouseEvent.BUTTON3_MASK); } public PopupGraphMousePlugin(int modifiers) { super(modifiers); } /** * If this event is over a Vertex, pop up a menu to * allow the user to increase/decrease the voltage * attribute of this Vertex * @param e */ @SuppressWarnings("unchecked") @Override protected void handlePopup(MouseEvent e) { final VisualizationViewer<Neuron, Connection> vv = (VisualizationViewer<Neuron, Connection>) e .getSource(); Point2D p = e.getPoint();//vv.getRenderContext().getBasicTransformer().inverseViewTransform(e.getPoint()); GraphElementAccessor<Neuron, Connection> pickSupport = vv.getPickSupport(); // if(pickSupport != null) { // final Neuron v = pickSupport.getVertex(vv.getGraphLayout(), p.getX(), p.getY()); // if(v != null) { // JPopupMenu popup = new JPopupMenu(); // popup.add(new AbstractAction("Delete Neuron") { // @Override // public void actionPerformed(ActionEvent e) { //// Double value = Math.min(1, transparency.get(v).doubleValue()+0.1); //// transparency.put(v, value); //// transparency.put(v, )transparency.get(v); //// MutableDouble value = (MutableDouble)transparency.getNumber(v); //// value.setDoubleValue(Math.min(1, value.doubleValue() + 0.1)); // vv.repaint(); // } // }); // popup.add(new AbstractAction("Neuron Properties"){ // @Override // public void actionPerformed(ActionEvent e) { //// Double value = Math.max(0, //// transparency.get(v).doubleValue()-0.1); //// transparency.put(v, value); //// MutableDouble value = (MutableDouble)transparency.getNumber(v); //// value.setDoubleValue(Math.max(0, value.doubleValue() - 0.1)); // vv.repaint(); // } // }); // popup.show(vv, e.getX(), e.getY()); // } else { // final Connection edge = pickSupport.getEdge(vv.getGraphLayout(), p.getX(), p.getY()); // if(edge != null) { // JPopupMenu popup = new JPopupMenu(); // popup.add(new AbstractAction(edge.toString()) { // @Override // public void actionPerformed(ActionEvent e) { // System.err.println("got "+edge); // } // }); // popup.show(vv, e.getX(), e.getY()); // // } // } // } } } /** * Controls the shape, size, and aspect ratio for each vertex. * * @author Joshua O'Madadhain */ private final static class VertexShapeSizeAspect<V, E> extends AbstractVertexShapeTransformer<V> implements Transformer<V, Shape> { protected boolean stretch = false; protected boolean scale = false; protected boolean funny_shapes = false; protected Transformer<V, Double> voltages; protected Graph<V, E> graph; // protected AffineTransform scaleTransform = new AffineTransform(); public VertexShapeSizeAspect(Graph<V, E> graphIn, Transformer<V, Double> voltagesIn) { this.graph = graphIn; this.voltages = voltagesIn; setSizeTransformer(new Transformer<V, Integer>() { @Override public Integer transform(V v) { if (scale) return (int) (voltages.transform(v) * 30) + 20; else return 20; } }); setAspectRatioTransformer(new Transformer<V, Float>() { @Override public Float transform(V v) { if (stretch) { return (float) (graph.inDegree(v) + 1) / (graph.outDegree(v) + 1); } else { return 1.0f; } } }); } public void setStretching(boolean stretch) { this.stretch = stretch; } public void setScaling(boolean scale) { this.scale = scale; } public void useFunnyShapes(boolean use) { this.funny_shapes = use; } @Override public Shape transform(V v) { if (funny_shapes) { if (graph.degree(v) < 5) { int sides = Math.max(graph.degree(v), 3); return factory.getRegularPolygon(v, sides); } else return factory.getRegularStar(v, graph.degree(v)); } else return factory.getEllipse(v); } } private final class SeedFillColor<V> implements Transformer<V, Paint> { protected PickedInfo<V> pi; protected final static float dark_value = 0.8f; protected final static float light_value = 0.2f; protected boolean seed_coloring; public SeedFillColor(PickedInfo<V> pi) { this.pi = pi; seed_coloring = false; } public void setSeedColoring(boolean b) { this.seed_coloring = b; } // public Paint getDrawPaint(V v) // { // return Color.BLACK; // } @Override public Paint transform(V v) { float alpha = (float) transparency.get(v).getWeight().getValue(); if (pi.isPicked(v)) { return new Color(1f, 1f, 0, alpha); } else { if (seed_coloring && seedVertices.contains(v)) { Color dark = new Color(0, 0, dark_value, alpha); Color light = new Color(0, 0, light_value, alpha); return new GradientPaint(0, 0, dark, 10, 0, light, true); } else return new Color(1f, 0, 0, alpha); } } } private final static class EdgeWeightStrokeFunction<E> implements Transformer<E, Stroke> { protected static final Stroke basic = new BasicStroke(1); protected static final Stroke heavy = new BasicStroke(2); protected static final Stroke dotted = RenderContext.DOTTED; protected boolean weighted = false; protected Map<E, Number> edge_weight; public EdgeWeightStrokeFunction(Map<E, Number> edge_weight) { this.edge_weight = edge_weight; } public void setWeighted(boolean weighted) { this.weighted = weighted; } @Override public Stroke transform(E e) { if (weighted) { if (drawHeavy(e)) return heavy; else return dotted; } else return basic; } protected boolean drawHeavy(E e) { double value = edge_weight.get(e).doubleValue(); if (value > 0.7) return true; else return false; } } private final static class VertexStrokeHighlight<V, E> implements Transformer<V, Stroke> { protected boolean highlight = false; protected Stroke heavy = new BasicStroke(5); protected Stroke medium = new BasicStroke(3); protected Stroke light = new BasicStroke(1); protected PickedInfo<V> pi; protected Graph<V, E> graph; public VertexStrokeHighlight(Graph<V, E> graph, PickedInfo<V> pi) { this.graph = graph; this.pi = pi; } public void setHighlight(boolean highlight) { this.highlight = highlight; } @Override public Stroke transform(V v) { if (highlight) { if (pi.isPicked(v)) return heavy; else { for (V w : graph.getNeighbors(v)) { // for (Iterator iter = graph.getNeighbors(v)v.getNeighbors().iterator(); iter.hasNext(); ) // { // Vertex w = (Vertex)iter.next(); if (pi.isPicked(w)) return medium; } return light; } } else return light; } } private final static class DirectionDisplayPredicate<V, E> implements Predicate<Context<Graph<V, E>, E>> //extends AbstractGraphPredicate<V,E> { protected boolean show_d; protected boolean show_u; public DirectionDisplayPredicate(boolean show_d, boolean show_u) { this.show_d = show_d; this.show_u = show_u; } public void showDirected(boolean b) { show_d = b; } public void showUndirected(boolean b) { show_u = b; } @Override public boolean evaluate(Context<Graph<V, E>, E> context) { Graph<V, E> graph = context.graph; E e = context.element; if (graph.getEdgeType(e) == EdgeType.DIRECTED && show_d) { return true; } if (graph.getEdgeType(e) == EdgeType.UNDIRECTED && show_u) { return true; } return false; } } private final static class VertexDisplayPredicate<V, E> implements Predicate<Context<Graph<V, E>, V>> // extends AbstractGraphPredicate<V,E> { protected boolean filter_small; protected final static int MIN_DEGREE = 4; public VertexDisplayPredicate(boolean filter) { this.filter_small = filter; } public void filterSmall(boolean b) { filter_small = b; } @Override public boolean evaluate(Context<Graph<V, E>, V> context) { Graph<V, E> graph = context.graph; V v = context.element; // Vertex v = (Vertex)arg0; if (filter_small) return (graph.degree(v) >= MIN_DEGREE); else return true; } } private final class SeedDrawColor<V> implements Transformer<V, Paint> { protected PickedInfo<V> pi; protected final static float dark_value = 0.8f; protected final static float light_value = 0.2f; protected boolean seed_coloring; public SeedDrawColor(PickedInfo<V> pi) { this.pi = pi; seed_coloring = false; } public void setSeedColoring(boolean b) { this.seed_coloring = b; } @Override public Paint transform(V v) { return Color.BLACK; } // public Paint getFillPaint(V v) // { // float alpha = transparency.get(v).floatValue(); // if (pi.isPicked(v)) // { // return new Color(1f, 1f, 0, alpha); // } // else // { // if (seed_coloring && seedVertices.contains(v)) // { // Color dark = new Color(0, 0, dark_value, alpha); // Color light = new Color(0, 0, light_value, alpha); // return new GradientPaint( 0, 0, dark, 10, 0, light, true); // } // else // return new Color(1f, 0, 0, alpha); // } // // } } public class GradientPickedEdgePaintFunction<V, E> extends GradientEdgePaintTransformer<V, E> { private Transformer<E, Paint> defaultFunc; protected boolean fill_edge = false; Predicate<Context<Graph<V, E>, E>> selfLoop = new SelfLoopEdgePredicate<V, E>(); public GradientPickedEdgePaintFunction(Transformer<E, Paint> defaultEdgePaintFunction, VisualizationViewer<V, E> vv) { super(Color.WHITE, Color.BLACK, vv); this.defaultFunc = defaultEdgePaintFunction; } public void useFill(boolean b) { fill_edge = b; } @Override public Paint transform(E e) { if (gradient_level == GRADIENT_NONE) { return defaultFunc.transform(e); } else { return super.transform(e); } } @Override protected Color getColor2(E e) { return vv.getPickedEdgeState().isPicked(e) ? Color.CYAN : c2; } // public Paint getFillPaint(E e) // { // if (selfLoop.evaluateEdge(vv.getGraphLayout().getGraph(), e) || !fill_edge) // return null; // else // return getDrawPaint(e); // } } public class VoltageTips<E> implements Transformer<Neuron, String> { @Override public String transform(Neuron vertex) { return "Voltage:" + voltages.transform(vertex); } } // class VertexFactory implements Factory<Neuron> { // // public Neuron create() { // return new Neuron(); // } // } // class EdgeFactory implements Factory<Connection> { // // public Connection create() { // return new Connection(); // } // } /** * * @author danyelf */ private final class LayoutChooser implements ActionListener { private final JComboBox jcb; private final VisualizationViewer<Neuron, Connection> vv; private LayoutChooser(JComboBox jcb, VisualizationViewer<Neuron, Connection> vv) { super(); this.jcb = jcb; this.vv = vv; } @Override public void actionPerformed(ActionEvent arg0) { Object[] constructorArgs = { graph }; Class<? extends Layout<Neuron, Connection>> layoutC = (Class<? extends Layout<Neuron, Connection>>) jcb .getSelectedItem(); // Class lay = layoutC; try { Constructor<? extends Layout<Neuron, Connection>> constructor = layoutC .getConstructor(new Class[] { Graph.class }); Object o = constructor.newInstance(constructorArgs); Layout<Neuron, Connection> l = (Layout<Neuron, Connection>) o; l.setInitializer(vv.getGraphLayout()); l.setSize(vv.getSize()); LayoutTransition<Neuron, Connection> lt = new LayoutTransition<Neuron, Connection>(vv, vv.getGraphLayout(), l); Animator animator = new Animator(lt); animator.start(); vv.getRenderContext().getMultiLayerTransformer().setToIdentity(); vv.repaint(); } catch (Exception e) { e.printStackTrace(); } } } }