(对不起,如果这个问题没有正确完成,我是新来的。但是至少我在问自己的问题之前做了很多研究)

你好。我正在用Java编写二十一点游戏,现在正变得相当庞大。我的问题是如何处理摆动组件的多个实例,我想您可以调用它。我无法确定是否可以在类级别或特定方法中创建组件(例如jpanel和jbutton)。

如果我使用它们的相应方法创建它们,那么我的动作侦听器将看不到它们,但是如果我将它们创建为类级别,则在调用dispose()时它们将被删除。

 class BlackjackGame extends JFrame implements ActionListener{

    public void mainMenu(){

        JPanel menuPane = new JPanel(new GridBagLayout()); //Init of main menu
        GridBagConstraints c = new GridBagConstraints();
        menuPane.setBackground(new Color(125,0,0));
        menuPane.setBounds(620,220,175,250);

        JLabel menuTitle = new JLabel("Welcome to Blackjack!");//Main menu-content
        c.gridx = 1;
        c.gridy = 0;
        c.insets = new Insets(0,0,20,0);
        menuPane.add(menuTitle, c);

        JButton playButton = new JButton("Play!");
        playButton.addActionListener(this);
        c.gridx = 0;
        c.gridy = 1;
        c.gridwidth = 3;
        c.ipadx = 25;
        c.ipady = 25;
        c.insets = new Insets(0,0,0,0);
        menuPane.add(playButton, c);

        JButton exitButton = new JButton("Exit!");
        exitButton.addActionListener(this);
        c.gridx = 0;
        c.gridy = 2;
        c.gridwidth = 3;
        menuPane.add(exitButton, c);

        JButton rulesButton = new JButton("Set rules.");
        rulesButton.addActionListener(this);
        c.gridx = 0;
        c.gridy = 3;
        c.gridwidth = 3;
        menuPane.add(rulesButton, c);

        this.add(menuPane,0);
    }

    //This is where I get problems
    public void actionPerformed (ActionEvent event){
        if(event.getSource() == playButton){
            //I want the menuPane to disappear, and a transition into the game.
            menuPane.dispose();
            //Call method for the rest of the game.

        }else if(event .getSource() etcetera etcetera){
            etcetera etcetera
        }
    }
}


用这种方法完成后,actionlistener找不到我的组件,例如playButton或menuPane。但是,如果我将它们作为类级别的对象引入:

class BlackjackGame extends JFrame implements ActionListener{

    JPanel menuPane = new JPanel(new GridBagLayout());
    JLabel menuTitle = new JLabel("Welcome to Blackjack!");
    JButton playButton = new JButton("Play!");
    JButton exitButton = new JButton("Exit!");
    JButton rulesButton = new JButton("Set rules.");

    public void mainMenu(){
        //Rest of code
    }

    public void actionPerformed(ActionEvent event){
        menuPane.dispose();
        //Rest of code
    }
}


...然后在我呼叫menuPane.dispose()时,当我想再次呼叫mainMenu()时如何找回它?如果要返回主菜单,则需要创建一个menuPane以及所有按钮的新实例,但是由于它们是类级别的,因此已经无法使用。

请帮助我,谢谢!

PS。如果有帮助,我可以发布完整的代码,因为它是atm。

编辑:Dan的答案已被接受,因为它确实是正确的答案,并且对我的特定程序非常有效。谢谢你,圣诞节快乐!

最佳答案

首先,除非我误解了您的代码,否则menuPane.dispose()不应该工作,因为JPanel没有名为dispose()的函数

如果要对菜单使用相同的menuPane,则是执行所需操作的最佳方法。代替menuPane.dispose();依次使用remove(menuPane);add(yourOtherPanel);

