Java 通过拖动绘制形状

Java 通过拖动绘制形状,java,swing,graphics,java-2d,Java,Swing,Graphics,Java 2d,我是图形编程的新手。我想通过拖动鼠标绘制多个形状,如直线、矩形和椭圆形。我试图完成这项任务,但失败了 我的输出如下所示。 这是我的密码: public class JavaDraw extends JPanel implements ActionListener, MouseMotionListener, MouseListener { private JButton btnLine, btnRect, btnEclipse, btnPointer; private DrawShap

我是图形编程的新手。我想通过拖动鼠标绘制多个形状,如直线、矩形和椭圆形。我试图完成这项任务,但失败了

我的输出如下所示。

这是我的密码:

public class JavaDraw extends JPanel implements ActionListener,
    MouseMotionListener, MouseListener {

private JButton btnLine, btnRect, btnEclipse, btnPointer;
private DrawShape drawShape;
private Vector<Line2D.Double> vecLine;
private Vector<Rectangle2D.Double> vecRectangle;
private Vector<Ellipse2D.Double> vecEllipse;
private int left, right, top, bottom;
private Point startPoint, endPoint;

public JavaDraw(int width, int height) {
    this();
    setSize(width, height);
    setBackground(Color.orange);
}

public JavaDraw() {

    setLayout(new FlowLayout(FlowLayout.CENTER));

    createControl();
    addControl();
    addListners();
}

private void createControl() {
    btnEclipse = new JButton("Eclipse");
    btnLine = new JButton("Line");
    btnRect = new JButton("Rectangle");
    btnPointer = new JButton("Pointer");

    vecEllipse = new Vector<>();
    vecLine = new Vector<>();
    vecRectangle = new Vector<>();

    startPoint = new Point();
    endPoint = new Point();
}

private void addControl() {

    add(btnLine);
    add(btnRect);
    add(btnEclipse);
    add(btnPointer);
}

private void addListners() {
    addActionListenerToControl();
    addMouseListenerToControl();
    addMouseMotionListenerToControl();
}

private void addActionListenerToControl() {
    btnEclipse.addActionListener(this);
    btnLine.addActionListener(this);
    btnPointer.addActionListener(this);
    btnRect.addActionListener(this);
}

private void addMouseListenerToControl() {
    addMouseListener(this);
}

private void addMouseMotionListenerToControl() {
    addMouseMotionListener(this);
}

private void resizeShape(int x, int y) {
    endPoint.x = x;
    endPoint.y = y;
    updateBounds(startPoint, endPoint);
}

private void drawShape(Graphics g, boolean xor, DrawShape dm) {

    if (drawShape == DrawShape.DRAW_RECT)
        g.drawRect(left, top, Math.abs(left - right),
                Math.abs(top - bottom));
    else if (drawShape == DrawShape.DRAW_ELLIPSE)
        g.drawOval(left, top, Math.abs(left - right),
                Math.abs(top - bottom));
    else if (drawShape == DrawShape.DRAW_LINE)
        g.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y);
}

void updateBounds(Point pt1, Point pt2) {
    left = (pt1.x < pt2.x) ? pt1.x : pt2.x;
    right = (pt1.x > pt2.x) ? pt1.x : pt2.x;
    top = (pt1.y < pt2.y) ? pt1.y : pt2.y;
    bottom = (pt1.y > pt2.y) ? pt1.y : pt2.y;
}

@Override
public void actionPerformed(ActionEvent e) {
    Graphics g = getGraphics();
    g.setColor(Color.black);
    g.setXORMode(getBackground());

    if (e.getSource() == btnEclipse) {
        drawShape = DrawShape.DRAW_ELLIPSE;
    } else if (e.getSource() == btnLine) {
        drawShape = DrawShape.DRAW_LINE;
    } else if (e.getSource() == btnRect) {
        drawShape = DrawShape.DRAW_RECT;
    } 
    g.setPaintMode();
}

@Override
public void mouseDragged(MouseEvent e) {
    Graphics g = getGraphics();
    g.setColor(Color.black);
    g.setXORMode(getBackground());

    resizeShape(e.getX(), e.getY());
    drawShape(g, true, drawShape);

}

@Override
public void mouseMoved(MouseEvent e) {
}

@Override
public void mouseClicked(MouseEvent e) {
}

@Override
public void mouseEntered(MouseEvent e) {
}

@Override
public void mouseExited(MouseEvent e) {
}

@Override
public void mousePressed(MouseEvent e) {
    startPoint = e.getPoint();
}

@Override
public void mouseReleased(MouseEvent e) {
}

}

