Java 同时淡入和淡出两个 JPanel

2023-12-15

我有一个 JPanel 列表,我想将其显示为“幻灯片”,其中一个 JPanel 淡出,列表中的下一个 JPanel 淡入。这是我正在摆弄的代码:

  public float opacity = 0f;
  private Timer fadeTimer;
  private boolean out;

  public void fadeIn()
  {
    out = false;
    beginFade();
  }

  public void fadeOut ()
  {
    out = true;
    beginFade();
  }

  private void beginFade()
  {
    fadeTimer =
      new javax.swing.Timer(75,this);
    fadeTimer.setInitialDelay(0);
    fadeTimer.start();
  }

  public void actionPerformed(ActionEvent e)
  {
    if (out)
    {
      opacity -= .03;
      if(opacity < 0)
      {
        opacity = 0;
        fadeTimer.stop();
        fadeTimer = null;
      }
    }
    else
    {
      opacity += .03;
      if(opacity > 1)
      {
        opacity = 1;
        fadeTimer.stop();
        fadeTimer = null;
      }
    }


    repaint();
  }
  public void paintComponent(Graphics g)
  {
    ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
    g.setColor(getBackground());
    g.fillRect(0,0,getWidth(),getHeight());
  }

问题是它有时会消失,有时不会,有时过渡非常滞后。我更喜欢的是,在一个 JPanel 淡出和下一个 JPanel 淡入之间,屏幕变白的那一瞬间。有谁知道我该如何解决这个问题?提前致谢。


因此,在处理这些类型的问题时,通常最好减少Timer你有,因为每个计时器都会将多个事件发布到事件调度队列(有自己的滴答更新以及重绘事件)。所有这些活动都会降低系统的性能。

动画也是随着时间变化的幻觉,为此,而不是尝试从起点循环到终点,您应该决定动画运行多长时间并计算时间进度并更新值相应地(这更多的是基于“时间线”的动画周期)。这有助于减少“滞后”的出现

通常我会使用时序框架来完成这个,但你也可以看看Trident框架或通用补间引擎它还为 Swing 提供复杂的动画支持。

这个例子与其目标非常紧密地结合在一起。就我个人而言,我通常有一个“可动画”对象的抽象概念,它可能只是具有update(float)方法,然后该方法将被扩展以支持其他对象,但我将让您自行解决。

另一个问题是确保组件一开始就完全透明(setOpaque(false)),这允许我们在动画过程中伪造组件的半透明度。

通常情况下,我总是鼓励你超越paintComponent,但有时这还不够,这就是其中之一。基本上,为了促进从一个组件到另一个组件的转换,我们需要控制组件内所有子组件的 alpha 级别,这是在重写时paint将是一个更好的选择。

Fade

注:代码设置为以 25 fps 左右运行,但屏幕捕获软件以大约 8 fps 捕获

