5

一般来说,我是 Java 新手,尤其是 Swing 库。当我尝试使用记事本演示(来自 JDK 的标准演示)时,尝试更改编辑器窗口中的文本时发生了崩溃。我的示例代码:

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 方法工作。但我想念什么?

4

2 回答 2

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

因此,问题可能在于您如何调用您的方法,而您尚未向我们展示。

于 2012-07-13T16:52:57.017 回答
2

根据您对原始问题的评论,

“[...] 它在另一个线程中工作 [s],但 [原始] 线程在创建所有对象后开始 [s]..”

所有修改 Swing 组件的代码都必须在事件分派线程中运行。如果你等到所有东西都被创建是不够的。

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

您可能想阅读以下内容:Java Event-Dispatching Thread 解释

...还有这个:Java:Swing 库和线程安全

于 2012-07-13T17:27:54.983 回答