2012-07-13 39 views
5

Tôi mới sử dụng Java nói chung và đặc biệt với thư viện Swing. Khi tôi thử nghiệm với bản demo Notepad (bản demo tiêu chuẩn từ JDK), tôi gặp sự cố khi cố gắng thay đổi văn bản trong cửa sổ trình soạn thảo. mẫu mã của tôi:JTextArea/JTextComponent setText gây ra sự cố

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

Tôi đã tìm kiếm ví dụ JTextComponent, cho đến khi tôi tìm thấy nó và sau đó thử nghiệm một số phương pháp. Tôi nghĩ rằng tôi đang thiếu một cái gì đó, một số chi tiết. Môi trường của tôi JDK 1.7, JRE 7.0, Win7 x64. Tôi sẽ rất vui khi được giúp đỡ. Cảm ơn bạn.

Cập nhật tôi thêm Exception handler

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

và có được điều này ..

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) 

Cập nhật 2 phương pháp setText làm việc sau khi thêm khối xử lý ngoại lệ. Nhưng những gì tôi nhớ?

+0

Có bất kỳ lỗi được báo cáo? – Brainbot

+2

Ý của bạn là gì? Nó có ném một ngoại lệ không? Nếu có, nó là cái gì? –

+0

Tôi có nghĩa là ứng dụng Notepad đã bị đóng băng và sẽ không phản hồi thao tác của tôi. – Darius

Trả lời

4

Đây không phải là một câu trả lời, nhưng mã bưu thấy rằng phương pháp của bạn, hoặc một biến thể của nó, người ta cho phép các coder để thay đổi những gì văn bản để thông báo, hoạt động:

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

Như vậy vấn đề là có khả năng cách bạn gọi phương thức của mình, điều mà bạn chưa thể hiện cho chúng tôi.

+0

Ok tôi cố gắng để hiển thị tất cả các mã nhưng không đổ lỗi cho tôi) Như tôi nói thử nghiệm của nó. – Darius

+0

+1 cho nỗ lực đăng mã runnable và hiển thị rằng 'setText' thực sự hoạt động :-) @Darius no, không hiển thị tất cả mã. Đăng một [SSCCE] (http://sscce.org) thể hiện vấn đề của bạn. – Robin

2

Theo các ý kiến ​​về câu hỏi ban đầu của bạn,

"[...] cho nó hoạt động [s] trong chủ đề khác, nhưng [bản gốc] chủ đề bắt đầu [s] sau khi tất cả đối tượng được tạo .. "

Tất cả mã sửa đổi thành phần Swing phải chạy trong chuỗi gửi sự kiện. KHÔNG đủ nếu bạn đợi cho đến khi mọi thứ được tạo ra.

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

Bạn có thể muốn đọc: Java Event-Dispatching Thread explanation

... và điều này: Java: Swing Libraries & Thread Safety

+0

Theo dấu vết ngăn xếp, ngoại lệ này * là * đến từ chuỗi gửi sự kiện. –

+1

Trong các ý kiến ​​của câu hỏi ban đầu, ông đã viết: "Và nó làm việc trong một chủ đề khác, nhưng thread bắt đầu sau khi tất cả các đối tượng tạo ra .." – lbalazscs

Các vấn đề liên quan