2012-07-13 13 views
5

Soy nuevo en Java en general y, en particular, en la biblioteca Swing. Cuando experimenté con la demo del Bloc de notas (demostración estándar de JDK), tuve un bloqueo al intentar cambiar el texto en la ventana del editor. Mi código de ejemplo:JTextArea/JTextComponent setText provoca 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); 
    } 
    } 
} 

me buscó por ejemplo JTextComponent, hasta que me encontré con él y luego probado algunos métodos. Creo que me falta algo, algunos detalles. Mi entorno JDK 1.7, JRE 7.0, Win7 x64. Estaré contento de tener alguna ayuda. Gracias.

actualización agrego gestor de excepciones

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

y obtén esta ..

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) 

Actualización 2 método de trabajo setText después de añadir el bloque de gestión de excepciones. Pero, ¿qué extraño?

+0

¿Hay errores detectados? – Brainbot

+2

¿Qué quieres decir con 'crash'? ¿Lanza una excepción? ¿Y si si, que? –

+0

Quiero decir que la aplicación Notepad se congeló y no responde a mi manipulación. – Darius

Respuesta

4

Esta no es una respuesta, pero una entrada de código que muestra que su método, o una variante de la misma, que permite que el codificador para cambiar lo que el texto para enviar, funciona:

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

Así, el problema es es probable que estés llamando a tu método, algo que aún no nos has mostrado.

+0

Ok, intento mostrar todo el código, pero no me culpen) Como digo su experimento. – Darius

+0

+1 por el esfuerzo de publicar código ejecutable, y mostrar que 'setText' realmente funciona :-) @Darius no, no muestra todo el código. Publique un [SSCCE] (http://sscce.org) que demuestre su problema. – Robin

2

De acuerdo con los comentarios sobre su pregunta original,

"[...] que funcione [s] en otro hilo, pero el comienzo [el original] hilo [s] después de que todos los objetos creados .. "

Todo código que modifique un componente Swing debe ejecutarse en la secuencia de envío del evento. NO es suficiente si esperas hasta que se haya creado todo.

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

Es posible que desee leer esto: Java Event-Dispatching Thread explanation

... y esto: Java: Swing Libraries & Thread Safety

+0

De acuerdo con el seguimiento de la pila, esta excepción * es * procedente del hilo de envío del evento. –

+1

En los comentarios de la pregunta original, escribió: "Y funciona en otro hilo, pero el hilo comienza después de todos los objetos creados ..." – lbalazscs