com.mxgraph.swing.handler.mxRotationHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jgraphx Show documentation
Show all versions of jgraphx Show documentation
JGraphX Swing Component - Java Graph Visualization Library
This is a binary & source redistribution of the original, unmodified JGraphX library originating from:
"https://github.com/jgraph/jgraphx/archive/v3.4.1.3.zip".
The purpose of this redistribution is to make the library available to other Maven projects.
package com.mxgraph.swing.handler;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.swing.util.mxMouseAdapter;
import com.mxgraph.util.mxConstants;
import com.mxgraph.util.mxEvent;
import com.mxgraph.util.mxEventObject;
import com.mxgraph.util.mxEventSource.mxIEventListener;
import com.mxgraph.util.mxRectangle;
import com.mxgraph.util.mxUtils;
import com.mxgraph.view.mxCellState;
/**
* Basic example of implementing a handler for rotation. This can be used as follows:
*
* new mxRotationHandler(graphComponent)
*
* Note that the Java core does actually not support rotation for the selection handles,
* perimeter points etc. Feel free to contribute a fix!
*/
public class mxRotationHandler extends mxMouseAdapter
{
/**
*
*/
public static ImageIcon ROTATE_ICON = null;
/**
* Loads the collapse and expand icons.
*/
static
{
ROTATE_ICON = new ImageIcon(
mxRotationHandler.class
.getResource("/com/mxgraph/swing/images/rotate.gif"));
}
/**
*
*/
private static double PI4 = Math.PI / 4;
/**
* Reference to the enclosing graph component.
*/
protected mxGraphComponent graphComponent;
/**
* Specifies if this handler is enabled. Default is true.
*/
protected boolean enabled = true;
/**
*
*/
protected JComponent handle;
/**
*
*/
protected mxCellState currentState;
/**
*
*/
protected double initialAngle;
/**
*
*/
protected double currentAngle;
/**
*
*/
protected Point first;
/**
* Constructs a new rotation handler.
*/
public mxRotationHandler(mxGraphComponent graphComponent)
{
this.graphComponent = graphComponent;
graphComponent.addMouseListener(this);
handle = createHandle();
// Installs the paint handler
graphComponent.addListener(mxEvent.AFTER_PAINT, new mxIEventListener()
{
public void invoke(Object sender, mxEventObject evt)
{
Graphics g = (Graphics) evt.getProperty("g");
paint(g);
}
});
// Listens to all mouse events on the rendering control
graphComponent.getGraphControl().addMouseListener(this);
graphComponent.getGraphControl().addMouseMotionListener(this);
// Needs to catch events because these are consumed
handle.addMouseListener(this);
handle.addMouseMotionListener(this);
}
/**
*
*/
public mxGraphComponent getGraphComponent()
{
return graphComponent;
}
/**
*
*/
public boolean isEnabled()
{
return enabled;
}
/**
*
*/
public void setEnabled(boolean value)
{
enabled = value;
}
/**
*
*/
protected JComponent createHandle()
{
JLabel label = new JLabel(ROTATE_ICON);
label.setSize(ROTATE_ICON.getIconWidth(), ROTATE_ICON.getIconHeight());
label.setOpaque(false);
return label;
}
/**
*
*/
public boolean isStateHandled(mxCellState state)
{
return graphComponent.getGraph().getModel().isVertex(state.getCell());
}
/**
*
*/
public void mousePressed(MouseEvent e)
{
if (currentState != null && handle.getParent() != null
&& e.getSource() == handle /* mouse hits handle */)
{
start(e);
e.consume();
}
}
/**
*
*/
public void start(MouseEvent e)
{
initialAngle = mxUtils.getDouble(currentState.getStyle(),
mxConstants.STYLE_ROTATION) * mxConstants.RAD_PER_DEG;
currentAngle = initialAngle;
first = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(),
graphComponent.getGraphControl());
if (!graphComponent.getGraph().isCellSelected(currentState.getCell()))
{
graphComponent.selectCellForEvent(currentState.getCell(), e);
}
}
/**
*
*/
public void mouseMoved(MouseEvent e)
{
if (graphComponent.isEnabled() && isEnabled())
{
if (handle.getParent() != null && e.getSource() == handle /* mouse hits handle */)
{
graphComponent.getGraphControl().setCursor(
new Cursor(Cursor.HAND_CURSOR));
e.consume();
}
else if (currentState == null
|| !currentState.getRectangle().contains(e.getPoint()))
{
mxCellState eventState = graphComponent
.getGraph()
.getView()
.getState(
graphComponent.getCellAt(e.getX(), e.getY(),
false));
mxCellState state = null;
if (eventState != null && isStateHandled(eventState))
{
state = eventState;
}
if (currentState != state)
{
currentState = state;
if (currentState == null && handle.getParent() != null)
{
handle.setVisible(false);
handle.getParent().remove(handle);
}
else if (currentState != null)
{
if (handle.getParent() == null)
{
// Adds component for rendering the handles (preview is separate)
graphComponent.getGraphControl().add(handle, 0);
handle.setVisible(true);
}
handle.setLocation(
(int) (currentState.getX()
+ currentState.getWidth()
- handle.getWidth() - 4),
(int) (currentState.getY()
+ currentState.getHeight()
- handle.getWidth() - 4));
}
}
}
}
}
/**
*
*/
public void mouseDragged(MouseEvent e)
{
if (graphComponent.isEnabled() && isEnabled() && !e.isConsumed()
&& first != null)
{
mxRectangle dirty = mxUtils.getBoundingBox(currentState,
currentAngle * mxConstants.DEG_PER_RAD);
Point pt = SwingUtilities.convertPoint(e.getComponent(),
e.getPoint(), graphComponent.getGraphControl());
double cx = currentState.getCenterX();
double cy = currentState.getCenterY();
double dx = pt.getX() - cx;
double dy = pt.getY() - cy;
double c = Math.sqrt(dx * dx + dy * dy);
currentAngle = ((pt.getX() > cx) ? -1 : 1) * Math.acos(dy / c)
+ PI4 + initialAngle;
dirty.add(mxUtils.getBoundingBox(currentState, currentAngle
* mxConstants.DEG_PER_RAD));
dirty.grow(1);
// TODO: Compute dirty rectangle and repaint
graphComponent.getGraphControl().repaint(dirty.getRectangle());
e.consume();
}
else if (handle.getParent() != null)
{
handle.getParent().remove(handle);
}
}
/**
*
*/
public void mouseReleased(MouseEvent e)
{
if (graphComponent.isEnabled() && isEnabled() && !e.isConsumed()
&& first != null)
{
double deg = 0;
Object cell = null;
if (currentState != null)
{
cell = currentState.getCell();
/*deg = mxUtils.getDouble(currentState.getStyle(),
mxConstants.STYLE_ROTATION);*/
}
deg += currentAngle * mxConstants.DEG_PER_RAD;
boolean willExecute = cell != null && first != null;
// TODO: Call reset before execute in all handlers that
// offer an execute method
reset();
if (graphComponent.isEnabled() && isEnabled() && !e.isConsumed()
&& willExecute)
{
graphComponent.getGraph().setCellStyles(
mxConstants.STYLE_ROTATION, String.valueOf(deg),
new Object[] { cell });
graphComponent.getGraphControl().repaint();
e.consume();
}
}
currentState = null;
}
/**
*
*/
public void reset()
{
if (handle.getParent() != null)
{
handle.getParent().remove(handle);
}
mxRectangle dirty = null;
if (currentState != null && first != null)
{
dirty = mxUtils.getBoundingBox(currentState, currentAngle
* mxConstants.DEG_PER_RAD);
dirty.grow(1);
}
currentState = null;
currentAngle = 0;
first = null;
if (dirty != null)
{
graphComponent.getGraphControl().repaint(dirty.getRectangle());
}
}
/**
*
*/
public void paint(Graphics g)
{
if (currentState != null && first != null)
{
Rectangle rect = currentState.getRectangle();
double deg = currentAngle * mxConstants.DEG_PER_RAD;
if (deg != 0)
{
((Graphics2D) g).rotate(Math.toRadians(deg),
currentState.getCenterX(), currentState.getCenterY());
}
mxUtils.setAntiAlias((Graphics2D) g, true, false);
g.drawRect(rect.x, rect.y, rect.width, rect.height);
}
}
}