调用repaint()+ revalidate()后,图像不会立即被替换

时间:2015-01-14 21:25:19

标签: java image swing

我正在制作一个游戏/模拟器,我正在使用以下方法将Image加载到我当前的Java项目中:

public static Image getImage(String name) {
    URL url = ImageLoader.class.getClassLoader().getResource("resources/" + name);
    Image img = Toolkit.getDefaultToolkit().createImage(url);
    ImageLoader.tracker.addImage(img, 1);
    try {
        ImageLoader.tracker.waitForID(1);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return img;
}

这会将图像加载到我的班级中,该班级正在绘制所有项目,包括玩家(他可以面对的每个方向有4个不同的图像:北,南,东,西):

private Image player = ImageLoader.getImage("playerEast.png");
private Image playerEast = ImageLoader.getImage("playerEast.png");
private Image playerWest = ImageLoader.getImage("playerWest.png");
private Image playerSouth = ImageLoader.getImage("playerSouth.png");
private Image playerNorth = ImageLoader.getImage("playerNorth.png");

加载到图像上方的类在这样的区域中绘制它们:

public class TerritoryPanel extends JPanel implements Observer {
@Override
protected void paintComponent(Graphics g){
    super.paintComponent(g);
//Draw player
    g.drawImage(player, (x, y, this);
     

}

我正在尝试使用此方法在同一个类中更新照片:

public void rotateEast(){
    player = playerEast;
    repaint();
    revalidate();
}

..但是只是调用这个rotateEast()不会立即更新图片,只有当我的常规Observer update()循环调用repaint()时它才会更新,这会每秒发生一次,因此可以看到丢失的rotateEast重绘:

@Override
public void update(Observable o, Object arg) {
    if (EventQueue.isDispatchThread()) {
        this.repaint();
    } else { // Simulation-Thread
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                repaint();
            }
        });
    }
}

为什么来自rotateEast的repaint()似乎没有效果?非常感谢你前进

1 个答案:

答案 0 :(得分:0)

  

但是只是调用这个rotateEast()不会立即更新图片,只有当我的常规Observer update()周期调用repaint()时才会更新,

不知道它是否有所作为,但正常的逻辑是:

revalidate(); // to invoke the layout manager
repaint(); // to repaint all the components

即使在这种情况下没有区别,在动态更改组件的属性时也应始终使用此顺序,包括从面板添加/删除组件。