/*** * Copyright (c) 2008, Endless Loop Software, Inc. * * This file is part of EgoNet. * * EgoNet 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 3 of the License, or * (at your option) any later version. * * EgoNet 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, see <http://www.gnu.org/licenses/>. */ package org.egonet.graph; import org.jdesktop.layout.GroupLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import javax.swing.*; import java.util.*; import edu.uci.ics.jung.algorithms.layout.CircleLayout; import edu.uci.ics.jung.algorithms.layout.FRLayout; import edu.uci.ics.jung.algorithms.layout.ISOMLayout; import edu.uci.ics.jung.algorithms.layout.KKLayout; import edu.uci.ics.jung.graph.Graph; import edu.uci.ics.jung.visualization.VisualizationViewer; import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse; import edu.uci.ics.jung.visualization.control.CrossoverScalingControl; import edu.uci.ics.jung.visualization.control.ScalingControl; public class GraphTabPanel extends JPanel { private List<Class> layoutOptions; private DefaultModalGraphMouse graphMouse; private VisualizationViewer vv; private GraphRenderer graphRenderer; private GroupLayout layout; private JLabel layoutLabel; private JComboBox<Class> layoutCombo; private JLabel modeLabel; private JComboBox modeCombo; private JLabel bgcolorLabel; private JButton bgcolorButton; private JCheckBox showLabelChkBox; private JCheckBox showWeightChkBox; private JLabel zoomLabel; private JButton zoomInButton; private JButton zoomOutButton; private JLabel layoutSize; private JButton increaseLayoutSize; private JButton decreaseLayoutSize; private JButton reiterate; private JButton reset; private ScalingControl scaler; public GraphTabPanel(Graph g, VisualizationViewer vv, DefaultModalGraphMouse graphMouse) { this.graphMouse = graphMouse; this.vv = vv; createComponents(); } public GraphTabPanel(GraphRenderer gr) { this.graphRenderer = gr; GraphRenderer.getGraph(); this.graphMouse = gr.getGraphMouse(); this.vv = GraphRenderer.getVv(); createComponents(); } private void createComponents() { layout = new GroupLayout(this); this.setLayout(layout); scaler = new CrossoverScalingControl(); layout.setAutocreateGaps(true); layout.setAutocreateContainerGaps(true); // label combo pair for choosing different layouts layoutLabel = new JLabel("Choose Layout"); layoutLabel.setOpaque(true); // add all possible layouts to the layout combo layoutOptions = new ArrayList<Class>(); layoutOptions.add(KKLayout.class); // Kamada-Kawai layoutOptions.add(FRLayout.class); // // Fruchterman-Reingold layoutOptions.add(CircleLayout.class); // Vertices randomly on a circle layoutOptions.add(ELSFRLayout2.class); layoutOptions.add(ISOMLayout.class); // Meyer's "Self-Organizing Map" layout Class[] layoutList = (Class[]) layoutOptions.toArray(new Class[0]); layoutCombo = new JComboBox<Class>(layoutList); // 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.setPreferredSize(new Dimension(20, 20)); layoutCombo.setMaximumSize(new Dimension(20, 30)); layoutCombo.setSelectedItem(ELSFRLayout2.class); layoutCombo.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { // call renderer to render the graph with selected layout JComboBox cb = (JComboBox) e.getSource(); Class lay = (Class) cb.getSelectedItem(); try { graphRenderer.changeLayout(lay); } catch (Exception ex) { throw new RuntimeException(ex); } } }); // label combo pair to choose mode of operation modeLabel = new JLabel("Choose Mode"); modeLabel.setOpaque(true); modeCombo = graphMouse.getModeComboBox(); modeCombo.setPreferredSize(new Dimension(20, 20)); modeCombo.setMaximumSize(new Dimension(20, 30)); modeCombo.addItemListener(((DefaultModalGraphMouse) vv.getGraphMouse()) .getModeListener()); // add label button pair for changing background color bgcolorLabel = new JLabel("BackGround"); bgcolorLabel.setOpaque(true); bgcolorButton = new JButton(); bgcolorButton.setText(" "); bgcolorButton.setBackground(vv.getBackground()); bgcolorButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { // code displaying a color box/palette to choose from Color c = JColorChooser.showDialog(null, "Choose color", vv .getBackground()); if (c != null) { vv.setBackground(c); JButton colorButton = (JButton) e.getSource(); colorButton.setBackground(c); } } }); // create check boxes for showing labels and Edge weights showLabelChkBox = new JCheckBox("Show Node Labels"); showLabelChkBox.setSelected(true); showLabelChkBox.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) graphRenderer.drawNodeLabels(); else graphRenderer.hideNodeLabels(); } }); showWeightChkBox = new JCheckBox("Show Edge Weights"); showWeightChkBox.setSelected(false); showWeightChkBox.setVisible(false); showWeightChkBox.setEnabled(false); showWeightChkBox.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { GraphRenderer.showEdgeWeights = true; graphRenderer.drawEdgeLabels(); graphRenderer.setShowNodeLabels(true); } else graphRenderer.hideEdgeLabels(); graphRenderer.setShowNodeLabels(false); } }); zoomLabel = new JLabel("Zoom: "); zoomInButton = new JButton("+"); zoomInButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { scaler.scale(vv, 1.1f, vv.getCenter()); } }); zoomOutButton = new JButton("-"); zoomOutButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { scaler.scale(vv, 1/1.1f, vv.getCenter()); } }); layoutSize = new JLabel("Layout Size:"); increaseLayoutSize = new JButton("+"); increaseLayoutSize.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ org.jdesktop.swingworker.SwingWorker worker = new org.jdesktop.swingworker.SwingWorker(){ @Override protected Object doInBackground() throws Exception { decreaseLayoutSize.paintImmediately(new Rectangle()); return null; } public void done(){ graphRenderer.changeLayoutSize(50, 50); } }; worker.execute(); } }); decreaseLayoutSize = new JButton("-"); decreaseLayoutSize.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ org.jdesktop.swingworker.SwingWorker worker = new org.jdesktop.swingworker.SwingWorker(){ @Override protected Object doInBackground() throws Exception { decreaseLayoutSize.paintImmediately(new Rectangle()); return null; } public void done(){ graphRenderer.changeLayoutSize(-50, -50); } }; worker.execute(); } }); reiterate = new JButton("Reiterate"); reiterate.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ org.jdesktop.swingworker.SwingWorker worker = new org.jdesktop.swingworker.SwingWorker(){ @Override protected Object doInBackground() throws Exception { reiterate.paintImmediately(new Rectangle()); return null; } public void done(){ graphRenderer.reiterate(); } }; worker.execute(); } }); reset = new JButton("Reset all settings"); reset.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ GraphRenderer.getGraphSettings().reset(); } }); // display in the panel using GroupLayout GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup(); // The sequential group in turn contains two parallel groups. // One parallel group contains the labels, the other the text fields. // Putting the labels in a parallel group along the horizontal axis // positions them at the same x location. // // Variable indentation is used to reinforce the level of grouping. hGroup.add(layout.createParallelGroup().add(layoutLabel).add(modeLabel) .add(bgcolorLabel).add(showLabelChkBox).add(showWeightChkBox) .add(zoomLabel)); hGroup.add(layout.createParallelGroup().add(layoutCombo).add(modeCombo) .add(bgcolorButton).add(zoomInButton).add(zoomOutButton)); hGroup.add(layout.createParallelGroup().add(layoutSize)); hGroup.add(layout.createParallelGroup().add(increaseLayoutSize).add(decreaseLayoutSize)); hGroup.add(layout.createParallelGroup().add(reiterate)); hGroup.add(layout.createParallelGroup().add(reset)); layout.setHorizontalGroup(hGroup); // Create a sequential group for the vertical axis. GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup(); // The sequential group contains two parallel groups that align // the contents along the baseline. The first parallel group contains // the first label and text field, and the second parallel group // contains // the second label and text field. By using a sequential group // the labels and text fields are positioned vertically after one // another. vGroup.add(layout.createParallelGroup(GroupLayout.BASELINE).add( layoutLabel).add(layoutCombo)); vGroup.add(layout.createParallelGroup(GroupLayout.BASELINE).add( modeLabel).add(modeCombo)); vGroup.add(layout.createParallelGroup(GroupLayout.BASELINE).add( bgcolorLabel).add(bgcolorButton)); vGroup.add(layout.createParallelGroup(GroupLayout.BASELINE).add( zoomLabel).add(zoomInButton) .add(layoutSize).add(increaseLayoutSize).add(reiterate) .add(layoutSize).add(increaseLayoutSize).add(reset)); vGroup.add(layout.createParallelGroup(GroupLayout.BASELINE).add( zoomOutButton).add(decreaseLayoutSize)); vGroup.add(layout.createParallelGroup(GroupLayout.BASELINE).add( showLabelChkBox)); vGroup.add(layout.createParallelGroup(GroupLayout.BASELINE).add( showWeightChkBox)); layout.setVerticalGroup(vGroup); } }