Java - GUI、面板和数据访问

发布于 2024-09-25 22:59:52 字数 2358 浏览 1 评论 0原文

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

我有我的主类,它扩展了 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 的类)内部访问该数据。

I'm making a game with three main panels and a few subpanels, and I'm confused about how you "connect" the panels and their data.

I have my main class, which extends JFrame and adds three JPanels. Each of those panels is a subclass of JPanel. (Ex: JPanel gameControlPanel = new GameControlPanel(), where GameControlPanel is a class I created to extend JPanel.)

Now, all the game data (such as the game state, and two arraylists that hold saved players and saved scores) is in the game panel. But I need to get and set that data from the other two panels. And how to do so is evading me.

** So my question is: how do I do this? How can I access data in one JPanel subclass from another JPanel subclass (that have the same parent JFrame)?


If it helps, this is the extended JFrame class's code, where I add the three panels...:

    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);       

The graphicsPanel holds all of this data:

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.

And I want to access that data from inside the other two panels (gameDataPanel's class and gameControlButton's class).

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

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

发布评论

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

评论(3

祁梦 2024-10-02 22:59:52

研究模型视图控制器模式。将游戏状态和数据存储到模型中,并使用观察者或侦听器通知 UI 组件数据的变化。

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

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

然后,您可以使用与以下类似的类 Players 来代替 savingPlayers 列表:

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);
        }

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

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

并在构造函数内将面板注册为玩家的侦听器。

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

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

Study the Model View Controller pattern. Store the game state and data to the model, and use Observers or listeners to notify the UI components about the changes in the data.

For example, if you follow the way Swing has been implemented, define a listener interface like this:

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

Then, instead of the savedPlayers list you could have a class Players similar to this:

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);
        }

When you create a new Panel that needs to observe the saved players, you can just pass the instance of Players class to the panels in constructor:

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

And inside the constructor just register the panel as a listener to players.

This way, whenever something saves a player, regardless of which component/class it is, all the interested parties will get notified of the changes. And make sure to pass in the same instance of Players to all panels.

This is actually how the Swing components work too, if you take a look at for example the JPanel, it has a number of different addSomethingListener methods. The listeners are classes that implement a specific listener interface. And the models are exchangeable in many of the components, for example JTable uses TableModel, which in turn is also defined as an interface. However in your case you probably don't need to be able to use different model implementations.

筑梦 2024-10-02 22:59:52

数据应存储在 UI 部分之间共享的模型中,仅使用 UI 面板进行演示。使用观察者模式通知 UI 演示有关模型的更改。

Data should be stored in a model that is shared between UI parts, use UI panels only for presentation. Use observer pattern to notify UI presentation about changes in model.

蓝梦月影 2024-10-02 22:59:52

您说您想在多个面板中显示某些信息?
您可以创建一个 Global 类来静态保存此数据,然后使用 get...();set...(); 从其他类访问此信息> 方法。

示例:

public class Global
 {
     private static Object objectName;

     public Object getObjectName()
     {
         return objectName;
     }

     public void setObjectName(Object objectName)
     {
         this.objectName = objectName;
     }
}

如果我需要进一步详细说明,请告诉我。

You said that you want to display some information in more than one of the panels?
You could make a Global class to hold this data statically, and then access this information from your other classes using get...(); and set...(); methods.

Example:

public class Global
 {
     private static Object objectName;

     public Object getObjectName()
     {
         return objectName;
     }

     public void setObjectName(Object objectName)
     {
         this.objectName = objectName;
     }
}

Let me know if I need to elaborate further.

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