当前位置: 首页 > 知识库问答 >
问题:

JFrame不可关闭,尽管有frame。setDefaultCloseOperation()

章承
2023-03-14

我遇到了一个问题,面板没有加载到JFrame中,JFrame本身没有设置默认的关闭操作,而是执行setSize()和setVisible()。我尝试过在main、run()方法和框架的构造函数中运行框架初始化,但没有区别。MouseListener似乎不起作用,但如果不将面板添加到框架中,就无法确定这一点。我发布这个问题的主要目的是在点击x时关闭框架,并再次将面板添加到框架中。我确信这在游戏状态下不是问题。buffer()或gameStae。油漆(g)。这是一款名为《当猪飞翔》的电子游戏。以下是代码:

主要类别:

package when.pigs.fly;

public class Main {
    static Frame frame;
    public static void main(String[] args) {
        frame=new Frame();
        frame.panel.run();
    }
}

框架类:

package when.pigs.fly;

import javax.swing.JFrame;

public class Frame extends JFrame{
    Panel panel;
    int windowWidth,windowHeight;
    public Frame(){
        super("When Pigs Fly");
        
        panel=new Panel();
        panel.setListeners();
        
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(1000,600);
        buffer();
        
        add(panel);
        setVisible(true);
    }
    
    public final void buffer(){
        windowWidth=getContentPane().getWidth();
        windowHeight=getContentPane().getHeight();
    }
}

面板类:

package when.pigs.fly;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JPanel;
import static when.pigs.fly.GameState.gameState;
import static when.pigs.fly.Main.frame;

public class Panel extends JPanel implements MouseListener,MouseMotionListener{
    private long timeElapsed;
    int mouseX,mouseY;
    boolean mouseDown;
    
    public Panel(){
        gameState=new GameState(1);
    }
    
    public final void setListeners(){
        addMouseListener(this);
        addMouseMotionListener(this);
    }
    
    public void run(){
        boolean run=true;
        while(run){
            long timeAtStart=System.nanoTime();
            
            if(timeElapsed>=33333333){
                gameState.buffer();
                frame.buffer();
                timeElapsed-=33333333;
            }
            repaint();
            
            timeElapsed+=System.nanoTime()-timeAtStart;
        }
    }
    
    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        gameState.paint((Graphics2D)g);
    }
    
    @Override
    public void mouseClicked(MouseEvent me) {
        
    }

    @Override
    public void mousePressed(MouseEvent me) {
        mouseDown=true;
    }

    @Override
    public void mouseReleased(MouseEvent me) {
        mouseDown=false;
    }

    @Override
    public void mouseEntered(MouseEvent me) {}

    @Override
    public void mouseExited(MouseEvent me) {}

    @Override
    public void mouseDragged(MouseEvent me) {
        mouseX=me.getX();
        mouseY=me.getY();
    }

    @Override
    public void mouseMoved(MouseEvent me) {
        mouseX=me.getX();
        mouseY=me.getY();
    }

}

共有1个答案

苏俊友
2023-03-14

怀疑无处不在,但根据您的描述,我怀疑您的run方法正在阻止事件调度线程。

Swing是单线程,不是线程安全的。这意味着您不应该在事件调度线程的上下文中运行长时间运行或阻塞代码,也不应该更新事件调度线程外部UI依赖的UI或任何状态。

有关更多详细信息,请参阅Swing中的并发。

一个简单的解决方案是使用SwingTimer,例如...

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Timer timer;
        private int mouseX, mouseY;
        private boolean mouseDown;

        public TestPane() {
            MouseHandler handler = new MouseHandler();
            addMouseListener(handler);
            addMouseMotionListener(handler);
        }

        protected void start() {
            if (timer != null) {
                return;
            }
            timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // Check input
                    // Update game state
                    repaint();
                }
            });
            timer.start();
        }

        protected void stop() {
            if (timer == null) {
                return;
            }
            timer.stop();
            timer = null;
        }

        @Override
        public void addNotify() {
            super.addNotify();
            start();
        }

        @Override
        public void removeNotify() {
            super.removeNotify();
            stop();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(1000, 600);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            int dotSize = 6;
            if (mouseDown) {
                g2d.setColor(Color.RED);
                g2d.fillOval(mouseX - dotSize, mouseY - dotSize, dotSize * 2, dotSize * 2);
            } else {
                g2d.setColor(Color.BLACK);
                g2d.drawOval(mouseX - dotSize, mouseY - dotSize, dotSize * 2, dotSize * 2);
            }
            g2d.dispose();
        }

        protected class MouseHandler extends MouseAdapter {

            @Override
            public void mousePressed(MouseEvent me) {
                mouseDown = true;
            }

            @Override
            public void mouseReleased(MouseEvent me) {
                mouseDown = false;
            }

            @Override
            public void mouseDragged(MouseEvent me) {
                mouseX = me.getX();
                mouseY = me.getY();
            }

            @Override
            public void mouseMoved(MouseEvent me) {
                mouseX = me.getX();
                mouseY = me.getY();
            }
        }

    }
}
 类似资料:
  • 问题内容: 关键字在Google Go中是什么意思? 问题答案: 2017更新 :解析器进行了重大更新,新的解析器似乎不再支持这些复活节彩蛋字眼。 对我来说,看起来像是一个复活节彩蛋: https://github.com/golang/go/blob/08e25fc1ba397e02ec776561ed73b7f9a8b94392/src/cmd/compile/internal/gc/lex.

  • 问题内容: 我想同时显示两个(或更多) JFrame 。 当我关闭其中一个(使用默认的关闭按钮)时,其他框架仍应可见。 我怎样才能做到这一点? 问题答案: 如果您 不 希望应用程序在a 关闭时终止,请使用 代替 从文档中: (在WindowConstants中定义):不执行任何操作;要求程序处理注册的WindowListener对象的windowClosing方法中的操作。 (在WindowCon

  • 问题内容: 我想知道是否有一种方法,通过单击“ X”,让程序在关闭JFrame之前执行一些代码。该方法仅使用整数。 问题答案: 您可能对使用感兴趣。本教程。

  • 我有一个带有登录名(JPanel)的JFrame,可以从菜单栏中选择。菜单栏还根据用户角色显示选项。当用户第一次登录创建的JFrame实例时,当我在菜单栏上选择login并在new JFrame上实例化时,我的问题就出现了,因为我显然打开了两个JFrame,我找不到从JPanel隐藏或关闭之前JFrame的方法。在实例化新JFrame或任何其他可能的解决方案之前,有没有办法隐藏/处理所有打开的窗口

  • 我正在做一个实验2D物理的个人项目。现在,我正在尝试设置JFrame,以便它每秒更新60次。但是,当我调用方法开始更新JFrame时,我不能关闭JFrame。但是如果我省略了调用方法的部分,我可以关闭JFrame。这是主要代码: 这是Frame的代码: 如果我不在start()中调用updater(),我可以关闭JFrame。我知道我离开running=true,但它仍然应该关闭,因为这在我的旧计

  • 我有一个Jframe窗口,里面有一个按钮。通过单击该按钮,它将打开一个新的JFrame窗口。但是当我关闭这个窗口时,它会自动用按钮关闭第一个Jframe窗口。当我关闭第二个Jframe窗口时,如何防止第一个Jframe窗口关闭?