0

我的问题已经在java draw line as the mouse is中提到过,但是,我还没有深入到本书中,无法涵盖 JPanels、JFrames 和 Points,正如之前提出这个问题的程序员所说的那样。

回答这个问题肯定会帮助大多数初学者更好地理解图形类和绘图,这是一个通常复杂的过程,尤其是对于初学者。

根据我正在使用的文本(因为我正在自己学习 Java),这是如何使用 Java 画线的示例:

/*
 * LineTest
 * Demonstrates drawing lines
 */
import java.awt.*;
public class LineTest extends Canvas {
public LineTest() {
super();
setSize(300, 200);
setBackground(Color.white);
}
public static void main(String args[]) {
LineTest lt = new LineTest();
GUIFrame frame = new GUIFrame("Line Test");
frame.add(lt);
frame.pack();
frame.setVisible(true);
}
public void paint(Graphics g) {
g.drawLine(10, 10, 50, 100);
g.setColor(Color.blue);
g.drawLine(60, 110, 275, 50);
g.setColor(Color.red);
g.drawLine(50, 50, 300, 200);
}
}

规范是:

创建一个允许您通过单击初始点并将鼠标拖动到第二个点来绘制线条的应用程序。应重新绘制应用程序,以便在拖动鼠标时可以看到线条的大小和位置发生变化。释放鼠标按钮时,将绘制线条。

正如您将认识到的,运行此程序不会由用户创建任何图形。我相信由于第 21 行遇到此错误:g.drawLine(x, y, x2, y2);不正确,因为这是定义线条绘制的语句。

任何帮助是极大的赞赏。预先感谢您在此问题上的所有时间和合作。

我回答这个问题的代码是:

import java.awt.*;
import java.awt.event.*;

public class LineDrawer extends Canvas
                        implements MouseListener, MouseMotionListener {
int x, y, x2, y2;

public LineDrawer() {
    super();
    setSize(300, 200);
    setBackground(Color.white);
}
public void mouseClicked(MouseEvent me) {
                int x = me.getX();
                int y = me.getY();
                int x2 = me.getX();
                int y2 = me.getY();

    }
public void paint(Graphics g) {
            g.drawLine(x, y, x2, y2);
            g.setColor(Color.blue);
    }


    public void mousePressed(MouseEvent me) {
        repaint();
    }

    public void mouseDragged(MouseEvent me) {
    }
    public void mouseExited(MouseEvent me) {
    }
    public void mouseEntered(MouseEvent me) {
    }


    public void mouseReleased(MouseEvent me) {
    }
    public void mouseMoved(MouseEvent me) {
    }

    public static void main(String args[]) {
        LineDrawer ld = new LineDrawer();
        GUIFrame frame = new GUIFrame("Line Drawer");
        frame.add(ld);
        frame.pack();
        frame.setVisible(true);
    }

}

PS:我一直犹豫寻求帮助,因为我担心其他程序员会用我还没有学过的方法来回答。

4

2 回答 2

1
int x1, y1, x2, y2;

public void mousePressed(MouseEvent e){
    x1 = e.getX();
    y1 = e.getY();
}

public void mouseDragged(MouseEvent e){
    x2 = e.getX();
    y2 = e.getY();
    // Now Paint the line
    repaint();
}

希望能帮助到你。

于 2012-12-30T05:21:20.787 回答
0

让我们从

public void mouseClicked(MouseEvent me) {
    int x = me.getX();
    int y = me.getY();
    int x2 = me.getX();
    int y2 = me.getY();
}

您之前已声明x、和y,但在此方法中,您已用新的减速覆盖了这些减速,这意味着将不会使用先前声明的变量并且将忽略事件参数。x2y2

mouseClickedmousePressed在一个和事件之后触发mouseReleased,这意味着这实际上是在用户释放鼠标按钮时。

Extreme Coder 指出MouseClicked只有在同时按下和释放鼠标按钮时才会触发,即不涉及拖动 - 它仍然不是正确的使用方法,但澄清很好

你应该做的是...

mousePressed存储点击的x,y位置,mouseReleased存储x2,y2位置。

mouseDragged事件中,您应该更新x2,y2值并调用repaint

public void mousePressed(MouseEvent me) {
    // Mouse is down, but hasn't yet being released...
    x = me.getX();
    y = me.getY();
    // We need to "override" any previous values...
    x2 = x;
    y2 = y;
    repaint();
}

