如何正确构建我的 JFrame 项目?

How to correctly structure my JFrame project?

我在执行 JFrame 项目时遇到问题。

基本上,我是 Java 的新手,我想提高自己使用简单的 classes 做一些 GUI 应用程序的能力。

我有一个实例化我的对象的主要方法,一个 JFrame window class,一个 Panel class 和一个 Story class,它描述了我将要实现的每个功能如果您单击框架按钮,请调用。

我的问题是,我找不到使用故事的方法 class。我想将它的方法调用到 Panel 中,但 Story 已经采用了一个 Panel 参数(用于调用 TextArea 和 Buttons 等面板组件),因此我无法将其实例化到我的 Panel class.

这是代码示例:

主要 Class :

public class Main {

public static void main(String[] args) {

    GamePanel myPanel = new GamePanel();
    GameWindow myWindow = new GameWindow(myPanel);
}
}

Window Class :

public class GameWindow extends JFrame {

private GamePanel p;

public GameWindow(GamePanel p) {
    this.p = p;
    this.setSize(800,600);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setContentPane(this.p);
    this.setLayout(null);
    this.setVisible(true);
}

public void setPanel(GamePanel panel) {
    this.p = panel;
}
public GamePanel getPanel() {
    return this.p;
}
}

面板Class:

public class GamePanel extends JPanel {

// PANEL TITLE MENU
private JPanel titleSection = new JPanel();
private JLabel titleName = new JLabel("TEXT ADVENTURE");
private Font titleFont = new Font("Bradley Hand", Font.BOLD, 50);

// PANEL STARTBUTTON MENU
private JPanel buttonSection = new JPanel();
private JButton buttonStart = new JButton("START");
private Font buttonFont = new Font("Bradley Hand", Font.BOLD, 30);

// PANEL MAINTEXT GAME
private JPanel mainTextSection = new JPanel();
private JTextArea mainTextArea = new JTextArea();
private Font mainTextFont = new Font("Avenir", Font.PLAIN, 20);

// PANEL MAINBUTTONS GAME
private JPanel buttonPanel = new JPanel();
private JButton button1 = new JButton();
private JButton button2 = new JButton();
private JButton button3 = new JButton();
private JButton button4 = new JButton();

// PANEL PLAYERINFO GAME
private JPanel playerInfo = new JPanel();
private JLabel playerHp, playerHpNumber, playerWeapon, playerWeaponName;


// HANDLERS OBJECTS
private TitleHandler tHandler = new TitleHandler();
private ButtonsHandler cHandler = new ButtonsHandler();

// DEFAULT CONSTRUCTOR
public GamePanel() {

    this.setBackground(Color.darkGray);

    // TITLE SETUP
    titleSection.setBounds(100,80,600,150);
    titleSection.setBackground(Color.darkGray);
    this.add(titleSection);
    titleName.setForeground(Color.white);
    titleName.setFont(titleFont);
    titleSection.add(titleName);

    // STARTBUTTON SETUP
    buttonSection.setBounds(300,400,200,100);
    buttonSection.setBackground(Color.darkGray);
    this.add(buttonSection);
    buttonStart.setForeground(Color.black);
    buttonStart.setFont(buttonFont);
    buttonStart.addActionListener(tHandler);
    buttonSection.add(buttonStart);
}

public void createGameScreen() {

    // MENU SCREEN DISABLE
    titleSection.setVisible(false);
    buttonSection.setVisible(false);

    // MAINTEXT SETUP
    mainTextSection.setBounds(100,100,600,250);
    mainTextSection.setBackground(Color.darkGray);
    this.add(mainTextSection);
    mainTextArea.setBounds(100,100,600,250);
    mainTextArea.setBackground(Color.darkGray);
    mainTextArea.setForeground(Color.white);
    mainTextArea.setFont(mainTextFont);
    mainTextArea.setLineWrap(true);
    mainTextSection.add(mainTextArea);

    // MAINBUTTONS SETUP
    buttonPanel.setBounds(250,350,300,150);
    buttonPanel.setBackground(Color.darkGray);
    buttonPanel.setLayout(new GridLayout(4,1));
    this.add(buttonPanel);
    button1.setForeground(Color.black);
    button1.setFont(mainTextFont);
    button1.addActionListener(cHandler);
    button1.setActionCommand("c1");
    buttonPanel.add(button1);
    button2.setForeground(Color.black);
    button2.setFont(mainTextFont);
    //button2.addActionListener(cHandler);
    //button2.setActionCommand("c2");
    buttonPanel.add(button2);
    button3.setForeground(Color.black);
    button3.setFont(mainTextFont);
    //button3.addActionListener(cHandler);
    //button3.setActionCommand("c3");
    buttonPanel.add(button3);
    button4.setForeground(Color.black);
    button4.setFont(mainTextFont);
    //button4.addActionListener(cHandler);
    //button4.setActionCommand("c4");
    buttonPanel.add(button4);

    // PLAYERINFO SETUP
    playerInfo.setBounds(100,25,600,50);
    playerInfo.setBackground(Color.darkGray);
    playerInfo.setLayout(new GridLayout(1,4));
    this.add(playerInfo);
    playerHp = new JLabel("HP :");
    playerHp.setFont(mainTextFont);
    playerHp.setForeground(Color.white);
    playerInfo.add(playerHp);
    playerHpNumber = new JLabel();
    playerHpNumber.setFont(mainTextFont);
    playerHpNumber.setForeground(Color.white);
    playerInfo.add(playerHpNumber);
    playerWeapon = new JLabel("Weapon :");
    playerWeapon.setFont(mainTextFont);
    playerWeapon.setForeground(Color.white);
    playerInfo.add(playerWeapon);
    playerWeaponName = new JLabel("None");
    playerWeaponName.setFont(mainTextFont);
    playerWeaponName.setForeground(Color.white);
    playerInfo.add(playerWeaponName);
    repaint();
}

public void setMainTextArea(String t) {
    this.mainTextArea.setText(t);
}
public void setButton1(String t) {
    this.button1.setText(t);
}
public void setButton2(String t) {
    this.button2.setText(t);
}
public void setButton3(String t) {
    this.button3.setText(t);
}
public void setButton4(String t) {
    this.button4.setText(t);
}


public class ButtonsHandler implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        defineEvent(e);
    }

    public void defineEvent(ActionEvent e) {
        if (true) {
            // call Story functions for test
        } else {

        }
    }
}

