两个设置背景和睡觉线程

时间:2017-08-24 07:00:41

标签: java actionlistener

我希望在输入内容后将JTextField的颜色更改为红色,然后在第二次返回默认的白色背景后。我在听众之外尝试了这个,但是它有效,但是当它成为听众的一部分时,它并没有(它只是跳过设置红色)。这对我来说很奇怪..

public class Test {
    JFrame frame;
    JTextField field;

    public Test() {
        frame = new JFrame();
        field = new JTextField("A");
        field.addKeyListener(new KeyBListener());
        frame.getContentPane().add(field);
        frame.pack();
        frame.setVisible(true);
    } 

    public static void main(String[] args) { new Test(); }

    private class KeyBListener implements KeyListener {
        @Override
        public void keyTyped(KeyEvent e) {

            try {
                field.setBackground(Color.RED);
                Thread.sleep(1000);
                field.setBackground(Color.WHITE);
            } catch (InterruptedException es) { es.printStackTrace(); }

        }

        @Override
        public void keyPressed(KeyEvent e) { }

        @Override
        public void keyReleased(KeyEvent e) { }
    } 
}

3 个答案:

答案 0 :(得分:3)

尝试创建一个单独的Thread来监听JTextField上的颜色变化,然后将其更改回来。在这种情况下,至少你不会阻止主线程,虽然我不确定它是最有效的方式。

public Main() {
    frame = new JFrame();
    frame.setSize(800, 600);
    field = new JTextField("A");
    field.addKeyListener(new KeyBListener());
    frame.getContentPane().add(field);
    frame.pack();
    frame.setVisible(true);

    new Thread(() -> {
        while(true) {
            if(field.getBackground().equals(Color.RED))
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            field.setBackground(Color.WHITE);
        }

    }).start();
}

答案 1 :(得分:0)

您之前的解决方案正在运行,因为它是从AWT本身执行的。

keyTyped()方法在Event dispatch thead(EDT)上执行,因此您必须将绘制操作移回AWT。

查看SwingUtilities.invokeLater()(非阻止)或SwingUtilities.invokeAndWait()(阻止),请参阅 Oracle Doc

SwingUtilities.invokeLater(new Runnable() {
  public void run() {
    try {
      field.setBackground(Color.RED);
      Thread.sleep(1000);
      field.setBackground(Color.WHITE);
    } catch (InterruptedException es) { 
      es.printStackTrace(); 
    }
  }
});

答案 2 :(得分:0)

您可以生成另一个执行颜色操作的线程。这确保了在EDT内部不会发生颜色处理。

import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class Test {
    JFrame frame;
    JTextField field;
    AtomicBoolean isColorChangeOn = new AtomicBoolean();
    public Test() {
        frame = new JFrame();
        field = new JTextField("A");
        field.addKeyListener(new KeyBListener());
        frame.getContentPane().add(field);
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        isColorChangeOn.set(false);
    }

    public static void main(String[] args) {
        new Test();
    }

    private class KeyBListener implements KeyListener {
        @Override
        public void keyTyped(KeyEvent e) {
                if(!isColorChangeOn.get()) {
                    isColorChangeOn.set(true);
                    Runnable setcolor = ()->{
                        try {
                            System.out.println("color changing");
                            field.setBackground(Color.RED);
                            Thread.sleep(1000);
                            field.setBackground(Color.WHITE);
                            isColorChangeOn.set(false);
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        }
                    };
                    new Thread(setcolor).start();
                }
        }

        @Override
        public void keyPressed(KeyEvent e) {
        }

        @Override
        public void keyReleased(KeyEvent e) {
        }
    }
}