工作实例

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class BlackjackGame extends JFrame implements ActionListener {
    private JPanel menuPane;
    private JLabel menuTitle;
    private JButton playButton;
    private JButton exitButton;
    private JButton rulesButton;

    private JPanel otherPane;
    private JLabel otherTitle;
    private JButton otherButton;

    public BlackjackGame() {
        mainMenu();
        otherPanel();
        setSize(400, 400);
        setVisible(true);
    }

    private void mainMenu() {

        menuPane = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        menuPane.setBackground(new Color(125,0,0));
        menuPane.setBounds(620,220,175,250);

        menuTitle = new JLabel("Welcome to Blackjack!");
        c.gridx = 1;
        c.gridy = 0;
        c.insets = new Insets(0,0,20,0);
        menuPane.add(menuTitle, c);

        playButton = new JButton("Play!");
        playButton.addActionListener(this);
        c.gridx = 0;
        c.gridy = 1;
        c.gridwidth = 3;
        c.ipadx = 25;
        c.ipady = 25;
        c.insets = new Insets(0,0,0,0);
        menuPane.add(playButton, c);

        exitButton = new JButton("Exit!");
        exitButton.addActionListener(this);
        c.gridx = 0;
        c.gridy = 2;
        c.gridwidth = 3;
        menuPane.add(exitButton, c);

        rulesButton = new JButton("Set rules.");
        rulesButton.addActionListener(this);
        c.gridx = 0;
        c.gridy = 3;
        c.gridwidth = 3;
        menuPane.add(rulesButton, c);

        add(menuPane);
    }

    private void otherPanel() {
        otherPane = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        otherPane.setBackground(new Color(125,0,0));
        otherPane.setBounds(620,220,175,250);

        otherTitle = new JLabel("Welcome to Second Pane!");
        c.gridx = 1;
        c.gridy = 0;
        c.insets = new Insets(0,0,20,0);
        otherPane.add(otherTitle, c);

        otherButton = new JButton("Go Back!");
        otherButton.addActionListener(this);
        c.gridx = 0;
        c.gridy = 1;
        c.gridwidth = 3;
        c.ipadx = 25;
        c.ipady = 25;
        c.insets = new Insets(0,0,0,0);
        otherPane.add(otherButton, c);
    }

    public void actionPerformed (ActionEvent event) {
        if(event.getSource() == playButton) {
            remove(menuPane);
            add(otherPane);
            validate();
            repaint();

        } else if(event.getSource() == otherButton) {
            remove(otherPane);
            add(menuPane);
            validate();
            repaint();
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> new BlackjackGame());
    }
}


编辑评论

因此,java方法remove()仅从容器(在本例中为JFrame)中删除对象。此方法不会影响它移动的对象,因此以后可以重用该对象。因此,为什么在上面的代码中我可以只使用remove()add()方法而无需重新声明或重新制作menuPaneotherPane

至于为什么我这样声明对象

`private JPanel menuPane;`


然后像这样初始化

menuPane = new JPanel(new GridBagLayout());


这是因为我希望ActionListener能够看到对象而无需立即对其进行初始化。 private JPanel menuPane;行使对象成为全局变量,而menuPane = new JPanel(new GridBagLayout());行使它成为我将要使用的对象。以这种方式代替JPanel menuPane = new JPanel(new GridBagLayout());这样做也意味着我可以在多种方法中重用相同的变量。例如

private JPanel panel;

private void createPanelOne() {
    panel = new JPanel(new FlowLayout());
    ...
    add(panel);
}

private void createPanelTwo() {
    panel = new JPanel(new GridBagLayout());
    ...
    add(panel);
}


完成此操作后,您的JPanel中将有两个JFrame,它们将有所不同,但是您只需要使用一个JPanel

这是声明它的另一种方法,它使一个局部变量。除非您将局部变量传递给其他人,否则本地变量对您正在使用的方法之外的其他方法不可见。

JPanel panel = new JPanel();


我不会说这是一个缺点。我认为有时在不应该被其他方法看到的方法中使用局部变量会很好。

最后,要将局部变量传递给其他方法,可以在已创建的方法中使用参数。例如

public void setSomeValue(int val) {
    someValue = val;
}

10-06 09:22