2012-07-13 56 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