1

HoltSoftのReadytoProgramのConsoleクラスを使用する必要があります。私はswingを使うことになっていないので、swingなしでそれができない場合は、これを無視してください。

//imports
import java.awt.*; 
import java.awt.event.*;
import hsa.*;

public class DrawLines extends Panel implements MouseListener, MouseMotionListener
{
    Console c;
    int startX, startY, prevX, prevY; //mouse coordinates
    private boolean dragging; //whether or not the mouse is being dragged
    MouseEvent e;
    public DrawLines ()
    {
        c = new Console (); //creates console window
        addMouseListener (this); //detects press/release
        addMouseMotionListener (this);//detects dragging
    }


    public void mousePressed (MouseEvent e)
    {
        while (!dragging)
        {
            try
            {
                startX = e.getX ();//get the
                startY = e.getY ();//original co-ordinates
                dragging = true;
            }
            catch (NullPointerException q) //because I kept getting this error
            {
            }
        }
    }


    public void mouseDragged (MouseEvent e)
    {
        while (dragging)
        {
            try
            {
                int x = e.getX (); //gets and
                int y = e.getY (); //updates
                prevX = x;         //the mouse
                prevY = y;         //coordinates
            }
            catch (NullPointerException q)//because I kept getting this error
            {
            }
        }
    }


    public void mouseReleased (MouseEvent e)
    {
        dragging = false; //stopped dragging
    }


    public void drawTheLine ()
    {
        mousePressed (e);
        mouseDragged (e);
        c.setColor (Color.black);
        c.fillOval (prevX, prevY, 50, 50); //draws a circle where the mouse is 
        mouseReleased (e);
    }


    public void mouseMoved (MouseEvent e){}
    public void mouseEntered (MouseEvent e){}
    public void mouseExited (MouseEvent e){}
    public void mouseClicked (MouseEvent e){}

    public static void main (String[] args)
    {
        DrawLines a = new DrawLines ();
        a.drawTheLine ();
    }
}

ConsoleでMouseListenerとMouseMotionListenerを使おうとしています。最初は、プログラムでエラーが発生し続けたので、try/catch構造を追加しました。これでクラッシュしなくなりましたが、画面には何も表示されません。なんで?ヘルプ?

try / catchを使用して無視するべきではない場合、どうすればよいですか?

このプログラムにConsole()以外のものを使用することは許可されていません。コースの課題です。

4

2 に答える 2

2

Swing はイベント ドリブン システムであり、シングル スレッド システムです。

これは、アプリケーションがイベントの発生を「待機」し (これはイベント ディスパッチ スレッドによって処理されます)、ループ、長時間実行プロセス、ブロック IO などの EDT をブロックする人は、アプリケーションが受信できないようにすることを意味します。これらのイベントの通知が行われ、アプリケーションの実行が不可能になります。

それで、これを見てみると...

    while (true)
    {
        mousePressed (e);
        mouseDragged (e);
        c.setColor (Color.black);
        c.fillOval (prevX, prevY, 50, 50);
        mouseReleased (e);
    }
}

1 つは、Swing でイベントがどのように生成されるか、2 つは EDT が実際にどのように機能するかを理解していないことです。

一部の UI フレームワークとは異なり、イベント ループを実装する必要はありません。これは Swing によって処理されます。このように EDT をブロックすると、イベントの処理が妨げられます

drawLineMethod代わりに、何もしていないのでを削除し、メインメソッドを次のようなものに置き換えます...

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception ex) {
            }

            JFrame frame = new JFrame("Test");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new BorderLayout());
            frame.add(new DrawLines());
            // I prefer pack, but you've not specified a preferred size for your panel...
            //frame.pack();
            frame.setSize(400, 400);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    });
}

今。クラスが何であるか、Consoleまたは何をするかはわかりませんが、マウスイベントメソッドでは、出力を更新できるように更新する必要があります...

例で更新

ここに画像の説明を入力

public class Test {

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

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

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

    public class DrawPane extends JPanel {

        private Point center;
        private int radius;

        public DrawPane() {
            MouseAdapter handler = new MouseAdapter() {

                @Override
                public void mousePressed(MouseEvent e) {
                    center = e.getPoint();
                    radius = 0;
                    repaint();
                }

                @Override
                public void mouseDragged(MouseEvent e) {
                    int width = Math.max(e.getX(), center.x) - Math.min(e.getX(), center.x);
                    int height = Math.max(e.getY(), center.y) - Math.min(e.getY(), center.y);
                    radius = Math.max(width, height);
                    repaint();
                }

            };
            addMouseListener(handler);
            addMouseMotionListener(handler);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (center != null) {
                g.setColor(Color.RED);
                g.fillOval(center.x - 2, center.y - 2, 4, 4);

                g.drawOval(center.x - (radius / 2), center.y - (radius / 2), radius, radius);

            }
        }
    }
}

時間をかけて一読されることをお勧めします...

  • Swing で GUI を作成して、Swingの全体的な基本を理解する
  • Swing でカスタム ペイントが実際にどのように実行されるかを理解するためのカスタム ペイントの実行
  • AWT と Swing でペイントする場合、Swing でカスタム ペイントを実行したいすべての開発者は、これがどのように機能するかを理解する必要があります...

純粋な AWT バージョンで更新する

OPがSwingの代わりにAWTを使用していると指摘されたので、なぜ、彼らはできるように見えるので...

public class DrawCircleAWT {

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

    public DrawCircleAWT() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                Frame frame = new Frame("Testing");
                frame.addWindowListener(new WindowAdapter() {
                    @Override
                    public void windowClosing(WindowEvent e) {
                        System.exit(0);
                    }
                });
                frame.setLayout(new BorderLayout());
                frame.add(new DrawPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class DrawPane extends Panel {

        private Point center;
        private int radius;

        public DrawPane() {
            MouseAdapter handler = new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    center = e.getPoint();
                    radius = 0;
                    repaint();
                }

                @Override
                public void mouseDragged(MouseEvent e) {
                    int width = Math.max(e.getX(), center.x) - Math.min(e.getX(), center.x);
                    int height = Math.max(e.getY(), center.y) - Math.min(e.getY(), center.y);
                    radius = Math.max(width, height);
                    repaint();
                }
            };
            addMouseListener(handler);
            addMouseMotionListener(handler);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        public void paint(Graphics g) {
            super.paint(g);

            if (center != null) {
                g.setColor(Color.RED);
                g.fillOval(center.x - 2, center.y - 2, 4, 4);

                g.drawOval(center.x - (radius / 2), center.y - (radius / 2), radius, radius);

            }
        }
    }
}
于 2013-01-03T21:31:38.723 に答える
2

これを見てください:

public void drawTheLine ()
{
    while (true)
    {
        mousePressed (e);
        mouseDragged (e);
        c.setColor (Color.black);
        c.fillOval (prevX, prevY, 50, 50); //draws a circle where the mouse is 
        mouseReleased (e);
    }
}

渡すパラメーター「e」は null です。ここで宣言されています:

public class DrawLines extends Panel 
    implements MouseListener, MouseMotionListener
{
    MouseEvent e; // IT IS NEVER SET TO ANYTHING! IT IS NULL!!!

コンストラクターのどこかでこれを行う必要があるため、null ではなくなります。

e = (something);
于 2013-01-03T17:19:31.467 に答える