Java swing-组件中的淡入淡出,正确的同步

Java swing-组件中的淡入淡出,正确的同步,java,user-interface,swing,multithreading,Java,User Interface,Swing,Multithreading,我正在为我的一个项目制作我的第一个GUI。我做了第一个页面,登录它。 现在我有了一个登录按钮,当它被点击时,应该让控制器知道,并传递用户名和密码,但我还没有为此设计登录按钮Listener,只是点击 现在我有了一个名为LoginButtonListener的MouseListener,它实现了MouseListener,这是我的覆盖mouseEntered方法,应该在登录按钮中消失: @Override public void mouseEntered(MouseEvent arg0) {

我正在为我的一个项目制作我的第一个GUI。我做了第一个页面,登录它。 现在我有了一个登录按钮,当它被点击时,应该让控制器知道,并传递用户名和密码,但我还没有为此设计登录按钮Listener,只是点击

现在我有了一个名为
LoginButtonListener
MouseListener
,它实现了
MouseListener
,这是我的覆盖mouseEntered方法,应该在登录按钮中消失:

@Override
public void mouseEntered(MouseEvent arg0) {
    Timer timer = new Timer();
    final LoginButtonListener b = this;
    timer.schedule(new TimerTask(){

        private int alpha = 0;

        @Override
        public void run() {
            alpha += 5;

            synchronized(b) {
                b.button.setBackground(new Color(255, 255, 255, alpha));
            }

            if (alpha >= 255) {
                this.cancel();
            }
        }
    }, 0, 50);
}
正如您所见,我同步b变量是因为我使用的计时器是
java.util.timer
,计时器是自己的线程,所以我认为这里需要同步

我是否正确地同步了它?还是我做的不对

这就是在
鼠标输入中发生的情况:


(来源:)

你做得不对。 切勿从消息调度程序线程以外的线程接触swing组件

为此,将访问swing的代码放入SwingUtilities.invokeLater(Runnable)(或invokeAndWait)中

您不需要(显式)同步来管理对swing组件的访问,因为您实际上只通过一个线程处理它们。其他线程只是注册到一些队列(通过SwingUtilities完成)任务,您想用GUI执行这些任务。

您做得不对。 切勿从消息调度程序线程以外的线程接触swing组件

为此,将访问swing的代码放入SwingUtilities.invokeLater(Runnable)(或invokeAndWait)中


您不需要(显式)同步来管理对swing组件的访问,因为您实际上只通过一个线程处理它们。其他线程只是注册到您想用GUI执行的某个队列(通过SwingUtilities完成)任务。

Swing是一个单线程环境,您的想法是正确的,但您的实现有点不正确

您确实应该使用
javax.swing.Timer
,而不是
java.util.Timer
,它将在事件调度线程的上下文中提高它的刻度,从而可以从内部安全地更新UI组件,例如

public void mouseEntered(MouseEvent arg0) {
    javax.swing.Timer timer = new javax.swing.Timer(50, new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
            alpha += 5;
            if (alpha >= 255) {
                alpha = 255;
                ((javax.swing.Timer)evt.getSource()).stop();
            }

            b.button.setBackground(new Color(255, 255, 255, alpha));
        }
    });
}
查看和了解更多详细信息


您还应该小心更改任何不透明组件的背景色的
alpha
,Swing只知道如何绘制不透明或透明组件,它无法处理半透明组件。要正确地执行此操作,您需要接管背景绘制的控制…

Swing是一个单线程环境,您的想法是正确的,但是您的实现有点不正确

您确实应该使用
javax.swing.Timer
,而不是
java.util.Timer
,它将在事件调度线程的上下文中提高它的刻度,从而可以从内部安全地更新UI组件,例如

public void mouseEntered(MouseEvent arg0) {
    javax.swing.Timer timer = new javax.swing.Timer(50, new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
            alpha += 5;
            if (alpha >= 255) {
                alpha = 255;
                ((javax.swing.Timer)evt.getSource()).stop();
            }

            b.button.setBackground(new Color(255, 255, 255, alpha));
        }
    });
}
查看和了解更多详细信息


您还应该小心更改任何不透明组件的背景色的
alpha
,Swing只知道如何绘制不透明或透明组件,它无法处理半透明组件。要正确执行此操作,您需要接管背景绘制的控制…

这就是我在执行invokeLater?后不需要任何同步的全部内容。@BenBeri在没有看到更多代码的情况下,使用alpha背景色可能会在Swing绘制过程中引发问题,因为Swing只知道如何绘制不透明和透明的组件,不是半透明的,要做到这一点,你们需要自己来画他们的背景…这就是我做invokeLater后不需要任何同步?@BenBeri在看不到更多代码的情况下,使用alpha背景色可能会在Swing绘画过程中引起问题,因为Swing只知道如何绘制不透明和透明的组件,而不知道如何绘制半透明的组件,所以您需要自己来绘制它们的背景。。。