4

First coord in this case should be 0,0 and not 8,30. What am i doing wrong(i am using NetBeans)

import java.awt.Color;
import java.awt.Graphics;
public class TEST extends javax.swing.JFrame {

@Override
public void paint(Graphics g){
    super.paint(g);
    g.setColor(Color.blue);
    g.drawRect(8, 30, 200, 200);
    repaint();
}}
David Kroukamp
  • 36,155
  • 13
  • 81
  • 138
VELIKI UM
  • 89
  • 1
  • 8
  • `g` is a graphic context of the frame. Now the title bar is a part of the frame too. As a result (0,0) means the top left of the frame, not the top left of the drawing area as you are expecting. – Extreme Coders Jan 06 '13 at 15:30
  • Frame's have decorations which take up space WITHIN the confines of the frame. Painting directly onto a frame is not recommended as 1. You run into this issue and 2. Frame's contain other components (content pane, menus, layer and glass panes). Check out [this](http://stackoverflow.com/questions/13734069/how-can-i-set-in-the-midst/13734319#13734319) for more information. You should use a custom component (like `JPanel`) and either add it to the content pane or replace the frame's content pane with it. – MadProgrammer Jan 06 '13 at 23:17

2 Answers2

4

Add a JPanel to the frame and paint in that. The frame's coordinates include the decorations (title bar, borders, etc.). It would look something like this:

public class Test extends JFrame {
    public static void main(String[] args) {
        new Test();
    }
    private Test() {
        add(new MyPanel());
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(600, 600);
        setVisible(true);
    }
    private class MyPanel extends JPanel {
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.blue);
            g.drawRect(8, 30, 200, 200);
        }
    }
}

Also, don't call repaint(); in paint();. That will cause an infinite loop and will freeze the entire program.

tckmn
  • 57,719
  • 27
  • 114
  • 156
  • 3
    *"`..Test extends JFrame..`"* Why extend frame? Just use an instance of one. – Andrew Thompson Jan 06 '13 at 15:46
  • 1
    +1 AndrewThompson, @DoorKnob Also always create Swing components on Event Dispatch Thread and dont call setSize rather call `pack()` on `JFrame` (and override `getPreferredSize()` of `JPanel` - see my answer for more). +1 for `paintComponent` `JPanel` and `repaint()` advice. – David Kroukamp Jan 06 '13 at 16:17
  • 1
    @AndrewThompson I was just trying to keep it as similar to the original program as possible. I usually wouldn't do this. – tckmn Jan 06 '13 at 16:18
  • @Doorknob Dont give OP code which demonstrates bad practices as he/or she might think this is the correct way of doing it and thus learns *incorrect* methods, rather correct their mistakes for the future IMO. – David Kroukamp Jan 06 '13 at 16:20
  • Thanks helped me out a lot tho i had some trouble in the beggining but fuigerd it out(i implemented this in another program) – VELIKI UM Jan 06 '13 at 16:22
3

The problem is your paint(..) method is not taking into account the JFrame Insets by calling getInsets which as docs state:

If a border has been set on this component, returns the border's insets.

this code works fine:

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Test {

    public Test() {
        createAndShowGui();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test();
            }
        });
    }

    private void createAndShowGui() {
        JFrame frame = new JFrame() {
            @Override
            public void paint(Graphics g) {
                super.paint(g);
                g.setColor(Color.blue);
                g.drawRect(0 + getInsets().left, 0 + getInsets().top, 200, 200);
            }
        };
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.pack();
        frame.setVisible(true);
    }
}

however this is not best practice.

Rather add JPanel to JFrame and override paintComponent(Graphics g) of JPanel dont forget call to super.paintComponent(g) as first call in the overridden method and than draw there (dont forget to override getPreferredSize() and return correct Dimensions so the JPanel will fit its drawing/graphic content) this problem will no longer persist as JPanel is added at correct co-ordinates on contentPane like so:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test {

    public Test() {
        createAndShowGui();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test();
            }
        });
    }

    private void createAndShowGui() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;
                g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
                g2d.setColor(Color.blue);
                g2d.drawRect(0, 0, 200, 200);
            }

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

        frame.add(panel);

        frame.pack();
        frame.setVisible(true);
    }
}

The above includes Graphics2D and RenderingHints i.e anti-aliasing. Just for some better looking drawings :)

David Kroukamp
  • 36,155
  • 13
  • 81
  • 138