是什么导致JLabel不更新?

时间:2015-03-25 21:14:48

标签: java swing observer-pattern

我正在使用观察者模式显示转动它是否正在播放。我正在从我的Observable获得正确的数据,这就是为什么我不发布它。如您所见,正在设置文本,因为我可以调用label.getText()。 标签怎么不更新?

我尝试过重绘,重新验证,SwingUtilities.invokeLater,updateUI以及所有类型的东西。我不知道我做错了什么。

先谢谢你。

public class PlayersTurnPane extends JPanel implements Observer {

    private JLabel label = new JLabel();

    public PlayersTurnPane() {
        setLayout(new BorderLayout());
        setBackground(Color.gray);
        label.setText("White");
        label.setHorizontalAlignment(getWidth() / 2);
        label.setFont(new Font("Serif", Font.PLAIN, 25));
        add(label);

    }

    @Override
    public void update(Observable arg0, Object arg1) {
        label.setText((String)arg1); //But it will not update label
        System.out.println(label.getText()); //The text is being set
    }

}

My Observable

 public class TurnObserver extends Observable {

    public TurnObserver(PlayersTurnPane playersTurnPane) {
        addObserver(playersTurnPane);
    }

    public void setTurn(String turn){
        setChanged();
        notifyObservers(turn);
        clearChanged();
    }

}

我发送数据的地方

private TurnObserver turnObserver = new TurnObserver(new PlayersTurnPane());    

public void grabPiece(BoardTile boardTile) {
        if(focusedPiece != null && playerTurn.getCurrentTurn() == focusedPiece.getPieceColor()) {
            boardTile.add(focusedPiece);
            updateUI();
            playerTurn.changeTurn();
            turnObserver.setTurn(playerTurn.getCurrentTurn());
        }
    }

此处添加了面板

public class EastPanel extends JPanel {

    public EastPanel() {
        setLayout(new GridLayout(3,0));
        add(new TimePane());
        add(new MoveHistoryPane());
        add(new PlayersTurnPane());
    }

}

1 个答案:

答案 0 :(得分:2)

如果正在打印System.out.println(label.getText());,那么您在代码中未显示Swing线程问题,可能是由于在Swing事件线程上运行了长时间运行的代码,导致此线程无法执行其工作 - - 就像在JLabel上绘制更新的文本一样。确保所有长时间运行的代码都在后台线程上完成,并且Swing状态发生更改并且在Swing事件线程上进行查询。请阅读Concurrency in Swing了解详细信息。

重,

  

我从我的Observable获得了正确的数据,这就是为什么我不发布它。

但是,未发布的代码是您解决问题的关键。


Dang,Mad是对的:你是影子:

public TurnObserver() {
    addObserver(new PlayersTurnPane());
}

您正在添加 PlayersTurnPane作为观察者,但可能不会显示PlayersTurnPane!密钥:每次在构造函数上调用 new 时,都会创建 对象,此处为PlayersTurnPane。您应该传入显示的PlayersTurnPane,而不是新的。

你遇到了这样的代码问题:

public class EastPanel extends JPanel {

    public EastPanel() {
        setLayout(new GridLayout(3,0));
        add(new TimePane());
        add(new MoveHistoryPane());
        add(new PlayersTurnPane());
    }
}

正在匿名创建dsiplayed PlayersTurnPane - 对象正被添加到显示中,但此对象未被任何变量引用,如果你要去,这需要完成将完全相同的PlayersTurnPane对象传递给使其成为可观察对象的方法。

我建议您使用类字段而不是需要对象引用的匿名对象。所以在这里,或许更好的是:

public class EastPanel extends JPanel {

    public EastPanel(PlayersTurnPane playersTurnPane) {
        setLayout(new GridLayout(3,0));
        add(new TimePane()); // you likely need parameters for 
        add(new MoveHistoryPane());  // these two objects as well
        add(playersTurnPane);
    }
}

您似乎缺少的关键概念是 引用 对于感兴趣的对象指针的重要性之一。阅读本文。