
org.jgraph.pad.GPExplorer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of freak-core Show documentation
Show all versions of freak-core Show documentation
Core library of the Free Evolutionary Algorithm Toolkit
package org.jgraph.pad;
import org.jgraph.event.GraphSelectionEvent;
import org.jgraph.event.GraphSelectionListener;
import org.jgraph.graph.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.*;
/**
* @author Gaudenz Alder
*
* To change this generated comment edit the template variable "typecomment":
* Window Preferences Java Templates.
* To enable and disable the creation of type comments go to
* Window Preferences Java Code Generation.
*/
public class GPExplorer extends JPanel
implements GraphSelectionListener, ChangeListener {
protected transient Object lastSelectionCell;
protected transient GPGraph graph;
protected transient JCheckBox exploreMode = new JCheckBox("Explore", true);
protected transient JCheckBox autoArrange = new JCheckBox("Arrange", true);
protected transient SpinnerNumberModel model = new SpinnerNumberModel(2, 1, 50, 1);
protected transient JSpinner levelSpinner = new JSpinner(model);
protected transient JLabel statusBar = new JLabel("Ready");
public GPExplorer(GPGraph graph) {
setLayout(new BorderLayout());
this.graph = new GPGraph(graph.getModel());
this.graph.setGraphLayoutCache(
new StatefulGraphLayoutCache(this.graph.getModel(), this.graph, false, true));
JPanel toolBar = new JPanel();
JButton showAll = new JButton("Reset");
showAll.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
reset();
}
});
toolBar.add(showAll);
toolBar.add(exploreMode);
toolBar.add(autoArrange);
toolBar.add(levelSpinner);
add(toolBar, BorderLayout.NORTH);
add(new JScrollPane(this.graph), BorderLayout.CENTER);
add(statusBar, BorderLayout.SOUTH);
this.graph.addGraphSelectionListener(this);
this.levelSpinner.addChangeListener(this);
reset();
executeLayout();
}
public void reset() {
graph.getGraphLayoutCache().setVisible(graph.getAll(), true);
graph.clearSelection();
executeLayout();
}
public void execute() {
if (exploreMode.isSelected()
&& graph.getSelectionCount() == 1
&& !graph.getModel().isEdge(
graph.getSelectionCell())) {
graph.setCursor(new Cursor(Cursor.WAIT_CURSOR));
// Hide all
GraphLayoutCache cache = graph.getGraphLayoutCache();
Object[] all =
cache.getCells(
cache.getAllDescendants(cache.getRoots()));
cache.setVisible(all, false);
int levels = model.getNumber().intValue();
Object[] cells = graph.getSelectionCells();
Set edges = new HashSet();
for (int i = 0; i < levels; i++) {
edges.addAll(
DefaultGraphModel.getEdges(
graph.getModel(),
cells));
cells =
getVerticesForEdges(graph, edges)
.toArray();
}
graph.getGraphLayoutCache().setVisible(
edges.toArray(),
true);
graph.getGraphLayoutCache().toBack(edges.toArray());
if (autoArrange.isSelected())
executeLayout();
graph.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
CellView[] views =
cache.getAllDescendants(cache.getRoots());
int edgeCount = 0, ports = 0, vertices = 0, groups = 0;
for (int i = 0; i < views.length; i++) {
if (!views[i].isLeaf())
groups++;
else if (views[i] instanceof EdgeView)
edgeCount++;
else if (views[i] instanceof PortView)
ports++;
else
vertices++;
}
cells = graph.getDescendants(graph.getRoots());
statusBar.setText(
vertices
+ " vertice(s) "
+ edgeCount
+ " edges(s) "
+ ports
+ " port(s) in "
+ groups
+ " group(s) visible out of "
+ cells.length
+ " cell(s)");
}
}
public static Set getVerticesForEdges(GPGraph graph, Set edges) {
HashSet set = new HashSet();
Iterator it = edges.iterator();
while (it.hasNext()) {
Object edge = it.next();
set.add(graph.getSourceVertex(edge));
set.add(graph.getTargetVertex(edge));
}
return set;
}
public void stateChanged(ChangeEvent e) {
execute();
}
public void valueChanged(GraphSelectionEvent e) {
//awps.resetTouchLayout();
if ((graph.getSelectionCount() == 1)
&& graph.getSelectionCell() == lastSelectionCell
&& !graph.isEditing()) {
graph.startEditingAtCell(lastSelectionCell);
} else {
execute();
}
lastSelectionCell = graph.getSelectionCell();
}
public class StatefulGraphLayoutCache extends GraphLayoutCache {
/* Boolean indicating whether new groups should be automatically shown.
* This setting has no effect in non-partial views.
*/
public static final boolean showNewGroups = false;
protected boolean askLocalAttribute = true;
protected Set localAttributes = new HashSet();
public StatefulGraphLayoutCache(GraphModel model, CellViewFactory factory,
boolean ordered, boolean partial) {
super(model, factory, ordered, partial);
localAttributes.add(GraphConstants.BOUNDS);
localAttributes.add(GraphConstants.POINTS);
localAttributes.add(GraphConstants.LABELPOSITION);
localAttributes.add(GraphConstants.ROUTING);
}
public Set getLocalAttributes() {
return new HashSet(localAttributes);
}
public void setLocalAttributes(Set attributes) {
localAttributes = attributes;
}
// Nested is in-out
protected GraphViewEdit createLocalEdit(
Map nested,
Object[] visible,
Object[] invisible) {
if ((nested != null && !nested.isEmpty()) && askLocalAttribute) {
// Move or Copy Local Attributes to Local View
Map globalMap = new Hashtable();
Map localMap = new Hashtable();
Map localAttr;
Iterator it = nested.entrySet().iterator();
while (it.hasNext()) {
localAttr = GraphConstants.createMap();
Map.Entry entry = (Map.Entry) it.next();
// (cell, Hashtable)
Object cell = entry.getKey();
Map attr = (Map) entry.getValue();
// Create Difference of Existing and New Attributes
CellView tmpView = getMapping(cell, false);
if (tmpView != null)
attr = diffMap(tmpView.getAllAttributes(), attr);
// End of Diff
Iterator it2 = attr.entrySet().iterator();
while (it2.hasNext()) {
Map.Entry entry2 = (Map.Entry) it2.next();
// (key, value)
Object key = entry2.getKey();
Object value = entry2.getValue();
if (isLocalAttribute(cell, key, value)
|| isControlAttribute(cell, key, value)) {
localAttr.put(key, value);
if (!isControlAttribute(cell, key, value))
it2.remove();
}
}
if (!localAttr.isEmpty())
localMap.put(cell, localAttr);
if (!attr.isEmpty())
globalMap.put(cell, attr);
}
nested.clear();
nested.putAll(globalMap);
GraphViewEdit edit =
new GraphViewEdit(new Hashtable(localMap), visible, invisible);
edit.end();
return edit;
}
return super.createLocalEdit(nested, visible, invisible);
}
/**
* Returns a new map that contains all (key, value)-pairs
* of newState
where either key is not used
* or value is different for key in oldState
.
* In other words, this method removes the common entries
* from oldState and newState, and returns the "difference"
* between the two.
*
* This method never returns null.
*/
public Map diffMap(Map oldState, Map newState) {
Map diff = new Hashtable();
Iterator it = newState.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
Object key = entry.getKey();
Object newValue = entry.getValue();
Object oldValue = oldState.get(key);
if (oldValue == null || !oldValue.equals(newValue))
diff.put(key, newValue);
}
return diff;
}
protected boolean isLocalAttribute(Object cell, Object key, Object value) {
return localAttributes.contains(key);
}
protected boolean isControlAttribute(
Object cell,
Object key,
Object value) {
return GraphConstants.REMOVEALL.equals(key)
|| GraphConstants.REMOVEATTRIBUTES.equals(key);
}
}
public void executeLayout() {
executeCircleLayout();
executeCircleLayout();
}
protected void executeCircleLayout() {
Dimension min = graph.getPreferredSize();
// Fetch All Views
CellView[] views = graph.getGraphLayoutCache().getRoots();
// Create list to hold vertices
List vertices = new ArrayList();
// Maximum width or height
int max = 0;
// Loop through all views
for (int i = 0; i < views.length; i++) {
// Add vertex to list
if (views[i] instanceof VertexView
&& !graph.isCellSelected(views[i].getCell())) {
vertices.add(views[i]);
// Fetch Bounds
Rectangle bounds = views[i].getBounds();
// Update Maximum
if (bounds != null)
max = Math.max(Math.max(bounds.width, bounds.height), max);
}
}
// Compute Radius
int r = (int) Math.max(vertices.size() * max / Math.PI / 2.5, 200);
int offx = Math.max(r, min.width / 2);
int offy = Math.max(r, min.height / 2);
Hashtable nested = new Hashtable();
// Compute angle step
double phi = 2 * Math.PI / vertices.size();
// Arrange vertices in a circle
for (int i = 0; i < vertices.size(); i++) {
CellView view = (CellView) vertices.get(i);
Rectangle bounds = new Rectangle(view.getBounds());
// Update Location
if (bounds != null) {
bounds.setLocation(
offx + (int) (r * Math.sin(i * phi)),
offy + (int) (r * Math.cos(i * phi)));
Map attr = GraphConstants.createMap();
GraphConstants.setBounds(attr, bounds);
nested.put(view.getCell(), attr);
}
}
// Move selected cell(s) to center
Object[] cells = graph.getSelectionCells();
for (int i = 0; i < cells.length; i++) {
if (graph.getGraphLayoutCache().isVisible(cells[i])) {
Rectangle bounds = graph.getCellBounds(cells[i]);
// Update Location
if (bounds != null) {
bounds.setLocation(offx, offy);
Map attr = GraphConstants.createMap();
GraphConstants.setBounds(attr, bounds);
nested.put(cells[i], attr);
}
}
}
graph.getGraphLayoutCache().edit(nested, null, null, null);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy