package vg.userInterface.utilPlugins;
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowStateListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Observable;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import vg.core.AMenuItem;
import vg.core.IGraphView;
import vg.core.VisualGraph;
import vg.core.event.AUIEvent;
import vg.core.event.UIEventChangeView;
import vg.core.exception.PluginException;
import vg.core.plugin.IPlugin;
import vg.core.plugin.PluginParameter;
import vg.userInterface.core.AGraphLayout;
import vg.userInterface.core.IGraphLayoutManager;
public class GraphLayoutManager implements IGraphLayoutManager, IPlugin{
private List<AGraphLayout> layouts = new ArrayList<AGraphLayout>();
private AGraphLayout defaultLayout = null;
private boolean animate = false;
private PluginParameter param;
private LayoutManagerFrame lm;
private final String CONF_STYLE_ANIMATE = "animate_layout";
private IGraphView view = null;
public void registerLayout(AGraphLayout layout) {
layouts.add(layout);
if (defaultLayout == null)
defaultLayout = layout;
}
public void setDefaultLayout(AGraphLayout layout) {
defaultLayout = layout;
}
public AGraphLayout getDefaultLayout() {
return defaultLayout;
}
public Collection<AGraphLayout> getInstalledLayouts() {
return layouts;
}
public void install(final PluginParameter param) throws PluginException {
this.param = param;
animate = Boolean.valueOf(VisualGraph.config.getProperty(CONF_STYLE_ANIMATE)).booleanValue();
lm = new LayoutManagerFrame() {
public void onOk() {
for (AGraphLayout l: GraphLayoutManager.this.layouts)
if (super.layoutList.getSelectedItem().equals(l)) {
defaultLayout = l;
break;
}
}
public void onExecute() {
executeLayout();
}
};
final JCheckBoxMenuItem animateMenuItem = new JCheckBoxMenuItem("Animate");
animateMenuItem.setState(animate);
animateMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
animate = !animate;
animateMenuItem.setState(animate);
VisualGraph.config.setProperty(CONF_STYLE_ANIMATE, new Boolean(animate).toString());
}
});
this.param.userInterface.addMenuItem(new AMenuItem(animateMenuItem) {
public void update(Observable o, Object arg) {
}
}, "Edit");
JMenuItem changeLayoutMenuItem = new JMenuItem("Change layout");
changeLayoutMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
lm.updateLayouts(GraphLayoutManager.this.getInstalledLayouts(),
GraphLayoutManager.this.defaultLayout);
lm.setVisible(true);
}
});
this.param.userInterface.addMenuItem(new AMenuItem(changeLayoutMenuItem) {
public void update(Observable o, Object arg) {
}
}, "Edit");
JMenuItem executeLayoutMenuItem = new JMenuItem("Execute layout");
executeLayoutMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
GraphLayoutManager.this.executeLayout();
}
});
executeLayoutMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, KeyEvent.ALT_DOWN_MASK));
//---------------------------------------
this.param.userInterface.addMenuItem(new AMenuItem(executeLayoutMenuItem) {
public void update(Observable o, Object arg) {
changeView(arg);
}
}, "edit");
}
public boolean isAnimated() {
return animate;
}
public void setAnimated(boolean animate) {
this.animate = animate;
}
private void changeView(Object obj) {
if(obj==null) return;
if(obj instanceof AUIEvent) {
AUIEvent event = (AUIEvent)obj;
switch(event.getType()) {
case DEF_CHANGE_VIEW:
{
UIEventChangeView bufEvent = (UIEventChangeView)event;
this.view = bufEvent.getView();
break;
}
}
}
}
private void executeLayout() {
if(this.view != null) {
view.executeLayout();
}
}
}
abstract class LayoutManagerFrame extends JFrame {
private static final long serialVersionUID = 5223945143525589924L;
private JPanel settingsPanel = new JPanel();
protected JComboBox layoutList = new JComboBox();
private JButton okButton = new JButton("Ok");
private JButton executeButton = new JButton("Execute");
private JButton cancelButton = new JButton("Cancel");
public LayoutManagerFrame() {
this.setTitle("Change layout");
this.setSize(400, 200);
this.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
this.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints(0, 0, 2, 1,
1,0, GridBagConstraints.NORTH,
GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0,0);
this.add(layoutList, gbc);
gbc = new GridBagConstraints(0, 1, 2, 1,
1,0, GridBagConstraints.CENTER,
GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0,0);
this.add(settingsPanel, gbc);
JPanel buttonsPanel = new JPanel();
buttonsPanel.setLayout(new GridBagLayout());
gbc = new GridBagConstraints(0, 0, 1, 1,
1,0, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0,0);
buttonsPanel.add(okButton, gbc);
gbc = new GridBagConstraints(1, 0, 1, 1,
1,0, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0,0);
buttonsPanel.add(executeButton, gbc);
gbc = new GridBagConstraints(2, 0, 1, 1,
1,0, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0,0);
buttonsPanel.add(cancelButton, gbc);
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
onOk();
LayoutManagerFrame.this.setVisible(false);
}
});
executeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
onOk();
onExecute();
LayoutManagerFrame.this.setVisible(false);
}
});
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
LayoutManagerFrame.this.setVisible(false);
}
});
gbc = new GridBagConstraints(0, 2, 2, 1,
1,1, GridBagConstraints.SOUTH,
GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0,0);
this.add(buttonsPanel, gbc);
settingsPanel.setLayout(new GridBagLayout());
}
public void repaint() {
super.repaint();
this.setMinimumSize(this.getPreferredSize());
this.pack();
}
public void updateLayouts(Collection<AGraphLayout> layouts, AGraphLayout selectedLayout) {
layoutList.removeAllItems();
for (AGraphLayout l: layouts) {
layoutList.addItem(l);
}
layoutList.setSelectedItem(selectedLayout);
layoutList.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (layoutList.getSelectedItem() instanceof AGraphLayout) {
updateSettingPanel((AGraphLayout) layoutList.getSelectedItem());
}
}
});
updateSettingPanel(selectedLayout);
}
private void updateSettingPanel(AGraphLayout gl) {
settingsPanel.removeAll();
final Map<String, Object> settings = gl.getSettings();
int i = 0;
for (final String s:settings.keySet()) {
GridBagConstraints gbc = new GridBagConstraints(0, i, 1, 1,
1,0, GridBagConstraints.WEST,
GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0,0);
settingsPanel.add(new JLabel(s), gbc);
gbc = new GridBagConstraints(1, i, 1, 1,
1,0, GridBagConstraints.EAST,
GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0,0);
if (settings.get(s) instanceof Boolean) {
Boolean boolValue = (Boolean) settings.get(s);
final JCheckBox checkbox = new JCheckBox();
checkbox.setSelected(boolValue);
checkbox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
settings.put(s, checkbox.isSelected());
}
});
settingsPanel.add(checkbox, gbc);
} else if (settings.get(s) instanceof Double) {
Double doubleValue = (Double) settings.get(s);
final JTextField te = new JTextField();
te.setText(doubleValue.toString());
te.getDocument().addDocumentListener(new DocumentListener() {
public void removeUpdate(DocumentEvent e) {
String str = te.getText();
if (str != null && str.length() > 0)
try {
settings.put(s, Double.parseDouble(str));
} catch (NumberFormatException e1) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
te.setText(settings.get(s).toString());
te.repaint();
}
});
}
}
public void insertUpdate(DocumentEvent e) {
String str = te.getText();
if (str != null && str.length() > 0)
try {
settings.put(s, Double.parseDouble(str));
} catch (NumberFormatException e1) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
te.setText(settings.get(s).toString());
te.repaint();
}
});
}
}
public void changedUpdate(DocumentEvent e) {
}
});
settingsPanel.add(te, gbc);
} else if (settings.get(s) instanceof Integer) {
Integer intValue = (Integer) settings.get(s);
final JFormattedTextField te = new JFormattedTextField();
te.setValue(intValue);
te.getDocument().addDocumentListener(new DocumentListener() {
public void removeUpdate(DocumentEvent e) {
String str = te.getText();
if (str != null && str.length() > 0)
try {
settings.put(s, Integer.parseInt(str));
} catch (NumberFormatException e1) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
te.setText(settings.get(s).toString());
te.repaint();
}
});
}
}
public void insertUpdate(DocumentEvent e) {
String str = te.getText();
if (str != null && str.length() > 0)
try {
settings.put(s, Integer.parseInt(str));
} catch (NumberFormatException e1) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
te.setText(settings.get(s).toString());
te.repaint();
}
});
}
}
public void changedUpdate(DocumentEvent e) {
}
});
settingsPanel.add(te, gbc);
}
i++;
}
settingsPanel.updateUI();
this.setMinimumSize(this.getPreferredSize());
this.pack();
}
public abstract void onOk();
public abstract void onExecute();
}