2012-07-13 19 views
5

Sono nuovo di Java in generale e in particolare con la libreria Swing. Quando ho sperimentato la demo di Notepad (demo standard di JDK), ho avuto un arresto anomalo durante il tentativo di cambiare il testo nella finestra dell'editor. Il mio codice di esempio:JTextArea/JTextComponent setText causa crash

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

ho cercato per esempio JTextComponent, fino a quando ho trovato e poi provato alcuni metodi. Penso che mi manchi qualcosa, alcuni dettagli. Il mio ambiente JDK 1.7, JRE 7.0, Win7 x64. Sarò felice di avere qualche aiuto. Grazie.

Aggiornamento aggiungo gestore di eccezioni

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

e ottenere questo ..

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) 

Update 2 metodo setText lavoro dopo aggiungere blocco gestore di eccezioni. Ma cosa mi manca?

+0

ci sono errori segnalati? – Brainbot

+2

Cosa intendi per "crash"? Fa un'eccezione? Se sì, che cos'è? –

+0

Voglio dire che l'applicazione Blocco note è stata congelata e non risponderà alla mia manipolazione. – Darius

risposta

4

Questa non è una risposta, ma un post di codice che mostra che il metodo o una variante di esso, quella che consente al programmatore di cambiare il testo da inviare, funziona:

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

Così il problema è probabilmente come stai chiamando il tuo metodo, qualcosa che non ci hai ancora mostrato.

+0

Ok, provo a mostrare tutto il codice ma non incolpare me) Come dico il suo esperimento. – Darius

+0

+1 per lo sforzo di pubblicare codice eseguibile e mostrare che 'setText' funziona davvero :-) @Darius no, non mostrare tutto il codice. Pubblica un [SSCCE] (http://sscce.org) che dimostra il tuo problema. – Robin

2

Secondo i commenti sul tua domanda iniziale,

"[...] mi [s] in un altro thread, ma [l'originale] inizio della discussione [s] dopo che tutti gli oggetti creati .. "

Tutto il codice che modifica un componente Swing deve essere eseguito nel thread di invio evento. NON è sufficiente se aspetti che tutto venga creato.

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

Si potrebbe desiderare di leggere questo: Java Event-Dispatching Thread explanation

... e questo: Java: Swing Libraries & Thread Safety

+0

In base allo stack trace, questa eccezione * è * proveniente dal thread di invio dell'evento. –

+1

Nei commenti della domanda originale, ha scritto: "E funziona in un altro thread, ma il thread inizia dopo che tutti gli oggetti sono stati creati .." – lbalazscs

Problemi correlati