Java JFrame未响应setVisible()和dispose()

Java JFrame未响应setVisible()和dispose(),java,swing,netbeans,jframe,Java,Swing,Netbeans,Jframe,我正在制作一个“蛇”游戏作为家庭作业,我花了几个小时搜索了所有可能的方法来关闭JFrame,没有任何结论。我开始创建一个带有背景图像和菜单的JFrame,仅此而已。当我点击“开始游戏”按钮(JMenuItem)时,它会打开一个新的JFrame,其中有一个线程来玩游戏。我的问题是第一个JFrame无论如何都不会关闭。我尝试使用解决方案,但JFrame仍然存在。看起来他听的唯一命令是作为DefaultCloseOperation的“EXIT_ON_CLOSE”,而不是“DISPOSE_ON_CLOS

我正在制作一个“蛇”游戏作为家庭作业,我花了几个小时搜索了所有可能的方法来关闭JFrame,没有任何结论。我开始创建一个带有背景图像和菜单的JFrame,仅此而已。当我点击“开始游戏”按钮(JMenuItem)时,它会打开一个新的JFrame,其中有一个线程来玩游戏。我的问题是第一个JFrame无论如何都不会关闭。我尝试使用解决方案,但JFrame仍然存在。看起来他听的唯一命令是作为DefaultCloseOperation的“EXIT_ON_CLOSE”,而不是“DISPOSE_ON_CLOSE”。这是我的蛇架课程:

package snake;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

/**
 *
 * @author Giacomo
 */
public class SnakeFrame extends Snake{

    protected JMenuItem start = new JMenuItem("Start game");

    public void pullThePlug(final SnakeFrame frame) {

  /*// this will make sure WindowListener.windowClosing() et al. will be called.
        WindowEvent wev = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
        Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
       // this will hide and dispose the frame, so that the application quits by
        // itself if there is nothing else around. 
        frame.setVisible(false);
        frame.dispose();*/


        frame.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentHidden(ComponentEvent e) {

                ((JFrame)(e.getComponent())).dispose();
            }
        });
    }

    public int game(final SnakeFrame frame,final JFrame gameFrame){

        short game_ok=0;

        try{
            start.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    GameThread gamethread = new GameThread(frame,gameFrame);
                    gamethread.start();

                    pullThePlug(frame);

                }
            });
        }
        catch(Exception e){
            game_ok=1;
        }


        return game_ok;
    }

//-----------Frame initialization with relative Listeners and Events.---------\\
    public SnakeFrame(){

            JFrame frame= new JFrame("Le Snake");
            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            double larghezza = screenSize.getWidth();
            double altezza = screenSize.getHeight();
            frame.setBounds(((int)larghezza/4),((int)altezza/4),800, 600);
            frame.setVisible(true);
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            ImageIcon icon = new ImageIcon("C:\\Users\\Giacomo\\Documents"
            + "\\NetBeansProjects\\Snake\\src\\res\\Snake-icon.png");
            frame.setIconImage(icon.getImage());
            frame.setResizable(false);
            frame.setLayout(new GridLayout());

            JMenuBar menuBar = new JMenuBar();
            JMenu menu = new JMenu("Menu");
            menuBar.add(menu);
            menuBar.setBounds(1, 1, frame.getWidth(),frame.getHeight()/25);
            JMenuItem close = new JMenuItem("Exit");

            close.addActionListener(new ActionListener(){

                @Override
                public void actionPerformed(ActionEvent e) {

                    System.exit(0);
                }
            });

            menu.add(start);
            menu.add(close);
            frame.setJMenuBar(menuBar);

            try {
            frame.setContentPane(new JLabel(new ImageIcon(ImageIO.read
                (new File("C:\\Users\\Giacomo\\Documents\\NetBeansProjects\\"
                        + "Snake\\src\\res\\default.png")))));
            } catch (IOException e) {
                System.out.println("Exception with the background image.");
            }

            frame.pack();

        }
//-------------------------Frame initialization ended.-----------------------\\

}
以下是游戏线程的代码(目前):

这是蛇框类(“固定”):

