我正在编写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;
}
}
答案 0 :(得分:4)
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类将面向创建JPanels,然后将其放置到JFrames或JDialogs或JTabbedPanes中,或者在需要时通过CardLayouts进行交换。这将大大增加GUI编码的灵活性。
其他单独且不相关的问题:
答案 1 :(得分:0)
简而言之,您应该尝试使用jLayeredPane和多个jPanels,而不是多个框架。如果您使用的是Netbeans,请查看我的GUI制作指南:http://philofjava.webstarts.com/