package research.figure;
import research.*;
import research.store.StorableOutput;
import research.store.StorableInput;
import research.connector.Connector;
import research.connector.OffsetBoxConnector;
import java.awt.*;
import java.util.Vector;
import java.io.IOException;
/**
* Created by IntelliJ IDEA.
* User: guanly
* Date: 2004-6-19
* Time: 23:53:55
* To change this template use File | Settings | File Templates.
*/
public class ComponentFigure extends AbstractFigure {
protected static BasicStroke stroke = new BasicStroke(2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
public static final String CELL = "cell";
public static final String ARM = "arm";
public static final String H_CELL_NUM = "hCellNum";
public static final String W_CELL_NUM = "wCellNum";
public ComponentFigure() {
setAttribute("fillColor", new Color(153, 204, 255, 0x88));
setAttribute("anchor", new Point(0, 0));
setAttribute("offset", new Point(0, 0));
setAttribute(CELL, new Integer(30));
setAttribute(ARM, new Integer(8));
setAttribute(H_CELL_NUM, new Integer(3));
setAttribute(W_CELL_NUM, new Integer(2));
initConnectors();
}
protected void initConnectors() {
int hNum = ((Integer) getAttribute(H_CELL_NUM)).intValue();
int wNum = ((Integer) getAttribute(W_CELL_NUM)).intValue();
connector = new Connector[2 * (hNum + wNum)];
Point anchor = (Point) this.getAttribute("anchor");
int arm = ((Integer) getAttribute(ARM)).intValue();
int cell = ((Integer) getAttribute(CELL)).intValue();
int index = 0;
Point _p = new Point();
//����������ӵ�
_p.setLocation(anchor);
_p.y += arm + cell / 2;
for (int i = 0; i < hNum; i++) {
_p.y += cell;
connector[index] = new OffsetBoxConnector(this, Connector.WEST_DIRECTION, _p.x - anchor.x, _p.y - anchor.y);
index++;
}
//�����Ҳ����ӵ�
_p.setLocation(anchor);
_p.x += 2 * arm + 2 * cell + wNum * cell;
_p.y += arm + cell / 2;
for (int i = 0; i < hNum; i++) {
_p.y += cell;
connector[index] = new OffsetBoxConnector(this, Connector.EAST_DIRECTION, _p.x - anchor.x, _p.y - anchor.y);
index++;
}
//�����ϲ����ӵ�
_p.setLocation(anchor);
_p.x += arm + cell / 2;
for (int i = 0; i < wNum; i++) {
_p.x += cell;
connector[index] = new OffsetBoxConnector(this, Connector.WEST_DIRECTION, _p.x - anchor.x, _p.y - anchor.y);
index++;
}
//�����²����ӵ�
_p.setLocation(anchor);
_p.x += arm + cell / 2;
_p.y += 2 * arm + 2 * cell + hNum * cell;
for (int i = 0; i < wNum; i++) {
_p.x += cell;
connector[index] = new OffsetBoxConnector(this, Connector.WEST_DIRECTION, _p.x - anchor.x, _p.y - anchor.y);
index++;
}
}
protected void basicMoveBy(int x, int y) {
Point anchor = (Point) this.getAttribute("anchor");
anchor.x += x;
anchor.y += y;
}
public void basicDisplayBox(Point newOrigin, Point newCorner) {
Point anchor = (Point) this.getAttribute("anchor");
anchor.x = newOrigin.x;
anchor.y = newOrigin.y;
}
public Rectangle getDisplayBox() {
return getDisplayBox(null);
}
public Rectangle getDisplayBox(Rectangle r) {
if (r == null)
r = new Rectangle();
Point anchor = (Point) this.getAttribute("anchor");
Point offset = (Point) this.getAttribute("offset");
Integer cell = (Integer) getAttribute(CELL);
Integer arm = (Integer) getAttribute(ARM);
Integer hNum = (Integer) getAttribute(H_CELL_NUM);
Integer wNum = (Integer) getAttribute(W_CELL_NUM);
int height = 2 * arm.intValue() + (2 + hNum.intValue()) * cell.intValue();
int width = 2 * arm.intValue() + (2 + wNum.intValue()) * cell.intValue();
r.setBounds(anchor.x + offset.x, anchor.y + offset.y, width, height);
return r;
}
public Vector handles() {
Vector handles = new Vector();
handles.addElement(new NullHandle(this, new InerRelativeLocator(0.0, 0.0)));
handles.addElement(new NullHandle(this, new InerRelativeLocator(0.0, 1.0)));
handles.addElement(new NullHandle(this, new InerRelativeLocator(1.0, 0.0)));
handles.addElement(new NullHandle(this, new InerRelativeLocator(1.0, 1.0)));
return handles;
}
public void drawBackground(Graphics g) {
Rectangle r = getDisplayBox();
int arm = ((Integer) getAttribute(ARM)).intValue();
int cell = ((Integer) getAttribute(CELL)).intValue();
g.fillRoundRect(r.x + arm, r.y + arm, r.width - 2 * arm, r.height - 2 * arm, 2 * cell, 2 * cell);
}
protected void drawFrame(Graphics g) {
//Graphics2D g2d = (Graphics2D) g;
//Stroke oldStroke = g2d.getStroke();
//g2d.setStroke(stroke);
Rectangle r = getDisplayBox();
int arm = ((Integer) getAttribute(ARM)).intValue();
int cell = ((Integer) getAttribute(CELL)).intValue();
int hNum = ((Integer) getAttribute(H_CELL_NUM)).intValue();
int wNum = ((Integer) getAttribute(W_CELL_NUM)).intValue();
r.x += arm;
r.y += arm;
r.width -= 2 * arm;
r.height -= 2 * arm;
g.drawRoundRect(r.x, r.y, r.width, r.height, 2 * cell, 2 * cell);
g.drawLine(r.x, r.y + cell, r.x + r.width, r.y + cell);
g.drawLine(r.x, r.y + r.height - cell, r.x + r.width, r.y + r.height - cell);
g.drawLine(r.x + cell, r.y, r.x + cell, r.y + r.height);
g.drawLine(r.x + r.width - cell, r.y, r.x + r.width - cell, r.y + r.height);
//g.drawRect(r.x + cell, r.y + cell, r.width - 2 * cell, r.height - 2 * cell);
int _inset = cell * 2 / 10;
Point _point = new Point();
Rectangle _rect = new Rectangle();
Point _armP1 = new Point();
Point _armP2 = new Point();
//�����Ľӿ�
_point.x = r.x;
_point.y = r.y;
for (int i = 0; i < hNum; i++) {
_point.y += cell;
_rect.setBounds(_point.x + _inset, _point.y + _inset, cell - 2 * _inset, cell - 2 * _inset);
g.drawOval(_rect.x, _rect.y, _rect.width, _rect.height);
_armP1.setLocation(_rect.x, _rect.y + _rect.height / 2);
_armP2.setLocation(_armP1.x - _inset - arm, _armP1.y);
g.drawLine(_armP1.x, _armP1.y, _armP2.x, _armP2.y);
//g.drawRect(_armP1.x - 1, _armP1.y - 1, 2, 2);
g.drawRect(_armP2.x - 1, _armP2.y - 1, 2, 2);
}
//���Ҳ�Ľӿ�
_point.x = r.x + r.width - cell;
_point.y = r.y;
for (int i = 0; i < hNum; i++) {
_point.y += cell;
_rect.setBounds(_point.x + _inset, _point.y + _inset, cell - 2 * _inset, cell - 2 * _inset);
g.drawOval(_rect.x, _rect.y, _rect.width, _rect.height);
_armP1.setLocation(_rect.x + _rect.width, _rect.y + _rect.height / 2);
_armP2.setLocation(_armP1.x + _inset + arm, _armP1.y);
g.drawLine(_armP1.x, _armP1.y, _armP2.x, _armP2.y);
//g.drawRect(_armP1.x - 1, _armP1.y - 1, 2, 2);
g.drawRect(_armP2.x - 1, _armP2.y - 1, 2, 2);
}
//���ϲ�Ľӿ�
_point.x = r.x;
_point.y = r.y;
for (int i = 0; i < wNum; i++) {
_point.x += cell;
_rect.setBounds(_point.x + _inset, _point.y + _inset, cell - 2 * _inset, cell - 2 * _inset);
g.drawOval(_rect.x, _rect.y, _rect.width, _rect.height);
_armP1.setLocation(_rect.x + _rect.width / 2, _rect.y);
_armP2.setLocation(_armP1.x, _armP1.y - _inset - arm);
g.drawLine(_armP1.x, _armP1.y, _armP2.x, _armP2.y);
//g.drawRect(_armP1.x - 1, _armP1.y - 1, 2, 2);
g.drawRect(_armP2.x - 1, _armP2.y - 1, 2, 2);
}
//���²�Ľӿ�
_point.x = r.x;
_point.y = r.y + r.height - cell;
for (int i = 0; i < wNum; i++) {
_point.x += cell;
_rect.setBounds(_point.x + _inset, _point.y + _inset, cell - 2 * _inset, cell - 2 * _inset);
g.drawOval(_rect.x, _rect.y, _rect.width, _rect.height);
_armP1.setLocation(_rect.x + _rect.width / 2, _rect.y + _rect.height);
_armP2.setLocation(_armP1.x, _armP1.y + _inset + arm);
g.drawLine(_armP1.x, _armP1.y, _armP2.x, _armP2.y);
//g.drawRect(_armP1.x - 1, _armP1.y - 1, 2, 2);
g.drawRect(_armP2.x - 1, _armP2.y - 1, 2, 2);
}
//g2d.setStroke(oldStroke);
}
public Connector connectorAt(int x, int y) {
int cell = ((Integer) getAttribute(CELL)).intValue();
Connector[] array = getConnectors();
Connector rv = null;
for (int i = 0; i < array.length; i++) {
Rectangle _rect = array[i].getDisplayBox();
_rect.setBounds(_rect.x + _rect.width / 2 - cell / 2, _rect.y + _rect.height / 2 - cell / 2, cell, cell);
if (_rect.contains(x, y)) {
rv = array[i];
break;
}
}
return rv;
}
protected class InerRelativeLocator extends RelativeLocator {
public InerRelativeLocator(double relativeX, double relativeY) {
super(relativeX, relativeY);
}
public InerRelativeLocator() {
super();
}
public Point locate(Figure owner) {
Rectangle r = owner.getDisplayBox();
int arm = ((Integer) owner.getAttribute(ARM)).intValue();
r.x += arm;
r.y += arm;
r.width -= 2 * arm;
r.height -= 2 * arm;
return new Point(r.x + (int) (r.width * fRelativeX), r.y + (int) (r.height * fRelativeY));
}
}
}
/**
class OffsetBoxConnector extends AbstractConnector {
protected int direction;
protected int offsetX;
protected int offsetY;
public OffsetBoxConnector() {
super();
}
public OffsetBoxConnector(ComponentFigure owner, int direction, int offsetX, int offsetY) {
super(owner);
this.direction = direction;
this.offsetX = offsetX;
this.offsetY = offsetY;
}
public void setDirection(int direction) {
this.direction = direction;
}
public int getDirection() {
return direction;
}
public void moveBy(int dx, int dy) {
offsetX += dx;
offsetY += dy;
}
public Rectangle getDisplayBox() {
Point anchor = (Point) owner().getAttribute("anchor");
Point _p = new Point(anchor);
_p.translate(offsetX, offsetY);
return new Rectangle(_p.x - SIZE / 2, _p.y - SIZE / 2, SIZE, SIZE);
}
public boolean containsPoint(int x, int y) {
return getDisplayBox().contains(x, y);
}
public void write(StorableOutput dw) {
super.write(dw);
dw.writeInt(direction);
dw.writeInt(offsetX);
dw.writeInt(offsetY);
}
public void read(StorableInput dr) throws IOException {
super.read(dr);
direction = dr.readInt();
offsetX = dr.readInt();
offsetY = dr.readInt();
}
}
**/