jFrames被这段代码冻结了吗? (附代码):Netbeans 8.2
Posted
技术标签:
【中文标题】jFrames被这段代码冻结了吗? (附代码):Netbeans 8.2【英文标题】:jFrames are got freeze by this code? (code attached) : Netbeans 8.2 【发布时间】:2017-07-12 16:31:17 【问题描述】:我在我的 Java 应用程序中遇到一个问题,当通过单击 jButton 打开新的 jFrames 时,会出现一点点冻结并在其打开后(冻结时间 1-2 分钟/3 分钟)。我还找不到发生了什么问题。但我对以下附加代码有一些疑问。该代码用于获取系统时间和日期并显示所有 jFrames。所以这段代码在所有的jFrames中。现在我的问题是,这段代码是否发生了这种冻结..?或者可能有任何其他原因..?如果这段代码有任何错误,请告诉我……我正在使用 NETbeans 8.2。提前致谢。
代码:
public AdminHome()
initComponents();
new Thread(new Runnable()
@Override
public void run()
while (true)
Date d=new Date();
SimpleDateFormat sd=new SimpleDateFormat("yyyy - MM - dd");
String s = sd.format(d);
String s1 = d.toString();
String ar[]=s1.split(" ");
jLbl_Date.setText(s);
jLbl_Time.setText(ar[3]);
).start();
【问题讨论】:
【参考方案1】:您可能创建了一个单独的线程,但所有 UI 更新都源于 AWT 线程。因此,该线程非常频繁地调用jLbl_date.setText()
和jLbl_time.setText()
方法实际上直接阻塞了AWT 线程。
尝试在jLbl_Time.setText()
之后添加sleep(1000)
。
【讨论】:
另外,setText
调用应该是SwingUtilities.InvokeLater
ed。
是的,如果我错了,请纠正我,但 AWT 不会像 JavaFX 那样限制多线程 UI 访问。
@Subhranil,tnx 为您解答。我试过你现在说的。但它显示错误。请你可以在这里修改我的代码和评论...?它对我很有用。
JLabel 是 Swing,不应被除事件调度线程之外的任何线程修改。
你好@Colin__s,你说答案我没听懂。请您解释一下修改我的代码...?它对我更有帮助。我只是java的初学者...【参考方案2】:
这两个调用:
jLbl_Date.setText(s);
jLbl_Time.setText(ar[3]);
必须在 EDT(事件调度线程)上发生,因为必须从 EDT 操作 GUI 组件。您可以使用 SwingUtilities
将它们包装在 EDT 上:
SwingUtilities.invokeLater(() ->
Date d=new Date();
SimpleDateFormat sd=new SimpleDateFormat("yyyy - MM - dd");
String s = sd.format(d);
String s1 = d.toString();
String ar[]=s1.split(" ");
jLbl_Date.setText(s);
jLbl_Time.setText(ar[3]);
);
但是,问题仍然存在。由于您的线程在更新标签之间不会休眠,因此您将使用更新请求淹没 EDT,从而导致您的 GUI 再次冻结。您可以通过在更新标签后添加 Thread.sleep(1000);
来解决此问题。
更优雅的方法是使用摇摆计时器而不是线程:
Timer timer = new Timer(1000, new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
Date d=new Date();
SimpleDateFormat sd=new SimpleDateFormat("yyyy - MM - dd");
String s = sd.format(d);
String s1 = d.toString();
String ar[]=s1.split(" ");
jLbl_Date.setText(s);
jLbl_Time.setText(ar[3]);
);
timer.setInitialDelay(0);
timer.start();
摆动计时器负责确保在 EDT 上执行带有 actionPerformed
方法的代码。它还有一个额外的优势,它可以在需要时合并事件 - 另一个机制来防止事件淹没 EDT。
【讨论】:
你打败了我! +1【参考方案3】:您似乎创建了一个线程来运行无限循环来更新某些日期和时间字段。这不是实现您想要做的事情的好方法。
更好的解决方案是使用具有较短间隔的javax.swing.Timer
,并从附加的操作侦听器更新您的 UI。
ActionListener timerListener = new ActionListener
public void actionPerformed(ActionEvent e)
Date d=new Date();
SimpleDateFormat sd=new SimpleDateFormat("yyyy - MM - dd");
String s = sd.format(d);
String s1 = d.toString();
String ar[]=s1.split(" ");
jLbl_Date.setText(s);
jLbl_Time.setText(ar[3]);
;
Timer t = new javax.swing.timer(1000, timerListener).start();
类似上面的东西应该可以解决问题。这为您省去了跨越线程边界来更新 UI 的麻烦,并且与您之前的解决方案相比,将大大减少 CPU 负载。
【讨论】:
我添加了你的代码。但是出错了,这个jframe也没有运行......它说“没有主要方法”在这里附加了你在我的代码中的代码: 公共 AdminStudent() initComponents(); ActionListener timerListener = new ActionListener public void actionPerformed(ActionEvent e) Date d=new Date(); SimpleDateFormat sd=new SimpleDateFormat("yyyy - MM - dd");字符串 s = sd.format(d);字符串 s1 = d.toString();字符串 ar[]=s1.split(" "); jLbl_Date.setText(s); jLbl_Time.setText(ar[3]); 定时器 t = new javax.swing.timer(1000, timerListener).start(); 我错过了动作监听器末尾的;
以上是关于jFrames被这段代码冻结了吗? (附代码):Netbeans 8.2的主要内容,如果未能解决你的问题,请参考以下文章
5年老Android面试竟然被这3道Android基础题难倒了,附大厂真题面经