公共类SnakeFrame扩展Snake{
私有最终JMenuItem开始=新JMenuItem(“开始游戏”);
私人最终背景小组;
公共智力游戏(最终蛇框){
短游戏_ok=0;
试一试{
start.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
defaultpanel.setVisible(false);
JPanel面板=新的JPanel();
JLabel[]griglia=新JLabel[50][50];
面板设置布局(新网格布局(50,50));
对于(int i=0;i一些一般性意见:

  • 为什么要创建第二个框架?通常游戏是在自己的框架中进行的?您有一个菜单,允许您更改游戏选项,这是通过显示一个模态JDialog来完成的。然后您有一个“开始”按钮,通过在现有框架中添加一个面板来启动游戏

  • 不要在框架上使用ComponentListener。不需要处理componentHidden

  • 为什么你有
    游戏()
    method?我甚至看不到在您的代码中调用该方法的地方。只需将actionListener添加到类构造函数的开始菜单项中。将菜单项的创建和actionListener的赋值保持在同一代码块中,这样我们就不需要在类中查找所有相关属性组成部分

  • 当我点击“开始游戏”按钮(JMenuItem)时,它会打开一个新的JFrame,其中有一个线程来玩游戏

    这是错误的。您不应该启动单独的线程。所有Swing组件都应该在事件分派线程(EDT)上创建。因此,基本上,应该从ActionListener中调用代码,因为所有事件代码都在EDT上执行

    看起来他听的唯一命令是作为DefaultCloseOperation的“EXIT_ON_CLOSE”,而不是“DISPOSE_ON_CLOSE”

    这些是您为框架设置的属性。然后,当用户单击框架顶部/右侧的“X”按钮时,框架将根据属性关闭。直接调用frame.dispose()或System.exit()时,这些属性无效

    GameThread gamethread = new GameThread(frame,gameFrame);
    
    为什么要将框架传递给其他类?如果你的目标是关闭原始框架,那么在创建其他框架后在此处关闭框架。事实上,为什么你甚至在此处引用“gameFrame”。如果你有其他类创建框架的组件,它也应该创建框架

    pullThePlug(frame);
    
    此代码不执行任何操作。您在尝试关闭框架后正在调用此方法


    一般来说,我无法遵循您的逻辑,因为代码不完整。但是,作为一般规则,应用程序应该只包含一个JFrame。隐藏/显示多个帧不是用户希望看到的体验。当新游戏开始时,您应该刷新现有帧的内容窗格。

    对不起,我很清楚,这是“障碍”eframe“”关闭时遇到问题?能否添加Snake类的源代码?@MrB是的,我关闭时遇到问题的是snakeframe,它只是一个简单的JFrame,根据我的需要使用边界和背景进行初始化。@ulix Snake类的源代码是我,我使它更容易初始化,并使该框架的内容保持一致。我决定创建一个新的JFrame,因为我无法以任何方式更改JFrame的背景。我尝试的一切都没有效果,所以我只是想:“既然我无法更改背景,我将创建一个没有背景的新JFrame”.无论如何,谢谢你的帮助,我会尝试修复上面突出显示的所有内容。@ServantGrunt,
    我无法以任何方式更改JFrame的背景
    -当然你可以更改背景。请查看几种方法。我刚刚意识到,可能我无法更改它,因为我没有将该背景设置为面板的背景but作为框架的背景?JFrame的“内容窗格”是一个JPanel,因此如果要更改背景颜色,需要更改“内容窗格”的颜色,不是框架。与图像相同。您将图像添加到内容窗格中。谢谢,这在我的脑海中并不完全清楚。我现在的问题是它说它无法读取文件。我这样做了:BackgroundPanel defaultpanel;image background=null;尝试{background=ImageIO.read(新文件(“/src/res/default.png”));}catch(IOException ex){Logger.getLogger(SnakeFrame.class.getName()).log(Level.SEVERE,null,ex);}defaultpanel=newbackgroundpanel(BackgroundPanel,BackgroundPanel.ACTUAL,1.0f,0.5f);你知道它为什么不能读取它吗?即使用“\\”代替“/”也不起作用。
    public class SnakeFrame extends Snake{
    
        private final JMenuItem start = new JMenuItem("Start game");
        private final BackgroundPanel defaultpanel;
    
        public int game(final SnakeFrame frame){
    
            short game_ok=0;
    
            try{
                start.addActionListener(new ActionListener() {
    
                    @Override
                    public void actionPerformed(ActionEvent e) {
    
                        defaultpanel.setVisible(false);
                        JPanel panel = new JPanel();
                        JLabel[][] griglia = new JLabel[50][50];
                        panel.setLayout(new GridLayout(50,50));
    
                    for(int i=0;i<50;i++){
                        for(int j=0;j<50;j++){
                            griglia[i][j] = new JLabel();
                            griglia[i][j].setBackground(Color.BLACK);
                            panel.add(griglia[i][j]);
                        }
                    } 
                    frame.add(panel);
                    griglia[45][30].setIcon(new ImageIcon
                            ("src\\res\\sneikhead.png"));
                    panel.setVisible(true);
                    }
                });
            }
            catch(Exception e){
                game_ok=1;
            }
    
            return game_ok;
        }
    
    //-----------Frame initialization with relative Listeners and Events.---------\\
        public SnakeFrame(){
    
                JFrame frame= new JFrame("Le Snake");
                ImageIcon imm = new ImageIcon(getClass().getResource
            ("/res/default.png"));
                Image background = imm.getImage();
                defaultpanel = new BackgroundPanel(background, BackgroundPanel.ACTUAL,
                        1.0f, 0.5f);
                frame.add(defaultpanel);
                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
                double larghezza = screenSize.getWidth();
                double altezza = screenSize.getHeight();
                frame.setBounds(((int)larghezza/4),((int)altezza/4),800, 600);
                frame.setVisible(true);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                ImageIcon imageIcon = new ImageIcon(getClass().getResource("/res/Snake-icon.png"));
                Image icon = imageIcon.getImage();
                frame.setIconImage(icon);
                frame.setResizable(false);
                frame.setLayout(new GridLayout());
                JMenuBar menuBar = new JMenuBar();
                JMenu menu = new JMenu("Menu");
                menuBar.add(menu);
                menuBar.setBounds(1, 1, frame.getWidth(),frame.getHeight()/25);
                JMenuItem close = new JMenuItem("Exit");
    
                close.addActionListener(new ActionListener(){
    
                    @Override
                    public void actionPerformed(ActionEvent e) {
    
                        System.exit(0);
                    }
                });
    
                menu.add(start);
                menu.add(close);
                frame.setJMenuBar(menuBar);
    
                frame.pack();
    
            }
    //-------------------------Frame initialization ended.-----------------------\\
    
    }
    
    GameThread gamethread = new GameThread(frame,gameFrame);
    
    pullThePlug(frame);