import java.awt.AlphaComposite;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class FadeTest {

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

    public FadeTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }

                    BufferedImage img1 = ImageIO.read(new File("C:\\Users\\shane\\Dropbox\\Ponies\\sillydash-small.png"));
                    BufferedImage img2 = ImageIO.read(new File("C:\\Users\\shane\\Dropbox\\Ponies\\SmallPony.png"));

                    AlphaPane pane1 = new AlphaPane();
                    pane1.add(new JLabel(new ImageIcon(img1)));
                    pane1.setAlpha(1f);

                    AlphaPane pane2 = new AlphaPane();
                    pane2.add(new JLabel(new ImageIcon(img2)));
                    pane2.setAlpha(0f);

                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new GridBagLayout());
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.gridx = 1;
                    gbc.gridy = 1;
                    gbc.weightx = 1;
                    gbc.weighty = 1;
                    gbc.fill = GridBagConstraints.BOTH;
                    frame.add(pane1, gbc);
                    frame.add(pane2, gbc);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);

                    MouseAdapter ma = new MouseAdapter() {

                        private AnimationController controller;

                        @Override
                        public void mouseClicked(MouseEvent e) {
                            try {
                                if (controller != null) {
                                    controller.stop();
                                }
                                controller = new AnimationController(4000);

                                boolean fadeIn = pane1.getAlpha() < pane2.getAlpha();

                                controller.add(controller.new AlphaRange(pane1, fadeIn));
                                controller.add(controller.new AlphaRange(pane2, !fadeIn));

                                controller.start();
                            } catch (InvalidStateException ex) {
                                ex.printStackTrace();
                            }
                        }

                    };
                    pane1.addMouseListener(ma);
                    pane2.addMouseListener(ma);

                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    public class AnimationController {

        private List<AlphaRange> animationRanges;
        private Timer timer;
        private Long startTime;
        private long runTime;

        public AnimationController(int runTime) {
            this.runTime = runTime;
            animationRanges = new ArrayList<>(25);
        }

        public void add(AlphaRange range) {
            animationRanges.add(range);
        }

        public void start() throws InvalidStateException {
            if (timer == null || !timer.isRunning()) {

                timer = new Timer(40, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (startTime == null) {
                            startTime = System.currentTimeMillis();
                        }
                        long duration = System.currentTimeMillis() - startTime;
                        float progress = (float) duration / (float) runTime;
                        if (progress > 1f) {
                            progress = 1f;
                            stop();
                        }

                        System.out.println(NumberFormat.getPercentInstance().format(progress));

                        for (AlphaRange range : animationRanges) {
                            range.update(progress);
                        }
                    }
                });
                timer.start();

            } else {
                throw new InvalidStateException("Animation is running");
            }
        }

        public void stop() {
            if (timer != null) {
                timer.stop();
            }
        }

        public class AlphaRange {

            private float from;
            private float to;

            private AlphaPane alphaPane;

            public AlphaRange(AlphaPane alphaPane, boolean fadeIn) {
                this.from = alphaPane.getAlpha();
                this.to = fadeIn ? 1f : 0f;
                this.alphaPane = alphaPane;
            }

            public float getFrom() {
                return from;
            }

            public float getTo() {
                return to;
            }

            public float getValueBasedOnProgress(float progress) {

                float value = 0;
                float distance = to - from;
                value = (distance * progress);
                value += from;

                return value;

            }

            public void update(float progress) {
                float alpha = getValueBasedOnProgress(progress);
                alphaPane.setAlpha(alpha);
            }

        }

    }

    public class InvalidStateException extends Exception {

        public InvalidStateException(String message) {
            super(message);
        }

        public InvalidStateException(String message, Throwable cause) {
            super(message, cause);
        }

    }

    public class AlphaPane extends JPanel {

        private float alpha;

        public AlphaPane() {
            setOpaque(false);
        }

        @Override
        public void paint(Graphics g) {
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));
            super.paint(g2d);
            g2d.dispose();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            // Fake the background
            g.setColor(getBackground());
            g.fillRect(0, 0, getWidth(), getHeight());
        }

        public void setAlpha(float value) {
            if (alpha != value) {
                this.alpha = Math.min(1f, Math.max(0, value));
                repaint();
            }
        }

        public float getAlpha() {
            return alpha;
        }

    }

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 同时淡入和淡出两个 JPanel 的相关文章

  • 编译错误:Android Studio

    我正在尝试修改基于 IntelliJ 构建的现有 Android 项目 我已经搜索并尝试了很多东西 但我的错误仍然没有消失 Error 5 1 android apt compiler main D android tinynote app
  • Windows 上的虚假唤醒。是否可以?

    我最近学习了 虚假唤醒 有人说这个问题只可能发生在某些类型的 Linux PC 上 我用的是窗户 我为虚假唤醒编写了测试 我得到的结果是这是可能的 但我想向您展示这个测试 也许我在某个地方犯了错误 我的初始变体 import java ut
  • 如何检测线程是否被IO阻塞?

    在Java中 线程可以有不同的状态 新的 可运行的 阻塞的 等待的 TIMED WAITING 的 终止的 然而 当线程被IO阻塞时 其状态为 RUNNABLE 如何判断是否被IO阻塞 NEW 线程已创建但尚未处理 可运行 线程正在占用CP
  • mvn dependency:analyze 结果不正确

    我一直在寻找一种工具 它能够向您显示未使用的依赖项 我很快就偶然发现了 Maven 命令mvn dependency analyze 这样做的问题是 它经常检测到 未使用的 依赖项 如果缺失 这些依赖项就会导致构建失败 这是优化项目的示例
  • 如何通过keytool命令删除已经导入的证书/别名?

    我正在尝试通过 keytool 命令删除已导入的证书 keytool delete noprompt alias initcert keystore keycloak jks 但低于异常 keytool 错误 java lang Excep
  • 使用 ScheduledExecutorService 安排每月任务

    我想在该月的某一天的特定时间安排一项任务 每次运行之间的间隔可以设置在 1 到 12 个月之间 在java中 可以使用ScheduledExecutorService以固定的时间间隔调度任务 既然一个月的天数不固定 那么如何实现呢 提前致谢
  • 仅使用 ServletContext 查找应用程序的 URL

    我正在使用 Spring MVC 编写一个 Java Web 应用程序 我有一个后台进程 它会遍历数据库并查找必须通过电子邮件发送给我的用户的通知 这些电子邮件需要包含应用程序的超链接 对于网络应用程序来说 这似乎是相当常见的模式 但我遇到
  • C# 中的 Culture 相当于 Java 中的 Locale 吗?

    C 使用文化的概念 这在操作上与 Java 中的 Locale 类似吗 或者底层概念是否存在显着差异 从文化而不是语言环境的角度进行工作是一种寻找正确抽象层次的尝试 从以类似方式做事的人群的角度来考虑事物 而不是谈论地理区域和语言 并有点疯
  • x.person 上的 @OneToOne 或 @ManyToOne 引用未知实体:y.Person - 继承问题

    我的 Hibernate 架构有问题 我有一个 MappedSuperClass 人员 一名员工和一名客户 gt Person class MappedSuperclass Audited public class Person exten
  • Java HttpURLConnection:内容长度计算

    我目前正在为 bitbucket issues RESTful API 开发一个库 我取得了很大的进步 现在我要解决这个部分更新问题 http confluence atlassian com display BBDEV Issues Is
  • 按位非运算符

    为什么要按位运算 0 打印 1 在二进制中 不是0应该是1 为什么 你实际上很接近 在二进制中 不是0应该是1 是的 当我们谈论一位时 这是绝对正确的 然而 一个int其值为0的实际上是32位全零 将所有 32 个 0 反转为 32 个 1
  • java3d 中的面部着色

    使用java3d 如何不在每个顶点基础上着色 而是在每个面基础上着色 我尝试学习 java3d 但我生成的 Shape3d 看起来并不符合预期 我想用不同的颜色给不同的三角形着色 但我不知道该怎么做 纹理看起来有点大材小用 而且我根本没有掌
  • JFreeChart MeterPlot

    我目前正在用java做Agent项目 在某些时候 我需要显示一个仪表 例如 电池电量 我的程序中有 5 个代理 每个代理都会创建自己的带有名称的仪表图 但不知何故他们没有更新数据集 或者他们正在更新数据集 只是它没有显示在仪表图上 任何想法
  • 如何迭代SparseArray?

    有没有办法迭代 Java SparseArray 适用于 Android 我用了sparsearray通过索引轻松获取值 我找不到 看来我找到了解决方案 我没有正确注意到keyAt index 功能 所以我会这样做 for int i 0
  • GAE - Eclipse 中的开发服务器未更新?

    我在 Eclipse 上使用 Google AppEngine 开发服务器 我的本地网页似乎没有更新 直到我在开发服务器上进行了多次重新启动 使用 Eclipse 中的 运行 或 调试 按钮 我究竟做错了什么 基本流程是 更改 java 文
  • 在java中设置Process对象的安全性

    有人可以告诉我如何限制通过进程对象访问系统属性吗 如果我通过进程对象运行以下代码 我可以抛出安全异常吗 System getProperty user home 请告诉我如何为流程对象配置证券 在ProcessBuilder类文档中 环境方
  • 当相应的 JTextfield 为空时,如何填充 JTable 中的所有项目

    我正在 Java 项目中设计一个高级搜索选项sqlite在 NetBeans 中 有5种不同JTextfields和 5 列 我想填充JTable具有相应的匹配标准 如果一个JTextfield为空 那么它应该选择该列的所有项目 我使用的查
  • java.lang.NoSuchMethodError:com.fasterxml.jackson.databind.type。使用 apache beam Spark runner 运行 go 示例时

    我想跑grades https github com apache beam tree master sdks go examples gradesapache beam go sdk 提出的示例 在一个主服务器和两个从服务器 spark2
  • java.lang.NoClassDefFoundError:com.google.ads.AdView

    我正在尝试将 admob 广告合并到我的应用程序中 到目前为止我已经添加了以下代码 在我的应用程序主要活动的 onCreate 方法中 adView new AdView this AdSize BANNER my code number
  • SAXParseException:找不到元素“定义”的声明

    我对 camunda 和 DMN 完全陌生 我试图在 spring boot 中运行 DMN 示例 链接在这里 https github com camunda camunda bpm examples tree master dmn en

