java - 什么会导致 Swing 应用程序不一致地抛出空指针异常?

标签 java swing

我有一个两类项目,一个类读取一个文件,并根据网站检查该文件中的每个条目,并将返回数据发布到另一个文件中。

如果返回数据为 true(例如),则文件中的数据点将在屏幕上闪烁。此功能有效。

我通过 while 循环中的以下 if 语句调用它。

if (!query.text().contains("unavailable") && !query.text().contains("at least 3 characters long to acquire.") && line != null) {

            HitBox h = new HitBox(line); //GUI Class.

            fos.write(query.text().getBytes());
            fos.write("\n".getBytes());

            fos.flush();

        }

下面是我的 GUI 类。

import java.awt.AlphaComposite;
import java.awt.Color;
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 java.io.IOException;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;

public class HitBox {
    private Timer t;
    JWindow frame = new JWindow();
    public HitBox(String s) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager
                            .getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                frame.setAlwaysOnTop(true);

                t = new Timer(1000 * 5, new ActionListener() {
                    public void actionPerformed(ActionEvent e2) {
                        SwingUtilities.getWindowAncestor(frame.getComponent(0))
                        .dispose();
                    }
                });

            }

        });
        frame.setBackground(new Color(0, 0, 0, 0));
        TranslucentPane tp = new TranslucentPane(s);
        frame.setContentPane(tp);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        t.start();

    }


}
class TranslucentPane extends JPanel {

    public TranslucentPane(String s) {
        add(new JLabel(s));
        setOpaque(false);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setComposite(AlphaComposite.SrcOver.derive(0.85f));
        g2d.setColor(getBackground());
        g2d.fillRect(0, 0, getWidth(), getHeight());


    }

}

使用相同的输入数据集会发生这种情况,即使我覆盖网络查询,并且只返回一个设置值,@运行时的随机点,将出现一个 JWindow,将抛出一个空指针(@我的调用我的计时器对象的启动方法)。

这让我相信我错误地实现了计时器;我对一致的数据和返回如何在抛出空指针的点上存在变化感兴趣。

Exception in thread "main" java.lang.NullPointerException
at HitBox.<init>(HitBox.java:51)
at OriginalGangster.main(OriginalGangster.java:38)

最佳答案

您没有在 GUI 线程上启动 GUI。您需要将其移至 Runnable 中,并确保它构建完成后启动计时器。

例如,

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.Timer;
import javax.swing.UIManager;

public class TestHitBox {
   public static void main(String[] args) {
      String text = "Hello world! This is Hovercraft!";
      int seconds = 5;
      float composite = 0.85f;
      float points = 48f;
      HitBox.showMessage(text, seconds, composite, points);
   }
}

class HitBox {

   public static void showMessage(final String text, final int seconds, final float composite, final float points) {
      EventQueue.invokeLater(new Runnable() {
         @Override
         public void run() {
            try {
               UIManager.setLookAndFeel(UIManager
                     .getSystemLookAndFeelClassName());
            } catch (Exception ex) {
               ex.printStackTrace();
            }
            final JWindow frame = new JWindow();
            frame.setBackground(new Color(0, 0, 0, 0));
            TranslucentPane tp = new TranslucentPane(text, composite, points);
            frame.setContentPane(tp);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);

            frame.setAlwaysOnTop(true);
            new Timer(1000 * seconds, new TimerListener(frame)).start();
         }
      });
   }
}

class TimerListener implements ActionListener {
   private JWindow frame;

   public TimerListener(JWindow frame) {
      this.frame = frame;
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      frame.dispose();
      ((Timer) e.getSource()).stop();
   }
}

@SuppressWarnings("serial")
class TranslucentPane extends JPanel {
   private float composite;

   public TranslucentPane(String s, float composite, float points) {
      this.composite = composite;
      JLabel label = new JLabel(s);
      label.setFont(label.getFont().deriveFont(Font.BOLD, points));
      add(label);
      setOpaque(false); // this breaks a rule
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g.create();
      g2d.setComposite(AlphaComposite.SrcOver.derive(composite));
      g2d.setColor(getBackground());
      g2d.fillRect(0, 0, getWidth(), getHeight());
      g2d.dispose(); // dispose of any graphics we create
   }
}
<小时/>

代码已更新。

  • 主要代码已移至公共(public)静态方法,因为这似乎是向用户显示消息而不与任何其他代码共享状态的代码,类似于 JOptionPane 消息,所以我将其制作为行为类似于 JOptionPane。
  • 为了简洁起见,计时器的 ActionListener 已从构造函数中移出。
  • 添加了 Alpha 合成、显示时间和消息字体点大小的参数。

关于java - 什么会导致 Swing 应用程序不一致地抛出空指针异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29736560/

相关文章:

java - Swing 应用程序连续运行约 6 小时后变得无响应

java - 如何使 vector 线可选?

java - 用于制作代码编辑器的 JSyntaxPane 的 JavaFX 等价物是什么?

java - 矩形边框 Java

java - Spring 事务参数化测试和 Autowiring

java - 从 viewpager 切换选项卡

java - 如何从 Web 存档的 WEB-INF 目录加载资源

java - 为什么我的 Spring 应用程序无法识别有人已经登录?

java - JTable 中的 JButton 图标/动画在按下时改变

java - 有没有办法确定文件夹是否是众所周知的文件夹?