Java:repaint()方法,为什么它是气质?

时间:2014-01-16 00:06:51

标签: java image swing paint event-dispatch-thread

我有一段代码用于我正在研究的非常基本的2D平台游戏,我无法开始工作。游戏本身工作正常但由于某种原因标题屏幕不会出现。我设法将这归结为这样一个事实:当从title()方法调用时,repaint()方法没有做任何事情。无论我如何尝试调用它,导致事件/设置另一个计时器,paintComponent方法都没有做任何事情,甚至没有出现窗口。尽管如此,看起来与我非常相似的level()方法确实会出现窗口并执行paintComponent方法。

我很抱歉代码有多丑,这对我来说是一个实验,所以现在有点不整洁。如何解决这个问题的任何帮助将不胜感激。

这是JPanel类的代码,我遇到了问题。

public class Screen extends JPanel implements ActionListener{

int currentScreen;
Image title;
Image background;
Image ship;
Image black;
private Timer timer;
private Level lvl;

public Screen(){

    addKeyListener(new TAdapter());
    setFocusable(true);
    setBackground(Color.BLACK);
    setDoubleBuffered(true);

    title();
    level();
}


public void paintComponent(Graphics g) {

    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D)g;
    if(currentScreen == 0) {
        g2d.drawImage(title, 0, 0, this);
    }
    else if(currentScreen == 1){
        g2d.drawImage(background, 0, 0, this);
        g2d.drawImage(lvl.getAvImage(), lvl.getAvX(), lvl.getAvY(), this);
        g2d.setFont(new java.awt.Font("SansSerif", Font.PLAIN, 12));
        for(int i=0;i<4;i++)
            for(int j=0; j<4; j++){
                g2d.drawImage(lvl.getPlijImage(i,j), lvl.getPlijX(i,j), lvl.getPlijY(i,j), this);
                g2d.drawString(Integer.toString(lvl.getPlijCurrent(i,j)), lvl.getPlijX(i,j)+64, lvl.getPlijY(i,j)+16);

            }
        g2d.drawImage(spaceship, 0, 0, this);
        g2d.drawImage(black, 0, 736, this);
        g2d.setColor(Color.WHITE);
        g2d.drawString(lvl.getSqDisplay(), 450, 32);
    }
    Toolkit.getDefaultToolkit().sync();
    g.dispose();
}

public void title(){

    ImageIcon ii = new ImageIcon(this.getClass().getResource("Title.png"));
    title = ii.getImage();
    currentScreen = 0;
    repaint(); //doesn't invoke paint
    Scanner reader = new Scanner(System.in); //not relevant, just getting it to stop before opening level
    int a=reader.nextInt();
}

public void level(){

    lvl = new Level(1);
    ImageIcon ii = new ImageIcon(this.getClass().getResource("Background.png"));
    background = ii.getImage();
    ii = new ImageIcon(this.getClass().getResource("Ship.png"));
    ship = ii.getImage();
    ii = new ImageIcon(this.getClass().getResource("Black.png"));
    black = ii.getImage();
    currentScreen = 1;
    timer = new Timer(10, this);
    timer.start();

}

public void actionPerformed(ActionEvent e) {
    lvl.actionPerformer(e);
    repaint(); //does invoke paintComponent, but not when I jump here from the title bit
}

private class TAdapter extends KeyAdapter {

    public void keyReleased(KeyEvent e) {
        if(currentScreen == 1) lvl.keyReleased(e);
    }

    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        if(currentScreen == 1) lvl.keyPressed(e);
        else if((currentScreen == 0)&&(key == KeyEvent.VK_ENTER)){
            onTitle = false;
        }
    }
}

}

1 个答案:

答案 0 :(得分:3)

Scanner reader = new Scanner(System.in); //not relevant, just getting it to stop before opening level
int a=reader.nextInt();

我不同意见。这(很可能)是你遇到问题的原因。

这两个简单的行阻止事件调度线程处理任何新事件,包括重绘请求。这意味着,在title方法返回之前,不会出现新的颜料

请查看Concurrency in Swing了解详情。

有许多可能的解决方案,但您需要提供更多详细信息,告诉您在实现这些解决方案之前要实现的目标......