2012-07-13 68 views
5

我是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方法工作之后添加异常处理程序块。但是我想念什么?

+0

有没有报告的任何错误? – Brainbot 2012-07-13 16:21:01

+2

“crash”是什么意思?它是否会抛出异常?如果是,那是什么? – 2012-07-13 16:21:03

+0

我的意思是记事本应用程序被冻结,不会回应我的操作。 – Darius 2012-07-13 16:23:40

回答

4

这不是一个答案,但呈现出的代码后,你的方法,或者它的一个变种,一个允许编码器来改变张贴什么文本,工作原理:

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(); 
     } 
     }); 
    } 
} 

因此,问题是可能你打电话给你的方法,你还没有向我们显示。

+0

好吧,我尝试显示所有的代码,但不要责怪我)正如我说的实验。 – Darius 2012-07-13 17:01:36

+0

+1,用于发布可运行代码,并显示'setText'实际工作:-) @Darius否,不显示所有代码。发布一个证明你的问题的[SSCCE](http://sscce.org)。 – Robin 2012-07-13 17:05:38

2

根据您的原始问题的意见,

“[...]它的工作[S]在另一个线程,但【原文】线程启动[S]的所有对象创建后.. “

修改Swing组件的所有代码都必须在事件派发线程中运行。如果您一直等到创建完成,那还不够。

java.awt.EventQueue.invokeLater(new Runnable() { 
    public void run() { 
     // modify swing components 
    } 
}); 

您可能需要阅读此:Java Event-Dispatching Thread explanation

...这:Java: Swing Libraries & Thread Safety

+0

根据堆栈跟踪,此异常*来自事件调度线程。 – 2012-07-13 17:48:43

+1

在原始问题的评论中,他写道:“它在另一个线程中工作,但线程在所有对象创建后启动..” – lbalazscs 2012-07-13 18:05:06