首页 > 解决方案 > 如何正确构建我的 JFrame 项目?

问题描述

我在做我的 JFrame 项目时遇到了麻烦。

基本上,我对 Java 还很陌生,我想通过使用简单的类来改进自己做一些 GUI 应用程序。

我有一个实例化我的对象的 main 方法、一个 JFrame 窗口类、一个 Panel 类和一个 Story 类,它们描述了如果您单击 Frame 按钮我将调用的每个函数。

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

这是代码示例:

主要课程:

public class Main {

public static void main(String[] args) {

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

窗口类:

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;
}
}

面板类:

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();
    }
}
}

故事课:

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;
}
}

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

我想我的代码结构很糟糕,但我找不到将我的 Story 和 Panel 类分开的方法。

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

标签: javajframejpanel

解决方案


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

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

您可能还需要实现观察者模式,其中观察者是面板,可观察者是故事。您可以让 GamePanel 实现 PropertyChangeListener 并且您的模型(故事)将在每次其状态更改时触发propertyChange事件。有关这方面的更多信息,您可以在这篇文章中找到。


推荐阅读