为什么paint()方法不执行update()或paint()方法?

发布于 2024-10-01 01:26:38 字数 4094 浏览 7 评论 0原文

我遇到这个问题,当我执行 repaint() 时,类中的 paint()update() 方法没有被调用>。代码如下:

public class BufferedDisplay extends Canvas implements Runnable {

// Contains all the images in order, ordered from background to foreground
private ArrayList<ImageStruct> images;
// Tracks the last insert ID of the last image for a particular layer
private TreeMap<Integer, Integer> insertIDs;
// Image that holds the buffered Image
private Image offscreen;

public BufferedDisplay() {
    images = new ArrayList<ImageStruct>();
    insertIDs = new TreeMap<Integer, Integer>();
}

public void addImageStruct(ImageStruct is) {
    int layer = is.getLayer();
    // Index to insert the image at
    int index = -1;
    if(insertIDs.containsKey(layer)) {
        index = insertIDs.get(layer)+1;
        insertIDs.put(layer, index);
    }
    else {
        index = images.size();
        insertIDs.put(layer, index);
    }
    if(index>-1) {
        images.add(index, is);
    }
}

public void run() {
    try
    {
        while(true)
        {
            System.out.print("\nSleeping... ");
            System.out.print("ArraySize:"+images.size()+" ");
            Thread.sleep(1000);
            System.out.print("Slept. ");
            repaint();
        }
    }
    catch(Exception e)
    {
        System.out.println("Display Error: ");
        e.printStackTrace();
        System.exit(-1);
    }
}

// Overrides method so the background isn't automatically cleared
public void update( Graphics g )
{
    System.out.print("Updating... ");
    paint(g);
}

public void paint( Graphics g )
{
    System.out.print("Painting... ");
    if(offscreen == null)
        offscreen = createImage(getSize().width, getSize().height);
    Graphics buffer = offscreen.getGraphics();
    buffer.setClip(0,0,getSize().width, getSize().height);
    g.setColor(Color.white);
    paintImages(buffer);
    g.drawImage(offscreen, 0, 0, null);
    buffer.dispose();
}

public void paintImages( Graphics window )
{
    for(ImageStruct i : images) {
        i.draw(window);
    }
}
}

该类的实现如下:

public class Game extends JPanel{
// A reference to the C4Game class
private C4Game game;
// A reference to the BufferedDisplay class
private BufferedDisplay display;
// The Image used to initialize the game board
private Image tile;
private int tileSize = 75;
private int tileLayer = 5;
// Thread that controls animation for the BufferedDisplay
Thread animation;

public Game(C4Game game) {
    this.game = game;
    display = new BufferedDisplay();
    try {
        tile = ImageIO.read(new File("img\\tile.png"));
    } catch (IOException e) {
        System.out.println("ERROR: ");
        e.printStackTrace();
    }
    ((Component)display).setFocusable(true);
    add(display);
    animation = new Thread(display);
    animation.start();
    initBoard();
}

public void initBoard() {
    for(int x = 0; x<game.numRows()*tileSize; x+=tileSize) {
        for(int y = 0; y<game.numCols()*tileSize; y+=tileSize)  {
            System.out.println("Placing " +x +" " +y +"...");
            display.addImageStruct(new ImageStruct(tile, tileLayer, x, y, tileSize, tileSize));
        }
    }
}
}

...然后在 JFrame 中实现。

public class TetraConnect extends JFrame{

