Java 两个背景和一根线
我想在JTextField中键入一些内容后将其颜色更改为红色,然后在第二次之后返回默认的白色背景。我在监听器之外尝试了这个方法,它很管用,但是当它成为监听器的一部分时,它就不管用了(它只是跳过设置红色)。这对我来说很奇怪Java 两个背景和一根线,java,actionlistener,Java,Actionlistener,我想在JTextField中键入一些内容后将其颜色更改为红色,然后在第二次之后返回默认的白色背景。我在监听器之外尝试了这个方法,它很管用,但是当它成为监听器的一部分时,它就不管用了(它只是跳过设置红色)。这对我来说很奇怪 public class Test { JFrame frame; JTextField field; public Test() { frame = new JFrame(); field = new JTextFie
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) { }
}
}
尝试创建一个单独的
线程
,该线程侦听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();
}
您以前的解决方案是有效的,因为它是从AWT本身执行的
keyTyped()
方法在事件分派thead(EDT)上执行,因此必须将绘制操作移回AWT
查看SwingUtilities.invokeLater()
(非阻塞)或SwingUtilities.invokeAndWait()
(阻塞),请参阅
您可以生成一个不同的线程,在其中执行颜色操作。这确保了颜色操纵不会在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) {
}
}
}
您需要阅读事件调度线程(EDT)。对于这样的更新,它们必须发生在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) {
}
}
}