enum DrawShape {
    DRAW_LINE, DRAW_RECT, DRAW_ELLIPSE
}
公共类JavaDraw扩展了JPanel实现ActionListener,
MouseMotionListener,MouseListener{
专用按钮btnLine、btnRect、btnEclipse、btnPointer;
私人DrawShape DrawShape;
专用矢量线;
私有向量向量机;
私有向量向量机;
私有int左、右、上、下;
专用点起点、终点;
公共JavaDraw(整数宽度、整数高度){
这个();
设置尺寸(宽度、高度);
挫折背景(橙色);
}
公共JavaDraw(){
setLayout(新的FlowLayout(FlowLayout.CENTER));
createControl();
addControl();
addListners();
}
私有void createControl(){
btnEclipse=newjbutton(“Eclipse”);
btnLine=新的JButton(“行”);
btnRect=新的JButton(“矩形”);
btnPointer=新的JButton(“指针”);
向量椭圆=新向量();
vecLine=新向量();
vecRectangle=新向量();
起始点=新点();
端点=新点();
}
私有void addControl(){
添加(btnLine);
添加(btnRect);
添加(btnEclipse);
添加(btnPointer);
}
私有void addListners(){
addActionListenerToControl();
addMouseListenerToControl();
addMouseMotionListenerToControl();
}
私有void addActionListenerToControl(){
btnEclipse.addActionListener(此);
btnLine.addActionListener(此);
btnPointer.addActionListener(此);
btnRect.addActionListener(此);
}
私有void addMouseListenerToControl(){
addMouseListener(这个);
}
私有void addMouseMotionListenerToControl(){
addMouseMotionListener(此);
}
私有空心大小调整形状(整数x,整数y){
终点x=x;
终点y=y;
updateBounds(起点、终点);
}
私有void drawShape(图形g、布尔异或、drawShape dm){
if(drawShape==drawShape.DRAW\u RECT)
g、 drawRect(左、上、Math.abs(左-右),
abs(上下));
else if(drawShape==drawShape.DRAW_椭圆)
g、 drawOval(左、上、数学abs(左-右),
abs(上下));
else if(drawShape==drawShape.DRAW_线)
g、 绘制线(起点.x,起点.y,终点.x,终点.y);
}
无效更新绑定(点pt1、点pt2){
左=(pt1.xpt2.x)?pt1.x:pt2.x;
top=(pt1.ypt2.y)?pt1.y:pt2.y;
}
@凌驾
已执行的公共无效操作(操作事件e){
Graphics g=getGraphics();
g、 设置颜色(颜色为黑色);
g、 setXORMode(getBackground());
如果(如getSource()==btnEclipse){
drawShape=drawShape.DRAW_椭圆;
}else if(例如getSource()==btnLine){
drawShape=drawShape.DRAW_线;
}else if(e.getSource()==btnRect){
drawShape=drawShape.DRAW\u RECT;
} 
g、 setPaintMode();
}
@凌驾
公共无效鼠标标记(鼠标事件e){
Graphics g=getGraphics();
g、 设置颜色(颜色为黑色);
g、 setXORMode(getBackground());
调整形状大小(e.getX(),e.getY());
drawShape(g,真,drawShape);
}
@凌驾
public void mouseMoved(MouseEvent e){
}
@凌驾
公共无效mouseClicked(MouseEvent e){
}
@凌驾
公共无效鼠标事件(鼠标事件e){
}
@凌驾
公共无效mouseExited(MouseEvent e){
}
@凌驾
公共无效鼠标按下(MouseEvent e){
startPoint=e.getPoint();
}
@凌驾
公共无效MouseEvent(MouseEvent e){
}
}
枚举绘图形状{
画直线,画直线,画椭圆
}
但如果我调用
repaint()
方法,那么以前绘制的图形就会消失

请帮帮我


提前感谢。

不要使用
getgraphic()
。你需要学习定制绘画的基础知识。看见基本上,您要做的是覆盖
paintComponent
并在那里进行绘制

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D)g;
    // draw here.
}
每当您
repaint()
面板时,都会隐式调用
paintComponent
。所以你可以做一些像

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D)g;
    for (Rectangle2D rect: rectangles) {
        g2.fill(rect);
    }
}
例如,您可以将一个新的
Rectangle2D
对象添加到
列表rectages
,画布上将绘制另一个矩形

您可能还想查看,其中显示了如何通过拖动鼠标来创建形状


本例中的代码仅使用一个矩形,但您可以轻松修改它以绘制一个矩形列表。每次按下鼠标时,它都会向列表中添加一个新的矩形,同时仍然允许您拖动鼠标来调整从鼠标按下获得的当前矩形的大小。检查链接。希望有帮助。

谢谢你的回答。它起作用了。请你能帮我对它进行进一步的图形操作吗?只需在上面发布另一个具体问题,说明你到目前为止有什么,以及你到底需要完成什么。我来看看。