    public TetraConnect() {
    super("TetraConnect", 800, 600);
    try {
        setIconImage(Toolkit.getDefaultToolkit().createImage("img/icon.png"));
        ms = new MainScreen(this);
        add(ms);
        ms.updateUI();
        C4Game c4g = new C4Game(5,6);
        Game g = new Game(c4g);
        add(g);
        g.updateUI();
    }
    catch(Exception e) {
        System.out.println("Init. Error: ");
        e.printStackTrace();
        System.exit(-1);
    }
}

我运行它时的输出是:

Slept.
Sleeping... Slept.
Sleeping... Slept.
Sleeping... Slept.

等等。我也无法在画布上看到任何图像(我假设它们从来没有被绘制过)。看起来完全跳过了repaint方法;调试语句“正在更新...”和“重新绘制...”永远不会出现。然而,重绘似乎也在执行;循环重复没有问题。为什么 repaint 方法不调用 Paint() 或 update() 方法?

I'm having this problem where the paint() or update() methods in a class isn't getting called when I execute repaint(). Here's the code:

public class BufferedDisplay extends Canvas implements Runnable {

// Contains all the images in order, ordered from background to foreground
private ArrayList<ImageStruct> images;
// Tracks the last insert ID of the last image for a particular layer
private TreeMap<Integer, Integer> insertIDs;
// Image that holds the buffered Image
private Image offscreen;

public BufferedDisplay() {
    images = new ArrayList<ImageStruct>();
    insertIDs = new TreeMap<Integer, Integer>();
}

public void addImageStruct(ImageStruct is) {
    int layer = is.getLayer();
    // Index to insert the image at
    int index = -1;
    if(insertIDs.containsKey(layer)) {
        index = insertIDs.get(layer)+1;
        insertIDs.put(layer, index);
    }
    else {
        index = images.size();
        insertIDs.put(layer, index);
    }
    if(index>-1) {
        images.add(index, is);
    }
}

public void run() {
    try
    {
        while(true)
        {
            System.out.print("\nSleeping... ");
            System.out.print("ArraySize:"+images.size()+" ");
            Thread.sleep(1000);
            System.out.print("Slept. ");
            repaint();
        }
    }
    catch(Exception e)
    {
        System.out.println("Display Error: ");
        e.printStackTrace();
        System.exit(-1);
    }
}

// Overrides method so the background isn't automatically cleared
public void update( Graphics g )
{
    System.out.print("Updating... ");
    paint(g);
}

public void paint( Graphics g )
{
    System.out.print("Painting... ");
    if(offscreen == null)
        offscreen = createImage(getSize().width, getSize().height);
    Graphics buffer = offscreen.getGraphics();
    buffer.setClip(0,0,getSize().width, getSize().height);
    g.setColor(Color.white);
    paintImages(buffer);
    g.drawImage(offscreen, 0, 0, null);
    buffer.dispose();
}

public void paintImages( Graphics window )
{
    for(ImageStruct i : images) {
        i.draw(window);
    }
}
}

This class is implemented in this:

public class Game extends JPanel{
// A reference to the C4Game class
private C4Game game;
// A reference to the BufferedDisplay class
private BufferedDisplay display;
// The Image used to initialize the game board
private Image tile;
private int tileSize = 75;
private int tileLayer = 5;
// Thread that controls animation for the BufferedDisplay
Thread animation;

public Game(C4Game game) {
    this.game = game;
    display = new BufferedDisplay();
    try {
        tile = ImageIO.read(new File("img\\tile.png"));
    } catch (IOException e) {
        System.out.println("ERROR: ");
        e.printStackTrace();
    }
    ((Component)display).setFocusable(true);
    add(display);
    animation = new Thread(display);
    animation.start();
    initBoard();
}

public void initBoard() {
    for(int x = 0; x<game.numRows()*tileSize; x+=tileSize) {
        for(int y = 0; y<game.numCols()*tileSize; y+=tileSize)  {
            System.out.println("Placing " +x +" " +y +"...");
            display.addImageStruct(new ImageStruct(tile, tileLayer, x, y, tileSize, tileSize));
        }
    }
}
}

...Which is then implemented in a JFrame.

public class TetraConnect extends JFrame{

    public TetraConnect() {
    super("TetraConnect", 800, 600);
    try {
        setIconImage(Toolkit.getDefaultToolkit().createImage("img/icon.png"));
        ms = new MainScreen(this);
        add(ms);
        ms.updateUI();
        C4Game c4g = new C4Game(5,6);
        Game g = new Game(c4g);
        add(g);
        g.updateUI();
    }
    catch(Exception e) {
        System.out.println("Init. Error: ");
        e.printStackTrace();
        System.exit(-1);
    }
}

The output when I run it, is:

Slept.
Sleeping... Slept.
Sleeping... Slept.
Sleeping... Slept.

And so forth. I'm also not able to see any images on the Canvas (I'm assuming they are never drawn in the first place). It seems to completely skip the repaint method; the debug statements "Updating... " and "Repainting... " never show up. However, repaint also seems to be executing; the loop repeats without problems. Why isn't the repaint method calling the paint() or update() methods?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

等往事风中吹 2024-10-08 01:26:38

正如 @camickr 在评论中指出的,您正在使用重量级 AWT 画布。您确实应该使用轻量级 Swing 组件。而不是:

public class BufferedDisplay extends Canvas implements Runnable {

我建议:

 public class BufferedDisplay extends JPanel implements Runnable {

考虑到这个小变化,我会执行以下操作:

当覆盖组件的默认绘画时,您应该覆盖paintComponent()方法。

因此,而不是:

public void paint( Graphics g )
{

应该是:

protected void paintComponent( Graphics g )
{

这可能会解决您的问题。

另外,您不必重写 update() 方法。相反,只需在绘制组件方法中省略对 super.paintCompenent(g) 的调用即可。这应该会导致背景默认保持不变。

As @camickr noted in the comments, you are using the heavyweight AWT canvas. You should really be using lightweight Swing components. Instead of:

public class BufferedDisplay extends Canvas implements Runnable {

I recommend:

 public class BufferedDisplay extends JPanel implements Runnable {

Given that small change, I would then do the following:

When overriding the default paining of a component you should override the paintComponent() method.

So, instead of:

public void paint( Graphics g )
{

It should be:

protected void paintComponent( Graphics g )
{

That may fix your problem.

Also, you shouldn't have to override the update() method. Instead, just leave out a call to super.paintCompenent(g) in the paint component method. This should cause the background to be left alone by default.

家住魔仙堡 2024-10-08 01:26:38

确保BufferedDisplay 对象已添加到容器(例如Frame),并且容器本身可见。如果组件未显示,则调用 repaint() 将不会导致调用 update()

这只是一般建议。如果您发布一个可以编译和运行的独立示例,可能会更容易找出内容是错误的。

Make sure that the BufferedDisplay object has been added to a container (e.g. a Frame), and that the container itself is visible. If the component is not showing, then calls to repaint() will not result in update() being called.

This is just generic advice. If you post a self-contained example that can be compiled and run it will probably be easier to find out what is wrong.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文