Java - GUI、面板和数据访问

标签 java class subclass jframe jpanel

我正在制作一个包含三个主面板和几个子面板的游戏,我对如何“连接”面板及其数据感到困惑。

我有我的主类,它扩展了 JFrame 并添加了三个 JPanel。这些面板中的每一个都是 JPanel 的子类。 (例如:JPanel gameControlPanel = new GameControlPanel(),其中 GameControlPanel 是我创建的用于扩展 JPanel 的类。)

现在,所有游戏数据(例如游戏状态,以及保存已保存玩家和已保存分数的两个数组列表)都在游戏面板中。但我需要从其他两个面板获取和设置该数据。而如何做到这一点是在逃避我。

** 所以我的问题是:我该怎么做?如何从另一个 JPanel 子类(具有相同的父 JFrame)访问一个 JPanel 子类中的数据?


如果有帮助,这是扩展的 JFrame 类的代码,我在其中添加了三个面板...:

    JPanel controlButtonsPanel = new GameControlButtons();
    controlButtonsPanel.setPreferredSize(new Dimension(801,60));
    controlButtonsPanel.setBorder(new LineBorder(Color.white, 1));
    constraints.anchor = GridBagConstraints.NORTHWEST;
    constraints.weightx = 2;
    constraints.weighty = 0.3;
    this.add(controlButtonsPanel, constraints);

    JPanel gameDataPanel = new GameDataPanel();
    gameDataPanel.setPreferredSize(new Dimension(500,838));
    gameDataPanel.setBorder(new LineBorder(Color.white, 2));
    constraints.anchor = GridBagConstraints.NORTHEAST;
    constraints.weightx = 1;
    constraints.weighty = 2;
    this.add(gameDataPanel, constraints);

    JPanel graphicsPanel = new RoofRunnerGame("Ken");
    constraints.anchor = GridBagConstraints.SOUTHWEST;
    constraints.weightx = 2;
    constraints.weighty = 1;
    graphicsPanel.setBorder(new LineBorder(Color.white, 1));
    graphicsPanel.setPreferredSize(new Dimension(800,800));
    graphicsPanel.requestFocus();
    this.add(graphicsPanel, constraints);       

graphicsPanel 包含所有这些数据:

private ArrayList<Player> savedPlayers;                                     // Holds saved data for player's who paused and exited game.
private ArrayList<Player> savedScores;                                      // Holds high scores from player's who played game and died.
private ArrayList<Birds> birdList = new ArrayList<Birds>();                 // Not serialized due to its randomness and unimportance to player.
private ArrayList<Clouds> cloudList = new ArrayList<Clouds>();              // Not serialized due to its randomness and unimportance to player.
private Player gamePlayer;                                                  // Player object that holds all data for a game instance.

我想从其他两个面板(gameDataPanel 的类和 gameControlButton 的类)访问该数据。

最佳答案

研究 Model View Controller图案。将游戏状态和数据存储到模型中,并使用 Observers 或 listeners 将数据的变化通知给 UI 组件。

例如,如果您按照 Swing 的实现方式,定义一个监听器接口(interface),如下所示:

public interface PlayersListener {
    void playerSaved(Player player);
}

然后,您可以使用类 Players 来代替 savedPlayers 列表:

public class Players {
    private List<PlayersListener> listeners = ...;
    private List<Player> players = ...;

    public void addPlayersListener(PlayersListener listener) {
        if (!listeners.contains(listener)) {
            listeners.add(listener);
        }
    }

    public voi removePlayerListener(PlayerListener listener) {
        listeners.remove(listener);
    }

    public voi savePlayer(Player player) {
        players.add(player);
        for (PlayerListener listener : listeners) {
            listener.playerSaved(player);
        }

当您创建一个需要观察已保存玩家的新面板时,您可以将 Players 类的实例传递给构造函数中的面板:

controlButtonsPanel = new GameControlButtons(players);
..
gameDataPanel = new GameDataPanel(players);

在构造函数中,只需将面板注册为 players 的监听器。

这样,无论何时某物 保存了玩家,无论它是哪个组件/类,所有相关方都会收到更改通知。并确保将相同的 Players 实例传递给所有面板。

这实际上也是 Swing 组件的工作方式,如果您看一下 JPanel,它有许多不同的 addSomethingListener 方法。监听器是实现特定监听器接口(interface)的类。并且模型在许多组件中是可交换的,例如 JTable 使用 TableModel,后者也被定义为接口(interface)。但是,在您的情况下,您可能不需要能够使用不同的模型实现。

关于Java - GUI、面板和数据访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3852989/

相关文章:

c# - 使用子类和方法的最佳方式

java - Android scrollview 去除蓝光

java - 使用 Spring 和 JUnit 在 @Before 和 @Test 执行之间注入(inject)逻辑

java - 创建一个知道他的类的对象

C++ 使用 "this"作为参数?

Javascript 在调用 super 之前初始化类属性

c++ - 如何检查对象的类型是否是 C++ 中的特定子类?

java - eclipse RCP 中的 plugin.properties 机制

Java正则表达式与句点部分匹配

javascript - 具有默认值的 JS 子类