vanR
vanR

Reputation: 85

repaint() - component doesn't appear for a simple show

I'm trying to code an Othello, and... I'm already stuck with a basic view.

My main class:

public class Othello extends JFrame {
    private static final long serialVersionUID = 1L;

    public static final int WIDTH = 800;
    public static final int HEIGHT = 600;

    private Grid grid;

    public Othello() {
        this.setSize(WIDTH, HEIGHT);
        this.setTitle("Othello");

        this.grid = new Grid();

        this.setContentPane(this.grid);

        this.grid.revalidate();
        this.grid.repaint();
    }

    public void run() {
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setResizable(false);
        this.setVisible(true);
    }

    public static void main(String[] args) {
        new Othello().run();
    }
}

And my JPanel class:

public class Grid extends JPanel {
    private static final long serialVersionUID = 1L;

    public Grid() {}

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

        g.setColor(new Color(0,128,0));
        g.fillRect(0, 0, WIDTH, HEIGHT);
    }
}

I don't understand why it doesn't show anything.

The paintComponent is called, but nothing happens, I tried to call revalidate() and repaint() almost everywhere and nothing works.

I've been looking for the solution in different topics for almost 1 hour, and none of the solution I've found worked.

Upvotes: 1

Views: 60

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

This is your problem:

g.fillRect(0, 0, WIDTH, HEIGHT);

The WIDTH and HEIGHT values are not what you expect them to be, and in fact they are likely both 0. Instead for safest programming, you need to get the actual width and height via getWidth() and getHeight()

No need for those revalidate()s and repaint()s. For example:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.*;

public class GridTest {

    private static final int WIDTH = 800;
    private static final int HEIGHT = 600;

    private static void createAndShowGui() {

        Grid mainPanel = new Grid(WIDTH, HEIGHT);

        JFrame frame = new JFrame("Grid Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

class Grid extends JPanel {
    private static final long serialVersionUID = 1L;
    private int prefW;
    private int prefH;


    public Grid(int prefW, int prefH) {
        this.prefW = prefW;
        this.prefH = prefH;
    }

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

        g.setColor(new Color(0,128,0));
        g.fillRect(0, 0, getWidth(), getHeight());
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(prefW, prefH);
    }

}

Also there really is no need to override paintComponent if all you're doing is filling the background. A call to setBackground(new Color(0, 128, 0)); within the Grid constructor will set it. Of course you might need the paintComponent if you're going to draw other things -- but if it's a grid, consider using a grid of JLabels and setting their icons.

Upvotes: 3

Related Questions