📄 arrow.java
字号:
/*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* Created on 2006/8/31
*
* @Author: Xiaojun Chen
* $Revision$ 1.0
*
*/
package eti.bi.alphaminer.tools.ExportCase;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import javax.swing.JComponent;
import eti.bi.alphaminer.operation.operator.Operator;
public class Arrow extends JComponent{
/**
*
*/
private static final long serialVersionUID = 8554403320642282982L;
protected static final int NORTH = 0;
protected static final int NORTHEAST = 1;
protected static final int EAST = 2;
protected static final int SOUTHEAST = 3;
protected static final int SOUTH = 4;
protected static final int SOUTHWEST = 5;
protected static final int WEST = 6;
protected static final int NORTHWEST = 7;
protected JComponent from, to;
protected int fromX, fromY, toX, toY;
protected Color color;
/* storing the appropriate length of the "arrow drawing" after computations */
protected int arrowLength;
/* the final product of the arrow drawing after matrix multiplications */
protected Shape arrow;
protected int target;
public Arrow(JComponent from, JComponent to) {
super();
this.from = from;
this.to = to;
color = Color.black;
createArrow();
}
private void createArrow() {
Rectangle f = null;
Rectangle t = null;
if (from instanceof Operator)
{
f = ((Operator)from).getIconBounds();
}
else if(from instanceof PlainOperator) {
f = ((PlainOperator)from).getIconBounds();
}
else
{
f = from.getBounds();
}
if (to instanceof Operator)
{
t = ((Operator)to).getIconBounds();
}
else if(to instanceof PlainOperator) {
t = ((PlainOperator)to).getIconBounds();
}
else
{
t = to.getBounds();
}
fromX = f.x + f.width / 2;
fromY = f.y + 17;
if ((f.x + 49) <= (t.x + 17)) {
toX = t.x;
toY = t.y + 17;
} else if ((f.x + 17) >= (t.x + 49)) {
toX = t.x + t.width;
toY = t.y + 17;
} else if (f.y >= t.y) {
toX = t.x + t.width / 2;
toY = t.y + t.height;
} else {
toX = t.x + t.width / 2;
toY = t.y + 2;
}
if (fromY == toY) {
/* west */
if (fromX > toX) {
target = WEST;
setBounds(toX, toY - 10, fromX - toX + 1, 21);
arrowLength = fromX - toX + 1;
}
/* east */
else if (fromX < toX) {
target = EAST;
setBounds(fromX, fromY - 10, toX - fromX + 1, 21);
arrowLength = toX - fromX + 1;
}
/* zero size, since "from" point is equal to "to" point. */
else {
setBounds(fromX, fromY, 0, 0);
arrowLength = 0;
}
}
/* the arrow should be in vertical direction */
else if (fromX == toX) {
/* north */
if (fromY > toY) {
target = NORTH;
setBounds(toX - 10, toY, 21, fromY - toY + 1);
arrowLength = fromY - toY + 1;
}
/* south */
else {
target = SOUTH;
setBounds(fromX - 10, fromY, 21, toY - fromY + 1);
arrowLength = toY - fromY + 1;
}
}
/* the arrow should be in diagonal direction */
else {
if (fromX < toX && fromY < toY) {
target = SOUTHEAST;
} else if (fromX < toX && fromY > toY) {
target = NORTHEAST;
} else if (fromX > toX && fromY > toY) {
target = NORTHWEST;
} else if (fromX > toX && fromY < toY) {
target = SOUTHWEST;
}
int width = Math.abs(fromX - toX) + 1;
int height = Math.abs(fromY - toY) + 1;
setBounds(
Math.min(fromX, toX),
Math.min(fromY, toY),
width,
height);
arrowLength = (int) Math.sqrt(width * width + height * height);
}
arrow = computeArrow();
Rectangle oldbound = getBounds();
setBounds(
oldbound.x - 30,
oldbound.y - 30,
oldbound.width + 60,
oldbound.height + 60);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
// recompute the arrow shape
computeArrow();
if (arrow != null) {
g.setColor(color);
// draw the arrow in the graphic object.
// since the buffer was made to be grown larger than the original one,
// therefore the shape is needed to be translated by the offset
// (Note that the original bounds, X and Y have been both minus by 30 units, so
// now the arrow drawing is moved by 30 units to cover the loss.)
// here Graphics2D is used because drawing "Shape" object on the Graphics class
// is not directly supported.
// Note that type-casting here potentially may generate problems,
// however it works for this JDK 1.2.2
((Graphics2D) g).fill(
AffineTransform.getTranslateInstance(
30,
30).createTransformedShape(
arrow));
}
}
private Shape computeArrow() {
/* read the bound of the computation area */
Rectangle bounds = getBounds();
/* get the center position of the draw area
so simply first draw an arrow pointing East,
then rotate it about the center to appropriate direction. */
int centerX = bounds.width / 2;
int centerY = bounds.height / 2;
/* make an arrow shape pointing to east first */
Polygon result = new Polygon();
result.addPoint(centerX - arrowLength / 2, centerY - 1);
result.addPoint(centerX + arrowLength / 2 - 8, centerY - 1);
result.addPoint(centerX + arrowLength / 2 - 8, centerY - 4);
result.addPoint(centerX + arrowLength / 2, centerY);
result.addPoint(centerX + arrowLength / 2 - 8, centerY + 4);
result.addPoint(centerX + arrowLength / 2 - 8, centerY + 1);
result.addPoint(centerX - arrowLength / 2, centerY + 1);
/* close the polygon */
result.addPoint(centerX - arrowLength / 2, centerY - 3);
/* if our arrow should pointing the East, otherwise do nothing. */
if (target == EAST) {
return result;
}
/* if pointing West, we rotate it by 180 degrees. */
else if (target == WEST) {
return AffineTransform
.getRotateInstance(Math.PI, centerX, centerY)
.createTransformedShape(result);
}
/* if pointing South, we rotate it by 90 degrees. */
else if (target == SOUTH) {
return AffineTransform
.getRotateInstance(Math.PI / 2, centerX, centerY)
.createTransformedShape(result);
}
/* if pointing North, we rotate it by 270 degrees. */
else if (target == NORTH) {
return AffineTransform
.getRotateInstance(Math.PI * 1.5, centerX, centerY)
.createTransformedShape(result);
}
/* for the other four direction,
we rotate it by computing the arc tangent appropriately. */
else if (target == SOUTHEAST) {
return AffineTransform
.getRotateInstance(
Math.atan(((double) bounds.height) / bounds.width),
centerX,
centerY)
.createTransformedShape(result);
} else if (target == SOUTHWEST) {
return AffineTransform
.getRotateInstance(
Math.atan(((double) bounds.width) / bounds.height)
+ Math.PI / 2,
centerX,
centerY)
.createTransformedShape(result);
} else if (target == NORTHWEST) {
return AffineTransform
.getRotateInstance(
Math.atan(((double) bounds.height) / bounds.width)
+ Math.PI,
centerX,
centerY)
.createTransformedShape(result);
} else {
return AffineTransform
.getRotateInstance(
Math.atan(((double) bounds.width) / bounds.height)
+ Math.PI * 1.5,
centerX,
centerY)
.createTransformedShape(result);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -