问题描述
我一直在尝试解决.setText崩溃问题,该问题是在我随机按下num0
按钮时发生的.
I have been trying to fix my .setText crash issue, which occures when i press the num0
button randomly.
- 但是似乎我只能通过使用来解决它
new Thread(new Runnable() { __overwrite__swing__textfields___ });
,但在那种情况下,我无法访问我的JTextField
.
- But it seems i can only resolve it by using
new Thread(new Runnable() { __overwrite__swing__textfields___ });
but in that case i can not access myJTextField
.
因此,我编写了一个RunnableOutput
类来发送和应用,但帽子也失败了.示例:
Therefore i have written a RunnableOutput
class to send and apply but that also failing. Example:
RunnableOutput.java
RunnableOutput.java
package ui;
import java.awt.ComponentOrientation;
import javax.swing.*;
/**
* JTextField - Wrapper for thread-safe
*
* @author root
*/
public class RunnableOutput implements Runnable {
private JTextField outputArea;
private String messageToAppend;
// initialze outputArea and message
public RunnableOutput(JTextField output, String message) {
outputArea = output;
messageToAppend = message;
}
@Override
public void run() {
outputArea.setText(messageToAppend);
}
}
Menu.java:
Menu.java:
public static JTextField nameTextField0 = new JTextField(20);
public void IPpanel(JPanel configPanel) {
JPanel Numlock = new JPanel(new GridLayout(0,12));
JButton num0 = new JButton("0");
num0.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
// Fails:
// was expecting this should fixed it but indeed still not
SwingUtilities.invokeLater(
new RunnableOutput(nameTextField0, "Unit test: 0"));
// Fails:
// wont work few times works but when randomly i press the
// button it fails
// Same result with: SwingUtilities.invokeAndWait();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
nameTextField0.setText("Unit test: 1");
}
});
// Works: does not freez but does not change/apply the values
new Thread(new Runnable() {
Menu.nameTextField0.setText("Unit test: 2");
});
}
});
Numlock.add(num0);
configPanel.setLayout(new GridLayout(0,1));
configPanel.add(Numlock);
}
跟进:
- 使用了多态并修复了所有这些问题
推荐答案
1)您必须添加代码行
1) you have to add code lines
revalidate()
repaint();
在这种情况下,请将JComponents
添加到已经可见的Container
in the case(s) you add JComponents
to the already visible Container
2)必须在EventDispatschTread
上添加/删除已经可见的Container
中的JComponents
,应将其包装到invokeLater
/invokeAndWait
2) add/remove JComponents
from/to the already visible Container
must be done on EventDispatschTread
, should be wrapped into invokeLater
/ invokeAndWait
3)我建议包装(事件声明为Thread Safe
方法)setText()
,append()
到从Runnable#Thread
,Executor
或util.Timer
3) I'd suggest to wrapping (event are declared as Thread Safe
methods) setText()
, append()
into invokeLater
called from Runnable#Thread
, Executor
or util.Timer
4)使用SwingTimer(EDT上的保证输出)或Runnable#Thread(必须包装到invokeLater/invokeAndWait中)
5)对于Swing GUI来说,使用SwingWorker会更好,也许比带/或Executor/util.Timer的Runnable#Thread更好. /a>
5) for Swing GUI would be better to use SwingWorker, maybe better that Runnable#Thread with/or Executor/util.Timer
6)请勿阻止EDT
7)为更好的帮助而建议,请尽快使用 SSCCE
7) as adviced for better help sooner edit your question with a SSCCE
编辑
new Thread(new Runnable() {
public void run() {
final RunnableOutput a = new RunnableOutput();
if (SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
a.setText(nameTextField0, text);
}
});
} else {
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
a.setText(nameTextField0, text);
}
});
} catch (InterruptedException ex) {
Logger.getLogger(Menu.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(Menu.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}).start();
这篇关于如何不让setText崩溃/冻结我的整个应用程序?即使使用SwingUtilities和线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!