【问题标题】:How to stop Swing from opening a new frame?如何阻止 Swing 打开新框架?
【发布时间】:2018-07-08 01:39:00
【问题描述】:

我正在编写 Java 文本冒险,并使用 Java Swing 作为一种将简单的用户 GUI 显示为游戏屏幕的方式。我想要三个不同的窗口,一个作为开始屏幕,一个用于用户输入名称和一些属性的角色创建屏幕,另一个用于实际进行游戏。

我想在一个单独的类中编写每个屏幕,以增加我的代码的组织性和可读性。但是,每当我单击JButton 进入下一个屏幕时,都会打开一个全新的JFrame 内容。如何编写我的 GUI,以便所有屏幕更改都发生在一帧中? 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;
}
}

【问题讨论】:

    标签: java swing user-interface jframe


    【解决方案1】:

    Java 应该像这样运行吗?

    您的代码只是按照您的指示行事,而您的代码中存在多个问题,包括此处的一个问题:

    public class CharacterCreator extends StartGame {
    

    您通过从 StartGame 扩展 CharacterCreator 类来滥用继承。您似乎这样做是为了允许类之间的通信,但这不是继承的目的,并且在这样做时,您的子类正在调用父类的构造函数,从而创建了比您想要或需要的更多的窗口。解决方案是在此处使用继承,而是将引用传递到需要它们的位置。

    另外请查看The Use of Multiple JFrames, Good/Bad Practice?,因为您的应用程序应该只有一个主应用程序窗口或 JFrame。任何子窗口都应该是 JDialogs,而不是 JFrames。

    另一个问题:StartGame 扩展了 JFrame 并且还保存了一个 JFrame 变量——JFrame 太多,最好去掉其中一个。通常您不想创建扩展顶级窗口的类,因为您会发现自己通过让您的类扩展 JFrame 将自己画在一个角落,迫使您创建和显示 JFrame,而通常需要更大的灵活性。事实上,我敢冒险说,我创建的大部分 Swing GUI 代码扩展了 JFrame,事实上你很少愿意这样做这。更常见的是,您的 GUI 类将用于创建 JPanel,然后可以将其放置到 JFrame 或 JDialogs 或 JTabbedPanes 中,或者在需要时通过 CardLayouts 交换。这将大大增加您的 GUI 编码的灵活性。

    其他独立且不相关的问题:

    • 您似乎正在将事件驱动的 GUI 与控制台 GUI 相结合,因为您使用的是由 System.in 启动的 Scanner 对象。这不是一个好主意,因为这两种编程范式不容易相互配合,最好坚持使用其中一种,无论是线性控制台程序还是事件驱动的 GUI。

    【讨论】:

    • :D 非常感谢您提供这些信息。我一直在想如何让它发挥作用。我非常感谢关于如何正确使用挥杆组件的课程。
    【解决方案2】:

    简而言之,您应该尝试使用 jLayeredPane 和多个 jPanel,而不是多个框架。如果您使用的是 Netbeans,请查看我的 GUI 制作指南:http://philofjava.webstarts.com/

    【讨论】:

      猜你喜欢
      • 2015-10-18
      • 2012-03-25
      • 1970-01-01
      • 2013-05-20
      • 2014-06-29
      • 1970-01-01
      • 1970-01-01
      • 2015-07-03
      • 2010-09-16
      相关资源
      最近更新 更多