首页 > 解决方案 > JFrame/Panel 停止实例化/构造函数调用

问题描述

这是我昨天发现的一个错误,从那时起就很难真正描述它。

错误本身从 main 方法开始:

public static void main(String[] args) {
        new LogManager();
        new ConfigManager();
        new Rendering();
        new ScriptManager();
        new FileManager();
        new SleepManager(System.currentTimeMillis()); <-- Here it is as if the JVM just stops reading code

由于我使用 eclipse,所以我使用断点来定位有问题的行。它实际上到达了最后一行(new SleepManager),但从未到达 SleepManager 构造函数的方法断点:

public SleepManager(long t) {
        lastCheck = t;

类中只有一个构造函数。此外,也不例外。但最终我设法将其缩小到渲染类中的 JFramework:

public class Rendering extends JPanel implements Runnable {
   private static final Log LOG = new Log(Rendering.class.getSimpleName());
   private static GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0];

   public Rendering() {

        //define basics
        systemFullScreen_width = device.getDisplayMode().getWidth();
        systemFullScreen_height = device.getDisplayMode().getHeight();
        width = (systemFullScreen_width > 0 ? systemFullScreen_width : width);
        height = (systemFullScreen_height > 0 ? systemFullScreen_height : height);

        //crate framework
        frame = new JFrame();
        frame.addWindowListener(new FrameClose());
        frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        frame.setSize(width, height);
        frame.setUndecorated(true);
        frame.setBackground(new Color(0.0f,0.0f,0.0f,0.5f));
        frame.setVisible(true);
        frame.setTitle(" Monitor ");
        frame.setResizable(false);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setLocationRelativeTo(null);
        frame.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Collections.<AWTKeyStroke> emptySet()); //TODO remove if not needed
        panel = this;
        panel.setSize(width, height);
        panel.setBackground(new Color(0.4f,0.4f,0.4f,0.9f));

    --> frame.add(panel, 0); //here i suspect the error

        panel.revalidate();
        panel.setVisible(true);

        //start rendering
        this.start();

        //frame.setAlwaysOnTop(true); //TODO enable at the end
        
        //set input listeners
        frame.addKeyListener(input);
        frame.addMouseListener(input);
        frame.addMouseMotionListener(input);
        frame.addMouseWheelListener(input);
        LOG.info("Rendering started!");
    }

好的,所以我在该方法中实际完成的工作(因为它在我编写它时工作并且透明灰色背景仍在工作/可见)是我尝试创建一个半透明半全屏灰色背景以稍后渲染我自己的 GUI它上面的元素又名 Graphics2D。在解决全屏/透明度/轻量级容器问题时遇到了困难,但如果有人有更好的解决方案,仍然可以打开它们。

因此,标记的 line( frame.add(panel, 0);) 似乎是问题所在,因为当我删除该行时它会起作用(就这么简单),而且它似乎是唯一这样做的行。

panel.revalidate();是我的第一个想法它没有帮助,喷气机我还是决定保留它。

无法理解为什么运行时已经完成的那一行应该阻止另一种方法,200 行以下的方法被调用?有任何想法吗?


Edit1: 感谢 Matt 指出这些代码行确实对这个主题很重要:

   public void render(Graphics2D g2d){
        while(isRunning){
            renderGUI(g2d); //this method does nothing jet its empty
        }
        frame.dispose();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        render((Graphics2D) g);
    }

    @Override
    public void run() {
        while(isRunning){
            try{
                frame.repaint();
                Thread.sleep(5);
            }catch(Exception e){
                LOG.error(e);
            }
        }
    } 

编辑2:

究竟是什么让我找到了解决方案:Matt 提到了我不知道的“ EDT ”,所以我用谷歌搜索并了解了Event Dispatch Thread是什么。所以现在我知道,在this.start开始调用线程之前,EDT 实际上在某个时候首先调用了该paintComponent方法并进入了这个我完全忽略的丑陋的子代码双循环概念。老实说……真为我感到羞耻。谢谢马特。

标签: javaswingjframejpanel

解决方案


推荐阅读