Swing Canvas没有按预期绘制(或根本没有)

时间:2012-03-29 23:54:07

标签: java swing awt custom-component

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);

    }

}

为什么无法在画布上绘制Rect?代码有什么问题?

1 个答案:

答案 0 :(得分:3)

  • 不要在没有充分理由的情况下将Swing与AWT组件混合使用。
  • 在这种情况下:
    1. 扩展JComponent而不是Canvas
    2. 覆盖paintComponent(Graphics)而不是paint(Graphics)

在我格式化该代码之前,我没有注意到paint()不是覆盖,而是这个经典..

Graphics gp = canvas.getGraphics();

不要对组件这样做。使用传递给第2点中提到的方法的Graphics对象,并在被告知时进行绘制。


这个答案已被接受,但我无法抗拒审查和清理来源以制作SSCCE,以及​​增加一些调整。请参阅代码中的注释以获取更多提示。

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");
            }
        });
    }
}