/*
* Lokomo OneCMDB - An Open Source Software for Configuration
* Management of Datacenter Resources
*
* Copyright (C) 2006 Lokomo Systems AB
*
* 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.
*
* Lokomo Systems AB can be contacted via e-mail: info@lokomo.com or via
* paper mail: Lokomo Systems AB, Sv�rdv�gen 27, SE-182 33
* Danderyd, Sweden.
*
*/
package org.onecmdb.rest.graph.panels;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import org.onecmdb.core.utils.bean.CiBean;
import org.onecmdb.rest.graph.events.CEvents;
import org.onecmdb.rest.graph.events.Event;
import org.onecmdb.rest.graph.events.EventDispatcher;
import org.onecmdb.rest.graph.events.IEventListener;
import org.onecmdb.rest.graph.model.CIAttributeModel;
import org.onecmdb.rest.graph.model.CIModel;
import org.onecmdb.rest.graph.model.prefuse.TemplateModelControl;
import org.onecmdb.rest.graph.model.prefuse.TemplateRelationGraphControl;
import org.onecmdb.rest.graph.prefuse.view.GraphView;
import org.onecmdb.swing.treetable.JTreeTable;
import prefuse.Visualization;
import prefuse.data.Node;
import prefuse.data.Tuple;
import prefuse.data.event.TupleSetListener;
import prefuse.data.tuple.TupleSet;
import prefuse.util.ui.JValueSlider;
public class TemplateReferencePanel extends JPanel implements IEventListener {
private TemplateRelationGraphControl ctrl;
private GraphView gView;
private int defaultDistance = 1;
private TemplateModelControl tModel;
private CIAttributeModel referencePropertyControl;
private JTreeTable pTree;
private JTabbedPane tp;
public TemplateReferencePanel(TemplateModelControl model) {
this.tModel = model;
System.out.println("TemplateReferencePanel.constuctor(" + this.tModel + ")");
initUI();
EventDispatcher.addEventListener(this);
}
protected void initUI() {
referencePropertyControl = new CIAttributeModel();
referencePropertyControl.setAdvanced(true);
pTree = new JTreeTable(referencePropertyControl);
//pTree.setDefaultEditor(CiBean.class, referencePropertyControl.getTableCellEditor());
ctrl = new TemplateRelationGraphControl(tModel);
gView = new GraphView(ctrl.getGraph(), "alias", "type");
gView.setEnableDistanceFilter(true);
gView.setDistance(defaultDistance);
gView.getVisualization().getGroup(Visualization.FOCUS_ITEMS).addTupleSetListener(
new TupleSetListener() {
public void tupleSetChanged(TupleSet t, Tuple[] add, Tuple[] rem) {
if (add.length == 1) {
// Fire selection change...
if (add[0] instanceof Node) {
Node n = (Node)add[0];
EventDispatcher.fireEvent(this, new Event(CEvents.RELATION_ITEM_SELECTED, n.getString("alias")));
}
}
}
}
);
JPanel center = new JPanel();
center.setLayout(new BorderLayout());
//center.add(getToolBar(), BorderLayout.NORTH);
center.add(gView, BorderLayout.CENTER);
tp = new JTabbedPane();
tp.setTabPlacement(JTabbedPane.TOP);
tp.add(new JScrollPane(pTree), "Attributes");
tp.add(new JScrollPane(getControlPanel()), "Graph Control");
//tp.add(new TemplateReferencePanel(), "Reference(s)");
final JSplitPane split = new JSplitPane();
split.setTopComponent(center);
split.setBottomComponent(tp);
split.setOrientation(JSplitPane.VERTICAL_SPLIT);
split.setOneTouchExpandable(true);
setLayout(new BorderLayout());
add(split, BorderLayout.CENTER);
this.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
Dimension newDimension = e.getComponent().getSize();
split.setDividerLocation(0.8D);
}
});
}
public JComponent getControlPanel() {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBackground(Color.WHITE);
final JValueSlider slider = new JValueSlider("Max distance from selected object", 0, 10, defaultDistance);
slider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
gView.setDistance(slider.getValue().intValue());
}
});
final JCheckBox forceBounds = new JCheckBox("Keep objects within window");
forceBounds.setBackground(Color.white);
forceBounds.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
gView.setEnforceBounds(forceBounds.isSelected());
}
});
final JCheckBox animation = new JCheckBox("Dynamic Graph", true);
animation.setBackground(Color.WHITE);
animation.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
gView.animate(animation.isSelected());
}
});
panel.setAlignmentX(Component.LEFT_ALIGNMENT);
forceBounds.setAlignmentX(Component.LEFT_ALIGNMENT);
slider.setAlignmentX(Component.LEFT_ALIGNMENT);
animation.setAlignmentX(Component.LEFT_ALIGNMENT);
Box checks = new Box(BoxLayout.Y_AXIS);
checks.add(Box.createHorizontalStrut(5));
checks.add(slider);
checks.add(forceBounds);
checks.add(animation);
checks.setAlignmentY(Component.TOP_ALIGNMENT);
checks.setBorder(BorderFactory.createTitledBorder(""));
checks.setMaximumSize(new Dimension(400, 80));
panel.add(Box.createVerticalStrut(5));
panel.add(checks);
Box help = new Box(BoxLayout.Y_AXIS);
help.setBorder(BorderFactory.createTitledBorder("Graph - Help"));
StringBuffer b = new StringBuffer();
b.append("<html>");
b.append("Hold left mouse button and move mouse: Move the graph<br>");
b.append("Hold right mouse button and move mouse: Zoom in/out<br>");
b.append("Turn mouse wheel: Zoom in/out<br>");
b.append("Single-click with right mouse button: Adjust zoom so all objects fit within window<br>");
b.append("Double-click with left mouse button: Center where the cursor is and zoom in<br>");
b.append("Single-click with left mouse button on an object: Select this object<br>");
b.append("Hold left mouse button on an object and move mouse: Move this object<br>");
b.append("</html>");
JLabel label = new JLabel(b.toString());
label.setFont(new Font("Times", Font.PLAIN, 12));
help.add(label);
panel.add(help);
return(panel);
}
/*
private JToolBar getToolBar() {
JToolBar bar = new JToolBar();
final JLabel label = new JLabel("" + defaultDistance);
gView.setDistance(defaultDistance);
final JSlider slider = new JSlider(0, 30, defaultDistance);
slider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
gView.setDistance(slider.getValue());
label.setText("" + slider.getValue());
}
});
slider.setPreferredSize(new Dimension(150,30));
slider.setMaximumSize(new Dimension(150,30));
slider.setEnabled(true);
label.setPreferredSize(new Dimension(48, 30));
JPanel component = new JPanel();
component.setLayout(new BoxLayout(component, BoxLayout.X_AXIS));
component.add(label);
component.add(slider);
final JCheckBox enableDistance = new JCheckBox("Enable Distance");
enableDistance.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
gView.setEnableDistanceFilter(enableDistance.isSelected());
slider.setEnabled(enableDistance.isSelected());
}
});
enableDistance.setSelected(true);
gView.setEnableDistanceFilter(true);
bar.add(enableDistance);
bar.add(component);
return(bar);
}
*/
public void setSelectedAlias(String alias) {
gView.animate(false);
Node n = ctrl.reloadGraph(alias);
/*
VisualItem f = (VisualItem)vg.getNode(0);
if (f != null) {
m_vis.getGroup(Visualization.FOCUS_ITEMS).setTuple(n);
}
*/
gView.setFocus(n);
gView.redrawAndZoomToFit();
gView.animate(true);
}
public void onEvent(Event e) {
switch(e.getType()) {
case(CEvents.ITEM_SELECTED):
{
String alias = (String) e.getData();
setSelectedAlias(alias);
}
break;
case(CEvents.REDRAW_GRAPH):
break;
case (CEvents.RELATION_ITEM_SELECTED):
{
String alias = (String) e.getData();
CiBean bean = tModel.getBean(alias);
if (bean != null) {
tp.setTitleAt(0, "Attributes for " + bean.getAlias());
referencePropertyControl.setRoot(new CIModel(bean, bean));
TableModel tModel = pTree.getModel();
if (tModel instanceof AbstractTableModel) {
((AbstractTableModel)tModel).fireTableDataChanged();
}
}
}
break;
}
}
}