(对不起,如果这个问题没有正确完成,我是新来的。但是至少我在问自己的问题之前做了很多研究)
你好。我正在用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()
方法而无需重新声明或重新制作menuPane
和otherPane
。至于为什么我这样声明对象
`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;
}