user11986012
user11986012

Reputation:

Graphics not appearing in window

I'm trying to draw a normal blue rectangle on to a JFrame, when I press play no window appears at all (with no blue rectangle)

I know that there are tutorials online showing how to draw a rectangle to a JFrame, but I would like to know the problem with the following code and why it does not work.

public class Window extends JFrame {
    public Window() {
        initialize();       
    }
    private void initialize() {
        JFrame frame = new JFrame();
            frame.setBounds(100, 100, 600, 600);
        frame.setResizable(false);
                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().setLayout(null);
            frame.getContentPane().add(new Display());

    }
    public static void main(String[]args) {

        Window window = new Window();   
    }   
}
public class Display extends JPanel {
@Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.BLUE);
        g.fillRect(0, 0, 100, 100);
    }
    public void reDraw() {
        repaint();
    }
}

Overall, I want to know the problems of the code above and how to fix it so that a blue rectangle is drawn on to a window when the program is played. Thanks for reading : )

Upvotes: 0

Views: 75

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347334

Your main issues are:

  • frame.getContentPane().setLayout(null); - This is generally a bad idea to start with. There are so many issues with this approach that it's difficult to list them all.
    • null layouts require you take full responsibility for the container's children's locations and sizes. They don't take into consideration different platform rendering systems and traits
    • You'll find it difficult to accurately size the parent window, as the available content size is the frame size MINIUS the frame borders, so while you're setting the frame to 600x600, the actual available content space is going to be smaller
    • A component's default size and position is 0x0 - so unless you're willing to take control of this (which is what layout managers do anyway), it will never be displayed (Swing's not dumb, but it is lazy ;))
  • Not calling setVisible on the JFrame
  • Not providing a sizing hint for the Display panel
  • Extending JFrame ... and not making any use of it. Extending JFrame is generally discouraged, but in your case, it's just adding unwanted noise

Work example

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

public class Test {//extends JFrame {

    public Test() {
        initialize();
    }

    private void initialize() {
        JFrame frame = new JFrame();
        //frame.setBounds(100, 100, 600, 600);
        //frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //frame.getContentPane().setLayout(null);
        frame.getContentPane().add(new Display());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        Test window = new Test();
    }

    public class Display extends JPanel {

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.BLUE);
            g.fillRect(0, 0, 100, 100);
        }

        // Not sure what benefit this provides
        //public void reDraw() {
        //    repaint();
        //}
    }
}

You might want to take a look at Laying Out Components Within a Container to get a better understanding of the layout managers and what they do and how they work (and why you should use them ;))

Upvotes: 1

Related Questions