public void mouseDragged(MouseEvent me) {
    x2 = me.getX();
    y2 = me.getY();
    repaint();
}

public void mouseReleased(MouseEvent me) {
    // Here I would store the points so I could re-draw each new line...
}

而不是使用x, y, x2and y2,使用两个数组可能会更好,即

private int[] startPoint;
private int[] endPoint;

然后你可以做类似的事情......

public void mousePressed(MouseEvent me) {
    // Mouse is down, but hasn't yet being released...
    startPoint = new int[2];
    startPoint[0] = me.getX();
    startPoint[1] = me.getY();
    endPoint = startPoint;
    repaint();
}
public void mouseDragged(MouseEvent me) {
    endPoint = new int[2];
    endPoint[0] = me.getX();
    endPoint[1] = me.getY();
    repaint();
}

现在我更喜欢paintComponentfrom JComponent,但我现在会坚持你的例子..

public void paint(Graphics g) {
    super.paint(g); // This is super important...
    if (startPoint != null && endPoint != null && startPoint.length == 2 && endPoint.length == 2) {
        g.drawLine(startPoint[0], startPoint[1], endPoint[0], endPoint[1]);
    }
}

额外的

这有点令人担忧...

public void paint(Graphics g) {
    g.drawLine(x, y, x2, y2);
    g.setColor(Color.blue);
}

操作顺序非常重要。在您绘制线条之后设置颜色对您的绘制操作没有影响(但可能会影响您之后发生的绘制操作)。

另外,你必须打电话super.paint(g)- 这非常重要......

例子

一个“基本”示例,使用int[]数组进行点存储......

public class BasicLineDraw {

    public static void main(String[] args) {
        new BasicLineDraw();
    }

    public BasicLineDraw() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new DrawLinePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class DrawLinePane extends JPanel {

        private int[] startPoint;
        private int[] endPoint;
        private List<int[][]> lines;

        public DrawLinePane() {

            lines = new ArrayList<int[][]>(25);

            MouseAdapter handler = new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    startPoint = new int[]{e.getX(), e.getY()};
                    endPoint = startPoint;
                    repaint();
                }

                @Override
                public void mouseDragged(MouseEvent e) {
                    endPoint = new int[]{e.getX(), e.getY()};
                    repaint();
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    if (startPoint != null && endPoint != null && startPoint.length == 2 && endPoint.length == 2) {
                        lines.add(new int[][]{startPoint, endPoint});
                    }
                    startPoint = null;
                    endPoint = null;
                    repaint();
                }
            };

            addMouseListener(handler);
            addMouseMotionListener(handler);

        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D) g.create();
            if (startPoint != null && endPoint != null && startPoint.length == 2 && endPoint.length == 2) {

                g2d.setColor(Color.RED);
                g2d.drawLine(startPoint[0], startPoint[1], endPoint[0], endPoint[1]);

            }

            g2d.setColor(Color.BLUE);
            for (int[][] line : lines) {
                g2d.drawLine(line[0][0], line[0][1], line[1][0], line[1][1]);
            }

            g2d.dispose();

        }
    }
}

还有一个更高级的例子,使用PointJava 的2D Graphics API

public class LineDrawer {

    public static void main(String[] args) {
        new LineDrawer();
    }

    public LineDrawer() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new DrawLinePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class DrawLinePane extends JPanel {

        private Point anchor;
        private Point lead;

        private List<Line2D> lines;

        public DrawLinePane() {

            lines = new ArrayList<Line2D>(25);

            MouseAdapter handler = new MouseAdapter() {

                @Override
                public void mousePressed(MouseEvent e) {
                    lead = null;
                    anchor = e.getPoint();
                    repaint();
                }

                @Override
                public void mouseDragged(MouseEvent e) {
                    lead = e.getPoint();
                    repaint();
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    if (lead != null && anchor != null && !anchor.equals(lead)) {
                        lines.add(new Line2D.Float(anchor, lead));
                    }
                    repaint();
                }

            };

            addMouseListener(handler);
            addMouseMotionListener(handler);

        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); 

            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(Color.RED);
            if (lead != null && anchor != null) {

                Composite composite = g2d.getComposite();
                g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.25f));
                g2d.draw(new Line2D.Float(anchor, lead));
                g2d.setComposite(composite);

            }

            for (Line2D line : lines) {
                g2d.draw(line);
            }

            g2d.dispose();

        }

    }

}
于 2012-12-30T05:29:17.033 回答