ijustdontgetit
ijustdontgetit

Reputation: 31

Why doesn't the circle appear when I click?

I have to use the Console class in HoltSoft's Ready to Program. I'm not supposed to use swing, so if I can't do it without swing, kindly ignore this.

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

I've been trying to use MouseListener and MouseMotionListener in Console. At first, the program kept giving me errors, so I added the try/catch structures. Now it doesn't crash, but nothing appears on the screen. Why? Help?

If I shouldn't use try/catch to just ignore it, what should I do?

I'm not allowed to use anything other than Console() for this program. It's a course assignment.

Upvotes: 1

Views: 262

Answers (2)

MadProgrammer
MadProgrammer

Reputation: 347184

Swing is an event driven system and is a single threaded system.

This means that your application "waits" for events to occur (which is taken care for you by the Event Dispatching Thread) and that anyone that blocks the EDT, like, loops, long running processes or blocking IO, will prevent you application from receiving notification of those events, making impossible for you application to run.

So, if we have a look at this...

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

It suggest that...one, you don't understand how events are generated in Swing and two, how the EDT actually works.

Unlike some UI frameworks, you are not required to implement a event loop, this is taken care of you by Swing. Blocking the EDT like this, will prevent it for processing events

Instead, remove the drawLineMethod as it is doing absolute nothing for you and replace you main method with something like...

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

Now. I have no idea what the Console class is or does, but in your mouse event methods, you will need to update it so that it can update it's output...

Updated with example

enter image description here

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

            }
        }
    }
}

I would suggest that you take the time to have a read through...

Update with a pure AWT version

As it was pointed out to me that the OP was using AWT instead of Swing, why, cause they seem to be able to ...

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

            }
        }
    }
}

Upvotes: 2

Name
Name

Reputation: 2045

Look at this:

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

The parameter "e" you're passing is null. It is declared here:

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

Somewhere in your constructor you should do this so it's no longer null:

e = (something);

Upvotes: 2

Related Questions