0

私の質問はJava draw line as the mouse is movedでほのめかされていますが、この質問をした前のプログラマーが述べたように、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);
}
}

仕様は次のとおりです。

始点をクリックし、マウスを 2 点目にドラッグして線を描画できるアプリケーションを作成します。マウスをドラッグすると、線のサイズと位置が変化するのを確認できるように、アプリケーションを再描画する必要があります。マウス ボタンを放すと、線が描画されます。

お気づきのとおり、このプログラムを実行しても、ユーザーは描画を作成しません。このエラーは、行 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以前に 、yx2および を宣言しy2ましたが、このメソッドでは、これらの減速を新しいもので上書きしました。つまり、以前に宣言された変数は使用されず、イベント パラメータは無視されます。

mouseClickedmousePressedandmouseReleasedイベントの後に発生します。これは、実際にユーザーがマウス ボタンを離したときであることを意味します。

MouseClickedExtreme Coder は、マウス ボタンが同じポイントで押されて離されたときにのみ発生することを指摘しました。

あなたがすべきことは...

クリックの位置をmousePressed保存するとx、位置が保存されます。ymouseReleasedx2y2

イベントで、値と呼び出しmouseDraggedを更新する必要がありますx2y2repaint

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...
}

xyx2およびを使用する代わりに、y22 つの配列を使用する方がよい場合があります。

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();
}

今はpaintComponentから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 に答える