Как остановить Swing от открытия нового фрейма?

Gavin Gnaster спросил: 13 июня 2018 в 11:59 в: java

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

Я хочу написать каждый экран в отдельном классе, чтобы увеличить организацию и читаемость моего кода. Однако всякий раз, когда я нажимаю на JButton, чтобы перейти к следующему экрану, открывается новый текст JFrame. Как я могу написать свой графический интерфейс, чтобы все изменения экрана происходили только в одном кадре? Является ли Java такой функцией?

Я просмотрел, по крайней мере, пару десятков вопросов Java Swing, но все же не могу понять, что я делаю неправильно с моей реализацией Java swing.

package guiPackage;import javax.swing.*;
import thingsPackage.Player;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class StartGame extends JFrame {JFrame Game;
JPanel buttonMenu, screen;
JButton newGame, settings, exit, loadGame;    public StartGame() {    Game = new JFrame();
    Game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    
    Game.setVisible(true);
    Game.setSize(750, 750);
    Game.setLocationRelativeTo(null);    screen = new JPanel();
    screen.setVisible(true);    TitleScreenHandler ts = new TitleScreenHandler();    buttonMenu = new JPanel();    newGame = new JButton("New Game");
    newGame.addActionListener(ts);
    loadGame = new JButton("LoadGame");
    loadGame.addActionListener(ts);    settings = new JButton("Settings");
    settings.addActionListener(ts);    exit = new JButton("Exit");
    exit.addActionListener(ts);    Game.add(screen);
    screen.add(buttonMenu, BorderLayout.SOUTH);
    buttonMenu.add(newGame);
    buttonMenu.add(loadGame);
    buttonMenu.add(settings);
    buttonMenu.add(exit);}public class TitleScreenHandler implements ActionListener{
    public void actionPerformed(ActionEvent titleScreenEvent) {        if (titleScreenEvent.getSource() == newGame) {
            buttonMenu.setVisible(false);
            CharacterCreator newCharacter = new CharacterCreator();        }
        else if (titleScreenEvent.getSource() == loadGame) {
            buttonMenu.setVisible(false);
        }
        else if (titleScreenEvent.getSource() == settings) {
            buttonMenu.setVisible(false);        }
        else if (titleScreenEvent.getSource() == exit){
            System.out.println("goodbye");
            System.exit(0);
        }
    }
}
}

package guiPackage;import javax.swing.*;
import java.awt.*;
import java.util.Scanner;public class CharacterCreator extends StartGame {JTextField newName;
JPanel creatorScreen;
Scanner scan = new Scanner(System.in);public CharacterCreator() {    creatorScreen = new JPanel();
    //creatorScreen.setVisible(true);    newName = new JTextField("Create a charactor");
    //newName.setLocation(null);    screen.add(creatorScreen);
    creatorScreen.add(newName);
}
public String setCharacterName(){
    String characterName = "";
    return characterName;
}
}

2 ответа

Есть решение
Hovercraft Full Of Eels ответил: 13 июня 2018 в 12:15

Предполагается ли, что Java должна работать следующим образом?

Ваш код выполняет только то, что вы ему рассказываете, и у вас есть несколько проблем в вашем коде, включая одну проблему здесь:

public class CharacterCreator extends StartGame {

Вы злоупотребляете наследованием, если класс CharacterCreator распространяется от StartGame. Вы, кажется, делаете это, чтобы разрешать общение между классами, но это не то, наследование, и при этом вы являетесь дочерним классом, вызывающим конструктор родительского класса, создавая больше окон, чем вы хотите или нуждаетесь. Решение заключается в not использовании наследования здесь, а скорее для передачи ссылок на то, где они необходимы.

Также, пожалуйста, ознакомьтесь с использованием нескольких JFrames, Good / Bad Practice? поскольку ваше приложение должно иметь только одно основное окно приложения или JFrame. Любые дочерние окна должны быть JDialogs, а не JFrames.

Другая проблема: StartGame расширяет JFrame, а также содержит переменную JFrame - слишком много JFrames и лучше всего избавиться от того или другого. Обычно вы не хотите создавать классы, которые расширяют окно верхнего уровня, так как вы сами будете рисовать себя в углу, если ваш класс расширит JFrame, заставив вас создавать и отображать JFrames, когда требуется больше гибкости. На самом деле, я бы рискнул, что большая часть кода графического интерфейса Swing, который я создал, и который я видел, не поддерживает не расширение JFrame, и на самом деле редко бывает, что вы когда-нибудь захотите это. Чаще всего ваши классы GUI будут ориентированы на создание JPanels, которые затем могут быть помещены в JFrames или JDialogs или JTabbedPanes или заменены через CardLayouts, где это необходимо. Это значительно повысит гибкость вашего графического интерфейса.

Другие отдельные и несвязанные проблемы:

  • Кажется, вы комбинируете графический интерфейс, управляемый событиями, с консольным графическим интерфейсом, с использованием объекта Scanner, инициированного с помощью System.in. Это не очень хорошая идея, так как эти две парадигмы программирования не просто хорошо сочетаются друг с другом, и вместо этого лучше всего придерживаться той или иной линейной консоли или графического интерфейса, управляемого событиями.
Gavin Gnaster ответил: 13 июня 2018 в 12:39
: D Большое вам спасибо за эту информацию. это заставляло меня задуматься о том, как заставить это работать. Я очень ценю урок, как правильно использовать компоненты swing.
Phil Longenecker ответил: 18 июня 2018 в 01:00

Короче говоря, вы должны попробовать использовать jLayeredPane и несколько jPanels, а не несколько кадров. Если вы используете Netbeans, ознакомьтесь с моим руководством по созданию графических интерфейсов по адресу: http://philofjava.webstarts.com/

Дополнительное видео по вопросу: Как остановить Swing от открытия нового фрейма?

Уроки Java для начинающих | #23 - GUI Java (Swing JFrame)

Java Programming Tutorial - 51 - GUI with JFrame

Java Programming with IntelliJ IDEA: Creating, Designing & Showing Swing GUI Forms