JTextArea/JTextComponent setText导致崩溃
我是Java的新手,尤其是Swing库。当我使用记事本演示(JDK的标准演示)进行实验时,在编辑器窗口中尝试更改文本时发生崩溃。我的示例代码:JTextArea/JTextComponent setText导致崩溃
void Filter(Component f){
if (f instanceof JTextComponent){
JTextComponent textComponent = (JTextComponent) f;
textComponent.setVisible(false); //Works
textComponent.setVisible(true); //Works
textComponent.getText(); //Works
textComponent.updateUI(); //Works
textComponent.setText("Hello world!"); //Crashes
}else{
RecursiveGet(f);
}
}
void RecursiveGet(Component c){
for (Component f : ((JComponent) c).getComponents()) {
if (f instanceof JComponent) {
Filter(f);
}
}
}
我搜索例如JTextComponent的,直到我找到它,然后测试了一些方法。我想我错过了一些东西,一些细节。我的环境JDK 1.7,JRE 7.0,Win7 x64。我会很高兴有任何帮助。谢谢。
更新 我添加异常处理程序
void Filter(Component f){
if (f instanceof JTextComponent){
JTextComponent textComponent = (JTextComponent) f;
textComponent.setVisible(false); //Work
textComponent.setVisible(true); //Work
textComponent.getText(); //Work
textComponent.updateUI(); //Work
try {
textComponent.setText("Hello world!"); //Crash
} catch (Exception e) {
e.printStackTrace();
}
}else{
RecursiveGet(f);
}
}
,并得到这个..
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.plaf.synth.SynthContext.getPainter(Unknown Source)
at javax.swing.plaf.synth.SynthTextAreaUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JViewport.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown S
ource)
at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent._paintImmediately(Unknown Source)
at javax.swing.JComponent.paintImmediately(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$700(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Sour
ce)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
更新2 的setText方法工作之后添加异常处理程序块。但是我想念什么?
这不是一个答案,但呈现出的代码后,你的方法,或者它的一个变种,一个允许编码器来改变张贴什么文本,工作原理:
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.text.*;
@SuppressWarnings("serial")
public class TestFilter extends JPanel {
public TestFilter() {
JPanel textFieldPanel = new JPanel(new GridLayout(0, 3));
for (int i = 0; i < 15; i++) {
textFieldPanel.add(new JTextField(10));
}
JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton(new FilterAction("Show Text", "Hello World")));
buttonPanel.add(new JButton(new FilterAction("Clear Text", "")));
setLayout(new BorderLayout());
add(textFieldPanel, BorderLayout.NORTH);
add(new JScrollPane(new JTextArea(10, 15)));
add(buttonPanel, BorderLayout.SOUTH);
}
private class FilterAction extends AbstractAction {
private String text;
public FilterAction(String name, String text) {
super(name);
this.text = text;
}
@Override
public void actionPerformed(ActionEvent e) {
filter(TestFilter.this, text);
}
}
void filter(Component f, String text) {
if (f instanceof JTextComponent) {
JTextComponent textComponent = (JTextComponent) f;
textComponent.setVisible(false); // Works
textComponent.setVisible(true); // Works
textComponent.getText(); // Works
textComponent.updateUI(); // Works
textComponent.setText(text); // Crashes
} else {
RecursiveGet(f, text);
}
}
void RecursiveGet(Component c, String text) {
for (Component f : ((JComponent) c).getComponents()) {
if (f instanceof JComponent) {
filter(f, text);
}
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("TestFilter");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new TestFilter());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
因此,问题是可能你打电话给你的方法,你还没有向我们显示。
根据您的原始问题的意见,
“[...]它的工作[S]在另一个线程,但【原文】线程启动[S]的所有对象创建后.. “
修改Swing组件的所有代码都必须在事件派发线程中运行。如果您一直等到创建完成,那还不够。
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
// modify swing components
}
});
根据堆栈跟踪,此异常*来自事件调度线程。 – 2012-07-13 17:48:43
在原始问题的评论中,他写道:“它在另一个线程中工作,但线程在所有对象创建后启动..” – lbalazscs 2012-07-13 18:05:06
有没有报告的任何错误? – Brainbot 2012-07-13 16:21:01
“crash”是什么意思?它是否会抛出异常?如果是,那是什么? – 2012-07-13 16:21:03
我的意思是记事本应用程序被冻结,不会回应我的操作。 – Darius 2012-07-13 16:23:40