📄 paintcanvas.java
字号:
package draw;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import net.NetMessage;
import app.Application;
import app.pane.MenuPane;
import draw.figuare.*;
import svg.SVGGen;
/**
* 实际画布,最后所有实际的图形操作都有这个类来完成
*
* @author Thihy
*
*/
@SuppressWarnings("serial")
public class PaintCanvas extends JPanel implements MouseListener,
MouseMotionListener {
protected View view;
public PaintCanvas(View view) {
super(true);
strokeColor = Color.black;
fillColor = null;
this.view = view;
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
public void paintToSVG(SVGGen svg) {
int len = drawingOps.size();
Graphics g = svg.getGraphics();
for (int i = 0; i < len; i++) {
AbstractFiguare d = drawingOps.elementAt(i);
d.draw((Graphics2D) g);
}
}
@Override
public void paint(Graphics g) {
super.paint(g);
int len = drawingOps.size();
for (int i = 0; i < len; i++) {
AbstractFiguare d = drawingOps.elementAt(i);
d.draw((Graphics2D) g);
}
if (currentShape != null && currentShape.isSelect()) {
currentShape.select((Graphics2D) g);
}
if (moveOnFiguare != null)
moveOnFiguare.preSelect((Graphics2D) g);
}
/**
* 在鼠标点击的位置生成一个新的图形
*/
protected AbstractFiguare getNewShape(int x, int y) {
switch (drawingShape) {
case AbstractFiguare.STRAIGHT_LINE:
return new LineFiguare(x, y, strokeColor, fillColor);
case AbstractFiguare.RECTANGEL:
return new RectangleFiguare(x, y, strokeColor, fillColor);
case AbstractFiguare.ROUND_RECTANGEL:
return new RoundedRectangleFiguare(x, y, strokeColor, fillColor);
case AbstractFiguare.ELLIPSE:
return new EllipseFiguare(x, y, strokeColor, fillColor);
case AbstractFiguare.TEXT:
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
TextFiguare tf = new TextFiguare(x, y, strokeColor, fillColor);
updateCursor();
updateNetFiguare(NetMessage.MES_NEW_FIGUARE, tf);
return tf;
case AbstractFiguare.ARROW:
return null;
case AbstractFiguare.SELECT:
return null;
default:
if (Application.DEBUG > 0)
System.out.println("Illegal Shape-" + drawingShape);
return null;
}
}
/**
* 设置外框颜色
*/
public void setStrokeColor(Color color) {
strokeColor = color;
if (currentShape != null && currentShape.isSelect()) {
currentShape.setStrokeColor(strokeColor);
repaint();
updateNetFiguare(NetMessage.MES_CHANGE_FIGUARE);
putClientProperty(View.CANVAS_CHANGED_PROPERTY,
currentShape.serialId + ":修改线条颜色");
}
}
/**
* 设置填充颜色
*/
public void setFillColor(Color color) {
fillColor = color;
if (currentShape != null && currentShape.isSelect()) {
currentShape.setFillColor(fillColor);
repaint();
updateNetFiguare(NetMessage.MES_CHANGE_FIGUARE);
putClientProperty(View.CANVAS_CHANGED_PROPERTY,
currentShape.serialId + ":修改填充颜色");
}
}
/**
* 设置当前工具
* @param shape 要设置的工具的唯一ID
*/
public void setShape(int shape) {
if (drawingShape == shape)
return;
drawingShape = shape;
if (currentShape != null && currentShape.isSelect()) {
currentShape.setSelect(false);
repaint();
}
updateCursor();
}
/**
* 更新光标
*/
public void updateCursor() {
switch (drawingShape) {
case AbstractFiguare.ARROW:
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
break;
case AbstractFiguare.SELECT:
case AbstractFiguare.STRAIGHT_LINE:
case AbstractFiguare.RECTANGEL:
case AbstractFiguare.ROUND_RECTANGEL:
case AbstractFiguare.ELLIPSE:
setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
break;
case AbstractFiguare.TEXT:
setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
default:
break;
}
}
/**
* 获取图形数量
* @return 图形数量
*/
public int getFiguareCount() {
int count = drawingOps.size();
return count;
}
/**
* 获取在指定位置下的图形
*/
public AbstractFiguare getSelectedShape(double x, double y) {
int len = drawingOps.size();
for (int i = len - 1; i >= 0; i--) {
AbstractFiguare d = drawingOps.elementAt(i);
if (d.contains(x, y))
return d;
}
return null;
}
@Override
public void mouseClicked(MouseEvent e) {
if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0
&& e.getClickCount() > 1) {
if (currentShape != null
&& currentShape.getID() == AbstractFiguare.TEXT) {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
((TextFiguare) currentShape).editText();
repaint();
updateCursor();
}
}
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
if ((e.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0) {
if (drawingShape == AbstractFiguare.ARROW) {
int style;
if (currentShape != null)
if (currentShape.isSelect()
&& (style = currentShape.getDirectionRect(e.getX(),
e.getY())) != -1) {
setCursor(currentShape.getCursor(style));
currentShape
.willDragFromHere(style, e.getX(), e.getY());
return;
}
selectShapeInLocation(e.getX(), e.getY());
} else {
AbstractFiguare d = getNewShape(e.getX(), e.getY());
if (d == null)
return;
currentShape = d;
drawingOps.addElement(currentShape);
}
repaint();
} else if (drawingShape == AbstractFiguare.ARROW
&& (e.getModifiersEx() & InputEvent.BUTTON3_DOWN_MASK) != 0) {// 弹出右键菜单
AbstractFiguare fig;
if ((fig = getSelectedShape(e.getX(), e.getY())) != null) {
JPopupMenu popMenu = MenuPane.creatCanvasPopmenu(this, fig);
popMenu.show(this, e.getX(), e.getY());
repaint();
}
}
}
@Override
public void mouseDragged(MouseEvent e) {
if (currentShape != null) {
if (drawingShape == AbstractFiguare.ARROW) {
if (currentShape.isSelect()) {
// selectShape(currentShape);
currentShape.moveTo(e.getX(), e.getY());
}
} else {
if (currentShape != null
&& currentShape instanceof RectangularFiguare) {
if ((e.getModifiersEx() & InputEvent.SHIFT_DOWN_MASK) != 0)
((RectangularFiguare) currentShape).setSquare(true);
else
((RectangularFiguare) currentShape).setSquare(false);
}
currentShape.drawTo(e.getX(), e.getY());
}
repaint();
}
}
@Override
public void mouseReleased(MouseEvent e) {
if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
updateCursor();
// System.out.println(e);//!debug
// System.out.println(currentShape);//!debug
if (currentShape != null) {
if (drawingShape == AbstractFiguare.ARROW) {
if (currentShape.isSelect()) {
currentShape.moveTo(e.getX(), e.getY());
if (currentShape.isDragging()) {
putClientProperty(View.CANVAS_CHANGED_PROPERTY,
currentShape.serialId + ":外形改变");
} else {
putClientProperty(View.CANVAS_CHANGED_PROPERTY,
currentShape.serialId + ":移动");
}
currentShape.dragged();
// currentShape.setMovePoint(e.getX(), e.getY());
// / currentShape.setSelect(false);
// currentShape.makePermanent();
repaint();
updateNetFiguare(NetMessage.MES_CHANGE_FIGUARE);
}
} else if (currentShape != null) {
currentShape.drawTo(e.getX(), e.getY());
currentShape.makePermanent();
currentShape.setSerialId(getNetName()
+ AbstractFiguare.figuareNum);
updateNetFiguare(NetMessage.MES_NEW_FIGUARE);
putClientProperty(View.CANVAS_CHANGED_PROPERTY,
currentShape.serialId + ":新建");
currentShape = null;
}
}
}
}
/**
* 获取网络名称,由服务器指定,这在网络通信中是唯一的
*/
private String getNetName() {
return view.getNetName();
}
/**
* 向网络上的其他客户更新所有图形
*/
public void updateAllNetFiguares() {
if (view.IsConnected()) {
view
.sendMessage(new NetMessage(NetMessage.MES_CLEAR_FIGUARE,
null));// 请求删除所有图形
for (AbstractFiguare fig : drawingOps) {
if (fig != null) {
view.sendMessage(new NetMessage(NetMessage.MES_NEW_FIGUARE,
fig.clone()));
fig.hasUpdatedNet();
}
}
}
}
/**
* 向网络上的其他客户更新所有需要更新的图形
*/
public void updateAllAvailableNetFiguares() {
if (view.IsConnected()) {
view
.sendMessage(new NetMessage(NetMessage.MES_CLEAR_FIGUARE,
null));// 请求删除所有图形
for (AbstractFiguare fig : drawingOps) {
if (fig.isChanged()) {
view.sendMessage(new NetMessage(NetMessage.MES_NEW_FIGUARE,
fig.clone()));
fig.hasUpdatedNet();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -