1

我想通过以下方式制作闪光效果:将(JTextArea的)背景更改为红色->然后等待1秒->返回白色。我喜欢这样:

JTextArea jTextArea = new JTextArea();
jTextArea.setBackGround(Color.RED);
Thread.currentThread().sleep(1000);
jTextArea.setBackGround(Color.WHITE)

但它不起作用,我所拥有的只是白色背景,我没有看到红色背景。

我错了什么?

谢谢!

4

3 回答 3

4

Thread.sleep(...)您应该使用javax.swing.Timer而不是 using ,这会冻结您的 GUI 。此外,正如@MinhCatVO 所说,必须在 EDT 上完成对 GUI 的任何更新。有关该主题的更多信息,请参阅Swing 中的并发。看看下面的代码并询问你无法理解的内容。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ColouringTextArea
{
    private JTextArea tarea;
    private Timer timer;
    private Color[] colours = {
                                Color.RED,
                                Color.BLUE,
                                Color.GREEN.darker(),
                                Color.DARK_GRAY,
                                Color.MAGENTA,
                                Color.YELLOW
                              };
    private int counter = 0;                          
    private ActionListener timerAction = new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {
            if (counter < colours.length)
            {
                tarea.setBackground(colours[counter]);
                counter++;
            }
            else
            {
                tarea.setBackground(Color.PINK);
                counter = 0;
            }   
        }
    };

    private void displayGUI()
    {
        JFrame frame = new JFrame("Colouring JTextArea");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel contentPane = new JPanel();
        tarea = new JTextArea(10, 10);
        contentPane.add(tarea);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

        timer = new Timer(1000, timerAction);
        timer.start();
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new ColouringTextArea().displayGUI();
            }
        });
    }
}
于 2012-08-10T16:52:30.650 回答
1

由于线程问题,这不起作用。你需要一个工作线程

这应该有效:

            SwingWorker<Object, Object> sw = new SwingWorker<Object, Object>() {
                @Override
                protected Object doInBackground() throws Exception {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            jTextArea.setBackground(Color.RED);
                        }
                    });
                    Thread.sleep(1000);
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            jTextArea.setBackground(Color.WHITE);
                        }
                    });
                    return null;
                }
            };

            sw.execute();

请注意,必须从 Event Dispatch Thread 调用 Swing 对象上的所有方法。为此,请使用以下模式:

    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            // Do gui things
        }
    });

了解事件调度线程。SO中有很多关于此的帖子。只需搜索单词。

于 2012-08-10T16:57:22.867 回答
1

因为你想睡 1 秒的线程不是 GUI 线程。我认为 Swing.Utilities 有一个方法 SwingUtilities.invokeLater()。

public void class Flash extends Thread {
  JTextArea jtextArea = new JTextArera();
  public void run() {
   SwingUtilities.invokeLater(new Runnable()) {
      jTextArea.setBackground(Color.WHITE);
   }
  }
}

public void class Main {
   public void main() {
      ...
      Flash fl = new Flash();
      fl.start();
   }
}
于 2012-08-10T16:42:18.173 回答