尽管frage.setDefaultCloseperation()

发布于 2025-01-28 18:57:19 字数 2949 浏览 2 评论 0原文

我遇到了一个问题,即面板不加载jframe,而jframe本身也没有设置默认关闭操作,而是执行setSize()和setVisible()。我尝试在Main,run()方法和帧的构造函数中运行帧初始化,没有区别。 MouseListeners似乎没有功能,但是如果没有将面板添加到框架中,就无法确定知道,这不是。我发布此问题的主要目标是在单击X时使框架关闭,并将面板再次添加到框架中。我敢肯定,在gamestate.buffer()或gamestae.paint(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();
    }

}

I am having a problem where the panel doesn't load in the JFrame and the JFrame itself doesn't set the default close operation, but performs setSize() and setVisible(). I have tried running the frame initialization in main, in the run() method, and in the frame's constructor and there is no difference. The MouseListeners don't seem to be functional, but there's no way to know for sure without the panel being added to the frame, which it isn't. My main goals of posting this question are to get the Frame to close when you click on the x, and to get the panel to be added to the frame again. I'm certain it is not a problem in gameState.buffer() or gameStae.paint(g). It's for a video game called When Pigs Fly. Here is the code:

Main class:

package when.pigs.fly;

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

Frame class:

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();
    }
}

Panel class:

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();
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我不会写诗 2025-02-04 18:57:19

怀疑比比皆是,但我怀疑,根据您的描述,您的运行方法正在阻止事件派遣线程。

秋千是单线螺纹,而不是线程安全。这意味着您不应在事件派发线程的上下文中长时间运行或阻止代码,并且您不应更新UI或UI依赖于事件派遣线程的任何状态。

参见 Swing 同意的同意。

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

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();
            }
        }

    }
}

Suspicion abounds, but I suspect, based on your description, your run method is blocking the Event Dispatching Thread.

Swing is single thread and NOT thread safe. This means that you should not run long running or blocking code with in the context of the Event Dispatching Thread and you shouldn't update the UI or any state the UI relies on out side of the Event Dispatching Thread.

See Concurrency in Swing for more details.

A simple solution would be to use a Swing Timer, for example...

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();
            }
        }

    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文