1

I'm trying to draw a rectangle to the screen based on mouse listeners. I'm having a few problems:

  • To start with the shape, it has an offset by a few pixels relative to the release location of the mouse.
  • Secondly I can get only the shape to display if I set the screen to visible each time after adding a JPanel component.

Could anyone tell me what I'm doing wrong or point me in the direction of some documentation? (I’ve read the Oracle documentation but I didn’t really understand it)

I know this isnt the greatest code but i just want to get it working for the moment.

This is my first time asking a question on stackoverflow so if I'm doing something wrong pls tell me.

This is my code

    public class Frame {
    private JFrame frame;

    public Frame() {
        this.frame = frameSetup("Graph");
        this.frame.addMouseListener(new Mouse());
    }

    private JFrame frameSetup(String heading) {
        JFrame f = new JFrame(heading);
        f.setBackground(Color.WHITE);
        f.setSize(800, 800);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        return f;
    }

    public void draw(int xIn, int yIn, int widthIn, int heightIn) {
        int x = xIn;
        int y = yIn;
        int width = widthIn;
        int height = heightIn;

        this.frame.add(new Panel(x, y, width, height));
        this.frame.pack();
        //this.frame.setVisible(true);
    }

    private class Mouse implements MouseListener {

        int x = 0;
        int y = 0;
        int height = 0;
        int width = 0;

        @Override
        public void mouseClicked(MouseEvent e) {

        }

        @Override
        public void mousePressed(MouseEvent e) {
            if (e.getButton() == 1) {

                x = e.getX();
                y = e.getY();

                System.out.println(x + ": " + y);
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            if (e.getButton() == 1) {

                width = (e.getX() - x);
                height = (e.getY() - y);

                System.out.println(width + ": " + height);
                draw(x - 7, y -30, width, height);
            }
        }

        @Override
        public void mouseEntered(MouseEvent e) {

        }

        @Override
        public void mouseExited(MouseEvent e) {

        }
    }

}

and

    public class Panel extends JPanel {

    private int x;
    private int y;
    private int width;
    private int height;

    public Panel(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

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

        g.setColor(Color.BLACK);
        g.fillRect(x, y, width, height);

    }
}
camickr
  • 321,443
  • 19
  • 166
  • 288
  • _I’ve read the Oracle documentation but I didn’t really understand it_ Can you post a link to the documentation that you read? – Abra Aug 31 '21 at 09:52
  • https://stackoverflow.com/questions/40945461/java-swing-draw-rectangle-in-mouse-drag-and-drop – Abra Aug 31 '21 at 10:38
  • This is the documentation I read https://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html – Aaron Vegoda Aug 31 '21 at 11:19
  • @AaronVegoda - the API only tells you about the methods of the Graphics object. It doesn't tell you how to structure your code. Read the tutorial from the first comment. It has a complete working example . Also don't call your class "Panel". There is an AWT class with that name. Your class name should be more descriptive. – camickr Aug 31 '21 at 13:25

1 Answers1

1

Welcome to the Site!
The offset is something I've had plenty of trouble with in the past aswell. It's caused by adding the MouseListener to the JFrame rather than it's contentPane. Basically, the JFrame is the thin border and the bar with the name, the icons and the buttons at the top. The content pane sits inside that, here it's the white surface. When you add the MouseListener to the JFrame, the coords are relative to this outline (the top left corner of the frame), rather than the white panel. This is fixed as follows:

// in the Frame constructor
this.frame.getContentPane().addMouseListener(new Mouse());

// in Mouse.mouseReleased(), remove the offset you added.
draw(x, y, width, height);

The Panel problem is a different story. I don't know how the code is doing what it does or how it works at all in the first place, but I can still give you some general tips.

  • Don't pack() the frame in the drawing method. It's used to calculate the window size while respecting the layout and the content of it. For me, it made the window as small as the OS allowed it to be.
  • Don't use JPanels like that! You'll run into weird problems like this, since they're made to be used in GUIs. For this reason, they're also way to heavy-weight to be used as a graphic. @user16320675 commented a tutorial on custom painting, I suggest you check that out.
  • Lastly, I suggest reworking the rectangle drawing. Right now, it only works when dragging from the top left to the bottom right.
mindoverflow
  • 364
  • 1
  • 12