// NESTED CLASS FOR HANDLING MENU STARTBUTTON
public class TitleHandler implements ActionListener {

    public void actionPerformed(ActionEvent e) {
        createGameScreen();
    }
}
}

故事 Class :

public class Story {

protected String position = "Start";
protected GamePanel p;

public Story() {

}

// FUNCTIONS
public void gameStart() {
    this.position = "Start";
    p.setMainTextArea("...\nYou're waking up in a forest.\nYour head hurts a lot.\nWhy are you here ?\n\n" +
            "You decide to explore through the forest, looking for clues.");
    p.setButton1(">");
}

// GETTERS & SETTERS
public String getPosition() {
    return position;
}
public GamePanel getP() {
    return p;
}

public void setGamePanel(GamePanel p) {
    this.p = p;
}
}

(抱歉,我这里的代码好像有括号问题)

我想我的代码结构很糟糕,但我找不到将故事和面板分开的方法 class。

任何帮助将不胜感激! :)

您需要了解一下 MVC(模型视图控制器)体系结构,在您的情况下,我相信您可以使用它更简单的姐妹,称为 MV(模型视图)。

你痛苦的原因是你将模型(Story)和视图(Panel)混合到同一个class(Story.java)。使用状态机模式可以(相对)轻松地实现您的模型。

您可能还需要实施观察者模式,其中观察者是面板,Observable 是故事。您可以让 GamePanel 实现 PropertyChangeListener,您的模型(故事)将在每次状态更改时触发 propertyChange 事件。关于此的更多信息,您可以找到 at this article.