/* * CCVisu is a tool for visual graph clustering * and general force-directed graph layout. * This file is part of CCVisu. * * Copyright (C) 2005-2012 Dirk Beyer * * CCVisu 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. * * CCVisu 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 CCVisu; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Please find the GNU Lesser General Public License in file * license_lgpl.txt or http://www.gnu.org/licenses/lgpl.txt * * Dirk Beyer (firstname.lastname@uni-passau.de) * University of Passau, Bavaria, Germany */ package org.sosy_lab.ccvisu.ui.controlpanel; import java.awt.BorderLayout; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.text.DecimalFormat; import java.util.EventObject; import javax.swing.AbstractAction; import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JFormattedTextField; import javax.swing.JPanel; import javax.swing.JSpinner; import javax.swing.JTextField; import javax.swing.KeyStroke; import org.sosy_lab.ccvisu.Options; import org.sosy_lab.ccvisu.Options.InFormat; import org.sosy_lab.ccvisu.Options.OptionsEnum; import org.sosy_lab.ccvisu.layout.MinimizerBarnesHut; import org.sosy_lab.ccvisu.layout.TwoPhaseMinimizer; import org.sosy_lab.ccvisu.readers.ReaderData; import org.sosy_lab.ccvisu.ui.StopTaskButton; import org.sosy_lab.util.interfaces.WorkerManager; @SuppressWarnings("serial") public class ToolPanelLayouter extends ControlPanel { private JCheckBox weightedCheckbox = new JCheckBox(); private JFormattedTextField gravitationTextField = new JFormattedTextField(DecimalFormat.getInstance()); private JComboBox<String> repulsionTypeTextField = new JComboBox<>(); private JFormattedTextField repulsionExponentTextField = new JFormattedTextField(); private JCheckBox animationCheckBox = new JCheckBox(); private JFormattedTextField attractionExponentTextField = new JFormattedTextField(); private JSpinner numOfIterationsSpinner = new JSpinner(); private JCheckBox autoStopIteratingCheckBox = new JCheckBox("Yes"); private JSpinner dimensionsSpinner = new JSpinner(); private JFormattedTextField scaleTextField = new JFormattedTextField(); private JButton chooseInitialLayoutButton = new JButton(); private JTextField initialLayoutTextField = new JTextField(); private JButton startMinimizerButton = new JButton("Run layouter"); private JButton randomLayoutButton = new JButton("Random layout"); private StopTaskButton stopTaskButton; private final Options options; private final WorkerManager workerManager; public ToolPanelLayouter(Options options, WorkerManager workerManager) { this.options = options; this.workerManager = workerManager; initComponents(); } @Override public void applyOptions() { options.getOption(OptionsEnum.dim).set(((Integer) dimensionsSpinner.getValue()).intValue()); options.getOption(OptionsEnum.iter).set(Integer.parseInt(this.numOfIterationsSpinner.getValue().toString())); options.getOption(OptionsEnum.autoStopIterating).set(autoStopIteratingCheckBox.isSelected()); options.getOption(OptionsEnum.initLayout).set(initialLayoutTextField.getText()); options.attrExponent = (Float) attractionExponentTextField.getValue(); options.repuExponent = (Float) repulsionExponentTextField.getValue(); options.gravitation = ((Number) gravitationTextField.getValue()).floatValue(); options.vertRepu = (repulsionTypeTextField.getSelectedIndex() == 1); options.noWeight = !weightedCheckbox.isSelected(); options.getOption(OptionsEnum.scalePos).set((Float) scaleTextField.getValue()); options.getOption(OptionsEnum.anim).set(animationCheckBox.isSelected()); } @Override public void loadOptions() { scaleTextField.setValue(new Float(options.getOption(OptionsEnum.scalePos).getFloat())); dimensionsSpinner.setValue(options.getOption(OptionsEnum.dim).getInt()); numOfIterationsSpinner.setValue(options.getOption(OptionsEnum.iter).getInt()); autoStopIteratingCheckBox.setSelected(options.getOption(OptionsEnum.autoStopIterating).getBool()); initialLayoutTextField.setText(options.getOption(OptionsEnum.initLayout).getString()); attractionExponentTextField.setValue(new Float(options.attrExponent)); gravitationTextField.setValue(new Float(options.gravitation)); repulsionExponentTextField.setValue(new Float(options.repuExponent)); weightedCheckbox.setSelected(!options.noWeight); animationCheckBox.setSelected(options.getOption(OptionsEnum.anim).getBool()); if (options.vertRepu) { repulsionTypeTextField.setSelectedIndex(1); } else { repulsionTypeTextField.setSelectedIndex(0); } } public void initComponents() { stopTaskButton = new StopTaskButton(workerManager); JPanel initLayoutPanel = new JPanel(new BorderLayout()); initLayoutPanel.add(initialLayoutTextField, BorderLayout.CENTER); initLayoutPanel.add(chooseInitialLayoutButton, BorderLayout.EAST); JPanel controlPanel = new JPanel(); controlPanel.add(randomLayoutButton); controlPanel.add(startMinimizerButton); controlPanel.add(stopTaskButton); JPanel paramsPanel = new JPanel(); paramsPanel.setLayout(new GridBagLayout()); addOptionControls(paramsPanel, "Weighted edges?", weightedCheckbox); addOptionControls(paramsPanel, "Animation during layouting?", animationCheckBox); addOptionControls(paramsPanel, "Attraction exponent:", attractionExponentTextField); addOptionControls(paramsPanel, "Repulsion exponent:", repulsionExponentTextField); addOptionControls(paramsPanel, "Repulsion type:", repulsionTypeTextField); addOptionControls(paramsPanel, "Gravitation:", gravitationTextField); addOptionControls(paramsPanel, "Initial layout:", initLayoutPanel); addOptionControls(paramsPanel, "Dimensions:", dimensionsSpinner); addOptionControls(paramsPanel, "Scale factor:", scaleTextField); addOptionControls(paramsPanel, "Number of iterations:", numOfIterationsSpinner); addOptionControls(paramsPanel, "Stop iterating on energy minimum?", autoStopIteratingCheckBox); this.setLayout(new BorderLayout()); this.add(paramsPanel, BorderLayout.CENTER); this.add(controlPanel, BorderLayout.SOUTH); animationCheckBox.setText("Yes"); repulsionTypeTextField.setModel( new DefaultComboBoxModel<String>(new String[] { "Edge repulsion", "Vertex repulsion" })); chooseInitialLayoutButton.setText("Choose..."); weightedCheckbox.setText("Yes"); setActionOnEnter(attractionExponentTextField); setActionOnEnter(repulsionExponentTextField); setActionOnEnter(gravitationTextField); setActionOnEnter(scaleTextField); setActionOnEnter(initialLayoutTextField); setActionOnEnter(dimensionsSpinner); setActionOnEnter(numOfIterationsSpinner); setMnemonics(); registerListeners(); } private void registerListeners() { startMinimizerButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { applyAndMinimize(); } }); randomLayoutButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent pE) { options.graph.setNodesToRandomPositions(options.graph.getVertices(), options.getOption(OptionsEnum.dim).getInt()); options.graph.notifyAboutLayoutChange(new EventObject(this)); } }); chooseInitialLayoutButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { JFileChooser fileDialog = new JFileChooser("."); fileDialog.setFileFilter(ReaderData.mkExtensionFileFilter(InFormat.LAY)); int outcome = fileDialog.showOpenDialog(null); if (outcome == JFileChooser.APPROVE_OPTION) { assert (fileDialog.getCurrentDirectory() != null); assert (fileDialog.getSelectedFile() != null); String fileName = fileDialog.getCurrentDirectory().toString() + File.separator + fileDialog.getSelectedFile().getName(); initialLayoutTextField.setText(fileName); } } }); } private void applyAndMinimize() { applyOptions(); MinimizerBarnesHut minimizer = new TwoPhaseMinimizer(options); workerManager.addAndRunTask(minimizer, "Minimizer"); } private void setActionOnEnter(JComponent component) { component.getInputMap().put(KeyStroke.getKeyStroke('\n'), "runMinimizer"); component.getActionMap().put("runMinimizer", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { applyAndMinimize(); } }); } private void setMnemonics() { chooseInitialLayoutButton.setMnemonic('C'); startMinimizerButton.setMnemonic('R'); stopTaskButton.setMnemonic('S'); } }