Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么';当我单击时,圆圈是否出现?_Java_Swing_Graphics_Mouseevent - Fatal编程技术网

Java 为什么';当我单击时,圆圈是否出现?

Java 为什么';当我单击时,圆圈是否出现?,java,swing,graphics,mouseevent,Java,Swing,Graphics,Mouseevent,我必须使用HoltSoft的Ready to Program中的Console类。我不应该使用swing,所以如果没有swing我做不到,请忽略这个 //imports import java.awt.*; import java.awt.event.*; import hsa.*; public class DrawLines extends Panel implements MouseListener, MouseMotionListener { Console c; i

我必须使用HoltSoft的Ready to Program中的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 ();
    }
}
我一直在尝试在控制台中使用MouseListener和MouseMotionListener。起初,程序不断给我错误,所以我添加了try/catch结构。现在它没有崩溃,但屏幕上没有显示任何内容。为什么?帮忙

如果我不应该用try/catch忽略它,我该怎么办

我不允许在这个程序中使用Console()以外的任何东西。这是一个课程作业。

看看这个:

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);
看看这个:

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

Swing是一个事件驱动系统,是一个单线程系统

这意味着您的应用程序“等待”事件发生(由事件调度线程负责),任何阻止EDT(如循环、长时间运行的进程或阻止IO)的人都会阻止您的应用程序接收这些事件的通知,从而使您的应用程序无法运行

所以,如果我们看看这个

    while (true)
    {
        mousePressed (e);
        mouseDragged (e);
        c.setColor (Color.black);
        c.fillOval (prevX, prevY, 50, 50);
        mouseReleased (e);
    }
}
这表明……第一,你不了解Swing中事件是如何生成的;第二,EDT实际上是如何工作的

与某些UI框架不同,您不需要实现事件循环,这由Swing负责。这样阻塞EDT将阻止它处理事件

取而代之的是,删除
drawLineMethod
,因为它对您毫无帮助,而将您的main方法替换为

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);
        }
    });
}
现在。我不知道
控制台
类是什么,但在鼠标事件方法中,您需要更新它,以便它可以更新其输出

用示例更新

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的整体基础知识
  • 了解如何在Swing中实际执行自定义绘制
  • 由于所有希望在Swing中执行自定义绘制的开发人员都需要了解它是如何工作的
使用纯AWT版本更新

正如有人向我指出的,OP使用AWT而不是Swing,为什么,因为他们似乎能够

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

            }
        }
    }
}

Swing是一个事件驱动系统,是一个单线程系统

这意味着您的应用程序“等待”事件发生(由事件调度线程负责),任何阻止EDT(如循环、长时间运行的进程或阻止IO)的人都会阻止您的应用程序接收这些事件的通知,从而使您的应用程序无法运行

所以,如果我们看看这个

    while (true)
    {
        mousePressed (e);
        mouseDragged (e);
        c.setColor (Color.black);
        c.fillOval (prevX, prevY, 50, 50);
        mouseReleased (e);
    }
}
这表明……第一,你不了解Swing中事件是如何生成的;第二,EDT实际上是如何工作的

与某些UI框架不同,您不需要实现事件循环,这由Swing负责。这样阻塞EDT将阻止它处理事件

取而代之的是,删除
drawLineMethod
,因为它对您毫无帮助,而将您的main方法替换为

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);
        }
    });
}
现在。我不知道
控制台
类是什么,但在鼠标事件方法中,您需要更新它,以便它可以更新其输出

用示例更新

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的整体基础知识
  • 了解如何在Swing中实际执行自定义绘制
  • 由于所有希望在Swing中执行自定义绘制的开发人员都需要了解它是如何工作的
使用纯AWT版本更新

正如有人向我指出的,OP使用AWT而不是Swing,为什么,因为他们似乎能够

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

            }
        }
    }
}

当你得到一个异常时,通常意味着出了问题。仅仅忽略它(使用空的catch语句)并不能解决根本的问题?您应该使用
JPanel
并覆盖
paintComponent
我觉得使用while循环是非常危险的。。。这个程序完成了吗?在我看来,它有很多无限期挂起的可能性,比如mouseDragged(…)为什么要在这个千年中使用AWT组件?@Andrew Thompson我不得不,学校项目。当你遇到异常时,通常意味着出了问题。仅仅忽略它(使用空的catch语句)并不能解决根本的问题?您应该使用
JPanel
并覆盖
paintComponent
我觉得使用while循环是非常危险的。。。这个程序完成了吗?在我看来,它有很多无限期悬挂的可能性,比如mouseDragged(…)为什么要在这个千年中使用AWT组件?@Andrew Thompson我必须,学校项目。我可以设置它什么?MouseEvent变量有值吗?@helpmeimdumb您根本不应该使用MouseEvent对象。从我所看到的,它看起来像一个java.awt.Point2D适合你的需要。。。那是什么意思?考虑到他们已经这样做了,这可能意味着他们不知道在构造函数中的某些地方应该这样做,这样它就不再是空的:你在开玩笑吧。@MadProgrammer很有趣,你批评我说“看这个”,然后我给他看了部分代码。你真的做了完全一样的事情:(引用你自己的答案)“那么,如果我们看一下这个…”(同一段代码)。我能把它设置成什么?