【问题标题】:Draw Shapes by Dragging通过拖动绘制形状
【发布时间】:2023-03-22 03:35:01
【问题描述】:

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

我的输出看起来像这样。

这是我的代码:

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
}

但是如果我调用repaint() 方法,那么之前绘制的形状就会消失。

请帮帮我。

提前致谢。

【问题讨论】:

    标签: java swing graphics java-2d


    【解决方案1】:

    不要使用getGrapchic()。您需要学习自定义绘画的基础知识。见Performing Custom Painting。基本上你想要做的是覆盖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 对象添加到 List&lt;Rectangle2D&gt; rectagles,然后在画布上绘制另一个矩形。

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

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

    【讨论】:

    • 感谢您的回答。有用。请您帮我对其进行进一步的图形操作。
    • 只需在 SO 上发布另一个具体问题,展示您到目前为止所拥有的,以及您究竟需要完成什么。我去看看。
    猜你喜欢
    • 2021-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-13
    • 1970-01-01
    • 2012-10-31
    • 1970-01-01
    相关资源
    最近更新 更多