2
public class TerrisView extends JFrame {
    public Canvas canvas;

    public TerrisView(String title) {
        super(title);
        canvas = new Canvas();
        canvas.setSize(300, 400);
        canvas.setBackground(Color.WHITE);
        // setSize(300, 400);
        this.add(canvas, BorderLayout.CENTER);
        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        paint();

    }

    public void paint() {

        // this.createBufferStrategy(2);
        // Graphics gp=getBufferStrategy().getDrawGraphics();
        // gp.setColor(Color.RED);
        // gp.fillRect(100, 100, 50, 50);
        // getBufferStrategy().show();
        Graphics gp = canvas.getGraphics();
        gp.setColor(Color.BLACK);
        gp.fillRect(0, 0, 10, 10);

    }

}

Why does it fail to draw the Rect on the canvas? What is wrong with the code?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433

1 Answers1

3
  • Don't mix Swing with AWT components without good reason.
  • In this case:
    1. Extend JComponent instead of Canvas
    2. Override paintComponent(Graphics) instead of paint(Graphics)

Before I formatted that code, I failed to notice that paint() was not an override, and this classic..

Graphics gp = canvas.getGraphics();

Don't do that with components. Use the Graphics object that is passed to the methods mentioned in point 2, and paint when told to do so.


This answer is already accepted, but I could not resist reviewing and cleaning up the source to make an SSCCE, as well as add a few more tweaks. See comments in code for further tips.

import java.awt.*;
import javax.swing.*;

public class TerrisView {

    public JComponent canvas;

    public TerrisView(String title) {
        // Don't extend frame, just use one
        JFrame f = new JFrame(title);
        canvas = new JComponent() {
            @Override // check this is a real method
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                // paint the BG - automatic for a JPanel
                g.setColor(getBackground());
                g.fillRect(0,0,getWidth(),getHeight());

                g.setColor(Color.BLACK);
                // make it dynamic, changing with the size
                int pad = 10;
                g.fillRect(pad, pad, getWidth()-(2*pad), getHeight()-(2*pad));
            }
        };
        // layout managers are more likely to respect the preferred size
        canvas.setPreferredSize(new Dimension(300, 400));
        canvas.setBackground(Color.ORANGE);
        f.add(canvas, BorderLayout.CENTER);
        f.pack();
        // nice tweak
        f.setMinimumSize(f.getSize());
        // see http://stackoverflow.com/a/7143398/418556
        f.setLocationByPlatform(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        // start/alter Swing GUIs on the EDT
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new TerrisView("Terris View");
            }
        });
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433