5

私は一般的にJava、特にSwingライブラリを初めて使用します。Notepad デモ (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

元の質問に対するコメントによると、

「[...] 別のスレッドで動作しますが、[元の] スレッドはすべてのオブジェクトが作成された後に開始します..」

Swing コンポーネントを変更するすべてのコードは、イベント ディスパッチ スレッドで実行する必要があります。すべてが作成されるまで待つだけでは十分ではありません。

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

これを読みたいと思うかもしれません: Java Event-Dispatching Thread の説明

...そしてこれ: Java: Swing Libraries & Thread Safety

于 2012-07-13T17:27:54.983 に答える