Java - графический интерфейс, панель и доступ к данным - PullRequest
1 голос
/ 04 октября 2010

Я делаю игру с тремя основными панелями и несколькими подпанелями, и меня смущает, как вы «соединяете» панели и их данные.

У меня есть основной класс, который расширяет JFrame и добавляет три JPanels. Каждая из этих панелей является подклассом JPanel. (Например: JPanel gameControlPanel = new GameControlPanel (), где GameControlPanel - это класс, созданный мной для расширения JPanel.)

Теперь все игровые данные (например, состояние игры и два массива, в которых хранятся сохраненные игроки и сохраненные результаты) находятся на игровой панели. Но мне нужно получить и установить эти данные из двух других панелей. И как это сделать, уклоняется от меня.

** Итак, мой вопрос: как мне это сделать? Как я могу получить доступ к данным в одном подклассе JPanel из другого подкласса JPanel (которые имеют тот же родительский JFrame)?


Если это поможет, это код расширенного класса 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).

Ответы [ 3 ]

3 голосов
/ 04 октября 2010

Изучите шаблон Model View Controller .Сохраните состояние игры и данные в модели и используйте наблюдателей или слушателей, чтобы уведомить компоненты пользовательского интерфейса об изменениях данных.

Например, если вы следуете тому, как реализован Swing, определите интерфейс слушателя следующим образом:

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

Тогда вместо списка savePlayers у вас может быть класс Playersпримерно так:

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.Слушатели - это классы, которые реализуют определенный интерфейс слушателя.И модели взаимозаменяемы во многих компонентах, например, JTable использует TableModel, которая, в свою очередь, также определяется как интерфейс.Однако в вашем случае вам, вероятно, не нужно использовать различные реализации моделей.

0 голосов
/ 04 октября 2010

Вы сказали, что хотите отображать некоторую информацию на нескольких панелях? Вы можете создать класс Global для статического хранения этих данных, а затем получить доступ к этой информации из других ваших классов, используя методы get...(); и set...();.

Пример:

public class Global
 {
     private static Object objectName;

     public Object getObjectName()
     {
         return objectName;
     }

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

Дайте мне знать, если мне нужно уточнить.

0 голосов
/ 04 октября 2010

Данные должны храниться в модели, которая разделяется между частями пользовательского интерфейса, используйте панели пользовательского интерфейса только для представления. Используйте шаблон наблюдателя, чтобы уведомить пользовательский интерфейс об изменениях в модели.

...