随机推荐

  • Javascript 中的函数重载 - 最佳实践 [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 在 Javascript 中伪造函数重载的最佳方法是什么 我知道不可能像其他语言那样重载 Javascript 中的函数 如果我需要一个有两种用途的函数foo x and foo x y
  • 选择并列出子项和父项

    我需要一个 SQL 查询来执行以下复杂任务 我需要从名为的列中进行选择parent id 如果一行有 0parent id这意味着它是一个类别 它也有type栏说cat对于类别 如果一行有 1 个或多个parent id这意味着这是一条规则
  • 带复选框和 JFileChooser 的 Swing JTree

    通过使用JFileChooser我可以选择使用文件对象获取 JList 的文件和文件夹 并使用复选框显示它 现在我的要求是我想用复选框在树结构中显示选定的文件和文件夹 并且该复选框应该仅适用于根元素而不适用于所有子元素 示例 例如 我选择了
  • 运行任意Python代码的Bokeh悬停工具

    我正在使用 Bokeh 尝试创建一个图形 当用户将其数据点 悬停 在其上时 将在悬停工具中显示另一个图形 显示有关该数据点的附加信息 即 在主图中 数据点是设定间隔内的时间序列 我希望悬停工具显示该间隔内的所有数据 The 用户指南 完整代
  • 从 SD 卡创建一个可绘制对象以设置为 Android 中的背景

    我正在尝试使用 SD 卡中的图像并将其设置为相对布局的背景 我尝试过在这里和其他地方找到的其他解决方案 但它们似乎对我不起作用 这是我的代码 我已经评论了我尝试过但不起作用的其他方法 唯一对我有用的是使用 setBackgroudnReso
  • 绑定到 VisualStateManager 中控件的属性

    我在 Stackoverflow 上搜索了这个问题 但我认为其他帖子没有涵盖这个问题 在我的自定义控件中 我使用视觉状态管理器 视觉状态管理器内部有一个动画 可以对元素的高度进行动画处理 当我尝试绑定到控件属性时 我在启动时收到以下错误 附
  • 上传文件不起作用 - 需要帮助

    我正在尝试使用 WebBrowser 控件上传文件 图像 似乎无法做到这一点 需要一些帮助 这是 HTML
  • 从 servlet 访问数据

    我有一个要求 mysql 数据库只能从本地主机访问 我必须实现一个 servlet 来访问数据库 从而允许该系统中的其他服务器访问数据 servlet 将充当代理 然而 该系统由一个远程服务器组成 该服务器下载大部分数据并执行如下语句 se
  • Bash 中的 RSS 日期到纪元

    寻找 bash 行以采用 RSS 日期格式 例如 Fri 13 Sep 2013 17 16 45 GMT 并将其转换为毫秒 我已经尝试过如下的事情 它们不会在几毫秒内产生 我运行的是 Mac OS X Snow Leopard 10 6
  • 在新存储库上推送原始主错误

    我刚刚开始使用 git 和 github 我按照他们的指示进行操作 但在最后一步遇到了错误 我正在检查当前不受源代码控制的现有目录 项目大约一周前 除此之外 我的用例应该是非常普通的 这是发生的事情 git push origin mast
  • 如何隐藏行索引

    我想将此 DataFrame 写入不带索引值的 xlsx 文件 我该怎么做 writer pd ExcelWriter r D pandas xlsx today datetime datetime today header pd Mult
  • 将 1 和 0 的字符串转换为二进制值

    我正在尝试将来自 stdin 的传入 1 和 0 字符串转换为各自的二进制值 其中诸如 11110111 之类的字符串将转换为 0xF7 这看起来很微不足道 但我不想重新发明轮子 所以我想知道 C C 标准库中是否有任何东西已经可以执行这样
  • 数组中给定数字的最小窗口

    最近看到这个问题 给定 2 个数组 第二个数组包含第一个数组的一些元素 返回第一个数组中包含第二个数组的所有元素的最小窗口 Eg 给定 A 1 3 5 2 3 1 和 B 1 3 2 Output 3 5 其中 3 和 5 是数组 A 中的
  • Javascript'this'值改变,但不明白为什么

    我是一个 Javascript 新手 我正在尝试了解 OLN 我遇到的是 当从同一对象上的另一个方法调用对象方法时 被调用方法中 this 的本地值正在改变 这是我的代码 var generator generateForLevelSkil
  • 使用 MPAndroidChart 库重叠饼图标签

    我正在使用菲尔杰MPAndroid图表图书馆 implementation com github PhilJay MPAndroidChart v3 1 0 And I implemented Pie Chart Pie Chart wit
  • 在Xamarin浏览器控件中访问html响应内容

    我有一个似乎不寻常的要求 我和我的同事无法在我们的 Xamarin 项目中实现 我们试图做的是动态处理浏览器导航到的任何页面的内容 而不是简单地处理从其访问的初始 URL 返回的内容 我见过以这种方式访问 返回内容的解决方案 Xamarin
  • 如何在 C# 中创建动态大小的数组或重新调整数组的大小?

    我需要知道如何在 C 中动态调整数组大小 在我下面编写的方法中 我需要能够返回一个仅包含用户输入的数字 最多 8 个数字 的数组 因此 如果用户决定只想输入 3 个数字 则数组应该只包含 3 个数字 而不是 8 个 现在我知道数组在实例化时
  • 在 Spring 测试中禁用 @EnableScheduling

    当我运行单元测试时 它会调用我的计划任务 我想防止这种行为 这是因为我有 EnableScheduling在我的主要应用程序配置上 如何在单元测试中禁用此功能 我遇到过这个问题 答案这建议设置配置文件 不知道我会怎么做 或者是否太过分了 我
  • MySQL 查询 - 使用 URL 名称识别数据,其中数据被组织成层次结构

    我有一个名为 content 的 mysql 表 它存储内容管理系统的内容数据 注意 所有内容都使用父 id 列组织成层次结构 id slug content type id parent 1 portfolio 5 0 2 about u
  • Java 同时淡入和淡出两个 JPanel

    我有一个 JPanel 列表 我想将其显示为 幻灯片 其中一个 JPanel 淡出 列表中的下一个 JPanel 淡入 这是我正在摆弄的代码 public float opacity 0f private Timer fadeTimer p