0

If I create a JFrame 800x600 pixels and draw a line from (0,0) to (800,600) it doesn't go from corner to corner, so, where is the (0,0) and where is the (800,600)? Here is the code

import java.awt.Graphics;

import javax.swing.JFrame;

public class Point0_0test extends JFrame {

    public Point0_0test() {
        setTitle("Test");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(800, 600);
        setLocationRelativeTo(null);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.drawLine(0, 0, 800, 600);
    }

    public static void main(String[] args) {
        Point0_0test test = new Point0_0test();
        test.setVisible(true);
    }

}

Here you can see what appears when the program is running

plr108
  • 1,201
  • 11
  • 16
Nemo_64
  • 15
  • 1
  • 5

3 Answers3

1

If you want a drawing area that's 800 x 600 pixels, then set a drawing area that's 800 x 600 pixels. Who cares how big the frame is?

Here's a simple drawing GUI that I created. I made it 400 x 300 pixels so it would fit in the answer easier.

Simple Drawing Panel

Here's the code. It's a minimal, runnable example for setting the size of the drawing area.

import java.awt.BasicStroke;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class SimpleDrawingArea implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new SimpleDrawingArea());
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Simple Drawing Panel");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new DrawingPanel());
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public class DrawingPanel extends JPanel {

        private static final long serialVersionUID = 1L;

        public DrawingPanel() {
            this.setPreferredSize(new Dimension(400, 300));
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setStroke(new BasicStroke(4f));
            g2d.drawLine(0, 0, 400, 300);
        }

    }

}
Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
0

The JFrame size and coordinates count the size of the decorations, such as the top part of the window contains the bar with the close button, the rest contain the extra outline that is added on Windows(Ubuntu, at least, doesn't seem to add an extra outline). In order to get a line like you would want to, you should use JFrame.getInsets(), which returns the size of the GUI that decorates the JFrame, like this:


    import java.awt.Insets;

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Insets in = getInsets();
        g.drawLine(in.left, in.top, 800-in.right, 600-in.bottom);
    }

Edit: this means that you don't have an actual 800x600 space. The Insets class seems to be "created" when setVisible(true) is called, as far as I can tell. So this would be how the code for that looks like:


import javax.swing.JFrame;
import java.awt.Insets;
import java.awt.Graphics;

public class InsetsTest extends JFrame {

    public InsetsTest() {
        super();
        setTitle("Test");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(800,600);
        setVisible(true);
        Insets insets= getInsets();
        setSize(800+insets.right+insets.left,600+insets.top+insets.bottom);

        setLocationRelativeTo(null);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Insets in = getInsets();
        g.drawLine(in.left, in.top, 800+in.left, 600+in.top);
    }

    public static void main(String[] args) {
        InsetsTest test = new InsetsTest();
        test.setVisible(true);
    }

}```
JunisvaultCo
  • 151
  • 7
  • Oh thanks! But now I'm currious So I have used `System.out.println("(" + insets.left + "," + insets.top + ")"); System.out.println("(" + insets.right + "," + insets.bottom + ")");` And I got (8,31) (8,8) Why don't I get (8,31) (800,600) if it is bottom right? – Nemo_64 Apr 07 '20 at 18:43
  • Insets returns more like the size of the decorations themselves, rather than the coordinates. I have now edited my answer with a slightly better explanation. – JunisvaultCo Apr 07 '20 at 18:52
  • Wait. This means that the space that I have to draw is not 800 x 600 is 800-insets.right-insets.left x 600-insets.top-insets.bottom. How can I get the real space for the 800x600. Do I use `setSize(800+insets.right+insets.left,600+insets.top+insets.bottom)` or the inset is created when the size is declarated? – Nemo_64 Apr 07 '20 at 19:07
  • The inset seems to be created when setVisible(true) is called... as far as I can tell. – JunisvaultCo Apr 07 '20 at 19:19
  • Did a quick test and it seems that, as you said, is created after the `setVisible(true)` – Nemo_64 Apr 07 '20 at 19:25
0

The window size should be defined without OS specific window decoration.

Try to add

this.setUndecorated(true);

before the

this.setVisible(true);
Yan.F
  • 630
  • 5
  • 20
  • That also works but I don't get the top bar for closing and minimizing and I think that's quite an usefull bar. But thanks for the help, I really apreciate it! – Nemo_64 Apr 07 '20 at 18:45