3

いつ書いているのか、いつ削除しているのか知りたいのですが、0.5秒遅れて「書き込み/削除を停止しました」と表示されますが、そのメッセージしか表示されず、0.5秒遅れて削除または書き込みされます.

どうすればThread.sleep(500);正しく使えますか?

私の現在のソースコード:

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;


public class TextChangedFrame extends JFrame {

    JTextField textField = new JTextField("Put your text here");
    JLabel label = new JLabel("You have written: ");

    public TextChangedFrame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(300, 100);
        setLayout(new BorderLayout());
        getContentPane().add(textField, BorderLayout.CENTER);
        getContentPane().add(label, BorderLayout.SOUTH);
        textField.getDocument().addDocumentListener(new DocumentListener() {

            public void insertUpdate(DocumentEvent e) {
                label.setText("I'm writting: " + textField.getText());
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ex) {

                }
                label.setText("I stopped writing");
            }

            public void removeUpdate(DocumentEvent e) {
                label.setText("I'm deleting");
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ex) {

                }
                label.setText("I stopped deleting");
            }

            public void changedUpdate(DocumentEvent e) {
            }
        });
    }

    public static void main(String[] args) {
        TextChangedFrame frame = new TextChangedFrame();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
4

2 に答える 2

3

ここでも、Swing Timer を使用して汚れた作業を行います。編集または削除するたびに、タイマーで再起動を呼び出して、タイマーを再設定して開始します。restart() メソッドは、実行中のタイマーを停止します。

     public void insertUpdate(DocumentEvent e) {
        label.setText(EDITING);
        writeDeleteTimer.restart();
     }

例えば:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

@SuppressWarnings("serial")
public class TextChangedFrame extends JPanel {

   public static final String STOPPED_EDITING = "No Longer Editing or Deleting";
   private static final String EDITING = "Editing";
   private static final String DELETING = "Deleting";
   private static final int TIMER_DELAY = 500;
   private static final int PREF_W = 400;
   private static final int PREF_H = 100;
   private JTextField textField = new JTextField("Put your text here");
   private JLabel label = new JLabel("You have written: ");
   private ActionListener timerListener = new TimerListener();
   private Timer writeDeleteTimer = new Timer(TIMER_DELAY, timerListener);

   public TextChangedFrame() {
      setLayout(new BorderLayout());
      add(textField, BorderLayout.CENTER);
      add(label, BorderLayout.SOUTH);
      textField.getDocument().addDocumentListener(new DocumentListener() {

         public void insertUpdate(DocumentEvent e) {
            label.setText(EDITING);
            writeDeleteTimer.restart();
         }

         public void removeUpdate(DocumentEvent e) {
            label.setText(DELETING);
            writeDeleteTimer.restart();
         }

         public void changedUpdate(DocumentEvent e) {
         }
      });
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent evt) {
         label.setText(STOPPED_EDITING);
         Timer timer = (Timer) evt.getSource();
         timer.stop();
      }
   }

   private static void createAndShowGui() {
      TextChangedFrame mainPanel = new TextChangedFrame();

      JFrame frame = new JFrame("TextChangedFrame");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

編集された回答: Timer オブジェクトを再作成する必要はありません。restart()実行中の場合は現在のタイマーを停止するため、単純に呼び出すだけです。

于 2013-05-03T16:02:38.580 に答える
2

この質問はかなり貧弱で、あまり明確ではないので、質問が解決されるまで正確な答えを出すことはできません.

Thread.sleep(500)現在、500ミリ秒の遅延を引き起こすために使用しているようです。ほとんどのプログラムでは、これでうまくいきます。

Thread.sleep(int x)x現在の操作をミリ秒 (この場合は 500 ミリ秒)中断します (または、質問者によってはフリーズします)。

使用しているアプリケーションでは、テキストの変更を一時停止するために使用しています。その場所にあるため、現在スイング ボックス全体がフリーズしており、回復していません。

を使用するThread.sleep(int x)必要がある場合は、使用しているテキストを文字列として保存し、文字列を更新したTextChangedFrame後に を更新することをお勧めします。これにより、 を中断せずに操作を中断できますTextChangedFrame

疑似コード:

String oldString = "old string";
String newString = "new string";

// setup your dialog/popup here, with oldString

Thread.sleep(500);

// modify the dialog/popup here, changing oldString to newString

これにより、フリーズの問題を回避できます。(これは、質問とコメントで、あなたの問題だと思います)。

Hovercraft Full Of Eelsのコメントで言及されているように、より良い解決策はSwing Timersを使用することです

于 2013-05-03T15:55:51.707 に答える