JFrame重绘/重新加载

4

我在启动新会话时遇到了困难。当我使用菜单选项“新游戏”时,我得到了一个新的实例 - 实际上,我只想用一个新实例替换当前实例。我尝试了很多不同的方法,但仍然无法解决它...

这是我的代码:

package tictactoe;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class TicTacToe2 extends JFrame implements ActionListener {

char[][] game = new char[3][3];
JButton[][] buttons = new JButton[3][3]; 

JButton menuItem      = new JButton();   
JMenu     menu        = new JMenu  ("TicTacToe");
JMenuItem newgame     = new JMenuItem("Start New Game"), 
          exit        = new JMenuItem("Exit"); 

TicTacToe2()
{
    super("Tic Tac Toe");
    setSize(500, 600);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setVisible(true);
    setLayout( new BorderLayout());

    JPanel northPanel= new JPanel();
    northPanel.setLayout(new FlowLayout(FlowLayout.LEFT));  
    add("North", northPanel);

    JPanel buttonPanel = new JPanel();
    buttonPanel.setLayout(new GridLayout(3,3, 4, 4));
    add("Center", buttonPanel);
    Font font = new Font("Serif", Font.BOLD, 32);

    for (int row=0; row < game.length; row++)
    {
        for (int col =0; col < game[row].length; col++)
        {
            game[row][col] = ' ';
            JButton b = new JButton(" ");
            b.setFont(font);
            b.setBackground(Color.green);
            b.addActionListener(this);
            buttons[row][col] = b;
            buttonPanel.add(b);
        }
    } 

    menu.add(newgame);  
    menu.add(exit);
    newgame.addActionListener(this); 
    exit.addActionListener(this); 

    JMenuBar bar = new JMenuBar( ); 
    bar.add(menu);  
    setJMenuBar(bar); 

} 
public void actionPerformed(ActionEvent e) {
    Object  menusource = e.getSource();   
    if(menusource ==  newgame){ 
        new TicTacToe2();   
    }else if(menusource ==  exit){
        System.exit(0);
    }  
} 
public static void main(String[] args) {
    TicTacToe2 ttt = new TicTacToe2();

}
}

我会写一个继承自JPanel的TicTacToePanel,然后在TicTacToe2()中添加(BorderLayout.CENTER,buttonPanel = new TicTacToePanel());(明确使用常量“Center”是不好的编程习惯),然后按照sampson-chen所说,有一个TicTacToePanel.reset()方法,运行两个嵌套的for循环。 - ignis
4个回答

4
每次通过“新游戏”菜单创建一个新实例时,您都是这样做的:
        new TicTacToe2();   

如果您只想重置实例,请编写一个reset()方法,将游戏状态设置为初始状态。

2
public void actionPerformed(ActionEvent e) {
    Object  menusource = e.getSource();   
    if(menusource ==  newgame){ 
        new TicTacToe2();   //What are you doing with this object? 
                            //Should really be resetGame();
    }else if(menusource ==  exit){
        System.exit(0);
    }  
} 

可能会有问题...我怀疑这是您获得新框架实例的地方。 有一个方法可以将数组清除为默认值,重置分数,然后您就可以开始了。


2

不要创建一个新的类实例

new TicTacToe2();

当点击“新游戏”菜单项时,您可以清除按钮数组的文本并准备开始一个新的游戏:

for (int i=0; i < buttons.length; i++ ) {
   for (int j=0; j < buttons[0].length; j++ ) {
      buttons[i][j].setText(" ");
   }
}

0

如上面的答案已经提到,您不必像创建新实例那样操作。

new TicTacToe2()

所以,我将从那里继续。你的if语句应该是这样的

if (menusource == newgame) {
     getContentPane.removeAll();
     setContentPane(aFunc);
}

创建一个函数,类似下面的样子,它设置布局并添加组件到其中。在这里放置您的绘图逻辑,并将其作为参数传递给"setContent pane"。例如:
 private JPanel aFunc() {
    custSelectPanel.setLayout(null);

    customerTable.setDragEnabled(false);
    customerTable.setFillsViewportHeight(true);

    ......

    cancelButton.setLocation(350, 0);
    cancelButton.setSize(100, 40);
    buttonPanel.add(cancelButton);

    return custSelectPanel;
}

我希望你能理解这里的逻辑


你的建议听起来很昂贵。而且你是想将一个函数指针传递到setContentPane中吗? - Lews Therin
这要看情况 :), 如果你的需求只是重新初始化文本,那么其中一个答案已经有了,但如果你想重新绘制整个场景,那我认为这就是你必须做的事情。 - mu_sa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接