悬停以及点击切换图片

news2025/4/22 6:25:41

为了实现悬停切换图片的功能,我们可以为每个按钮添加鼠标悬停事件监听器。以下是详细步骤和代码:

  1. 首先在控制器类中添加初始化方法,并添加事件监听器:
package com.example.demo6;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;

public class LoginController {

    // 原有的FXML注入字段保持不变...
    
    @FXML
    public void initialize() {
        // 初始化所有悬停图片为不可见
        setHoverImagesVisible(false);
        
        // 为所有按钮绑定悬停效果
        bindHoverEffects();
    }

    private void setHoverImagesVisible(boolean visible) {
        friend2.setVisible(visible);
        message2.setVisible(visible);
        info2.setVisible(visible);
        avatar2.setVisible(visible);
        memes2.setVisible(visible);
        file2.setVisible(visible);
        photo2.setVisible(visible);
        voice2.setVisible(visible);
    }

    private void bindHoverEffects() {
        setupHoverEffect(friend, friend1, friend2);
        setupHoverEffect(message, message1, message2);
        setupHoverEffect(info, info1, info2);
        setupHoverEffect(avatar, avatar1, avatar2);
        setupHoverEffect(memes, memes1, memes2);
        setupHoverEffect(file, file1, file2);
        setupHoverEffect(photo, photo1, photo2);
        setupHoverEffect(voice, voice1, voice2);
    }

    private void setupHoverEffect(Button button, ImageView normal, ImageView hover) {
        button.setOnMouseEntered(event -> {
            normal.setVisible(false);
            hover.setVisible(true);
        });
        
        button.setOnMouseExited(event -> {
            normal.setVisible(true);
            hover.setVisible(false);
        });
    }

    // 原有的空方法可以保留或移除(如果不需要点击事件)
    @FXML
    void exchange(ActionEvent event) {
        // 如果需要保留点击功能可以在这里添加代码
    }

    // 其他exchange方法同理...
}
  1. 确保FXML中成对的ImageView初始状态正确(默认显示第一个图片),或者在initialize方法中设置初始可见性。
  2. 如果需要保留点击切换功能,可以在原有exchange方法中添加切换逻辑:
@FXML
void exchange(ActionEvent event) {
    boolean visible = friend2.isVisible();
    friend1.setVisible(!visible);
    friend2.setVisible(visible);
}

实现原理:

  1. 使用setOnMouseEntered和setOnMouseExited事件监听器
  2. 通过控制ImageView的visible属性切换图片显示
  3. 初始化时将所有悬停状态图片设为不可见
  4. 使用通用方法setupHoverEffect为所有按钮统一添加效果

注意事项:

  1. 确保图片资源路径正确
  2. 检查FXML中ImageView的叠加顺序(后定义的会在上层)
  3. 如果不需要点击事件,可以移除对应的onAction属性和控制器方法
  4. 所有按钮的style都设置了transparent背景以保证视觉效果

这个实现会在鼠标进入按钮区域时显示悬停图片,离开时恢复默认图片。如果需要添加点击效果,可以在原有exchange方法中补充切换逻辑。

让我们分步实现点击保持状态的功能,同时保留其他按钮的悬停效果。以下是完整实现方案:

package com.example.demo6;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.image.ImageView;

public class LoginController {

    // 保持原有FXML注入字段...
    
    @FXML private Button friend;
    @FXML private ImageView friend1;
    @FXML private ImageView friend2;
    
    @FXML private Button avatar;
    @FXML private ImageView avatar1;
    @FXML private ImageView avatar2;
    
    @FXML private Button info;
    @FXML private ImageView info1;
    @FXML private ImageView info2;
    
    @FXML private Button message;
    @FXML private ImageView message1;
    @FXML private ImageView message2;

    private Button activeButton; // 当前激活的按钮

    @FXML
    public void initialize() {
        // 初始化所有悬停图片为不可见
        setInitialStates();
        
        // 绑定悬停效果(所有按钮)
        bindHoverEffects();
        
        // 绑定点击效果(特定按钮)
        bindClickEffects();
    }

    private void setInitialStates() {
        // 设置初始可见性(确保FXML中默认显示1号图片)
        friend2.setVisible(false);
        avatar2.setVisible(false);
        info2.setVisible(false);
        message2.setVisible(false);
        
        // 其他按钮的初始化(如有需要)
        // memes2.setVisible(false);
        // file2.setVisible(false);
        // ...
    }

    private void bindHoverEffects() {
        // 所有按钮的悬停效果
        setupHoverEffect(friend, friend1, friend2);
        setupHoverEffect(avatar, avatar1, avatar2);
        setupHoverEffect(info, info1, info2);
        setupHoverEffect(message, message1, message2);
        
        // 其他按钮的悬停效果
        // setupHoverEffect(memes, memes1, memes2);
        // setupHoverEffect(file, file1, file2);
        // ...
    }

    private void bindClickEffects() {
        // 特定按钮的点击效果
        setupClickEffect(friend, friend1, friend2);
        setupClickEffect(avatar, avatar1, avatar2);
        setupClickEffect(info, info1, info2);
        setupClickEffect(message, message1, message2);
    }

    // 悬停效果处理(通用方法)
    private void setupHoverEffect(Button btn, ImageView normal, ImageView hover) {
        btn.setOnMouseEntered(e -> {
            if (btn != activeButton) { // 非激活状态才响应悬停
                normal.setVisible(false);
                hover.setVisible(true);
            }
        });
        
        btn.setOnMouseExited(e -> {
            if (btn != activeButton) { // 非激活状态才恢复
                normal.setVisible(true);
                hover.setVisible(false);
            }
        });
    }

    // 点击效果处理(特定按钮)
    private void setupClickEffect(Button btn, ImageView normal, ImageView active) {
        btn.setOnAction(e -> {
            if (btn == activeButton) {
                // 点击已激活的按钮:取消激活
                normal.setVisible(true);
                active.setVisible(false);
                activeButton = null;
            } else {
                // 取消之前的激活状态
                if (activeButton != null) {
                    resetPreviousActive();
                }
                
                // 设置新的激活状态
                normal.setVisible(false);
                active.setVisible(true);
                activeButton = btn;
            }
        });
    }

    private void resetPreviousActive() {
        // 根据按钮类型重置状态
        if (activeButton == friend) {
            friend1.setVisible(true);
            friend2.setVisible(false);
        } else if (activeButton == avatar) {
            avatar1.setVisible(true);
            avatar2.setVisible(false);
        } else if (activeButton == info) {
            info1.setVisible(true);
            info2.setVisible(false);
        } else if (activeButton == message) {
            message1.setVisible(true);
            message2.setVisible(false);
        }
    }
}

实现说明:

  1. 状态管理机制
    • 使用 activeButton 变量跟踪当前激活的按钮• 点击时检查是否重复点击同一按钮,实现状态切换
  2. 悬停与激活状态的关系
// 在悬停处理中增加状态判断
if (btn != activeButton) {
    // 只有非激活按钮才会响应悬停
}
  1. 点击逻辑流程
点击事件
是否点击已激活按钮?
取消激活状态
取消之前的激活
设置新激活状态

FXML 需要调整的部分:

<!-- 移除所有按钮的 onAction 属性 -->
<Button fx:id="friend" ... />  <!-- 原 onAction="#exchange" 需要删除 -->
<Button fx:id="avatar" ... />
<Button fx:id="info" ... />
<Button fx:id="message" ... />

验证步骤:

  1. 点击 “好友” 按钮 → friend2 保持显示
  2. 悬停 “消息” 按钮 → 显示 message2(此时消息未激活)
  3. 点击 “消息” 按钮 → friend2 消失,message2 保持显示
  4. 再次点击 “消息” → message2 消失,恢复 message1

常见问题处理:

现象可能原因解决方案
点击无反应FXML 中保留 onAction 属性删除所有按钮的 onAction 属性
图片显示叠加ImageView 层级问题确保 FXML 中 2 号图片定义在 1 号之后
激活状态无法取消activeButton 未置空检查 resetPreviousActive 逻辑
悬停效果干扰激活状态未正确判断 activeButton确认悬停处理中的状态判断逻辑

这个方案实现了:
• 点击特定按钮保持激活状态

• 同一时间只能有一个激活状态

• 激活按钮不受悬停效果影响

• 其他按钮保留原有悬停功能

• 可通过二次点击取消激活状态

如果需要调整激活状态的视觉效果,可以修改对应图片的可见性逻辑。如果还需要其他按钮的点击效果,可以通过相同模式扩展 setupClickEffect 方法。

package com.example.demo6;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;

public class LoginController {

    public ImageView qq2;
    @FXML
    private Button avatar;

    @FXML
    private ImageView avatar1;

    @FXML
    private ImageView avatar2;

    @FXML
    private Button file;

    @FXML
    private ImageView file1;

    @FXML
    private ImageView file2;

    @FXML
    private Button friend;

    @FXML
    private ImageView friend1;

    @FXML
    private ImageView friend2;

    @FXML
    private Button info;

    @FXML
    private ImageView info1;

    @FXML
    private ImageView info2;

    @FXML
    private Button memes;

    @FXML
    private ImageView memes1;

    @FXML
    private ImageView memes2;

    @FXML
    private Button message;

    @FXML
    private ImageView message1;

    @FXML
    private ImageView message2;

    @FXML
    private Button photo;

    @FXML
    private ImageView photo1;

    @FXML
    private ImageView photo2;

    @FXML
    private ListView<?> qq;

    @FXML
    private TextField search;

    @FXML
    private TextField search2;

    @FXML
    private ImageView setting;

    @FXML
    private Button voice;

    @FXML
    private ImageView voice1;

    @FXML
    private ImageView voice2;

    @FXML
    private Button activeButton; // 当前激活的按钮
    @FXML
    public void initialize() {
        // 初始化所有悬停图片为不可见
        setInitialStates();

        // 绑定悬停效果(所有按钮)
        bindHoverEffects();

        // 绑定点击效果(特定按钮)
        bindClickEffects();
    }

    private void setInitialStates() {
        // 设置初始可见性(确保FXML中默认显示1号图片)
        friend2.setVisible(false);
        avatar2.setVisible(false);
        info2.setVisible(false);
        message2.setVisible(false);
        memes2.setVisible(false);
        file2.setVisible(false);
        photo2.setVisible(false);
        voice2.setVisible(false);
    }

    private void bindHoverEffects() {
        setupHoverEffect(friend, friend1, friend2);
        setupHoverEffect(message, message1, message2);
        setupHoverEffect(info, info1, info2);
        setupHoverEffect(avatar, avatar1, avatar2);
        setupHoverEffect(memes, memes1, memes2);
        setupHoverEffect(file, file1, file2);
        setupHoverEffect(photo, photo1, photo2);
        setupHoverEffect(voice, voice1, voice2);
    }

    private void bindClickEffects() {
        // 特定按钮的点击效果
        setupClickEffect(friend, friend1, friend2);
        setupClickEffect(avatar, avatar1, avatar2);
        setupClickEffect(info, info1, info2);
        setupClickEffect(message, message1, message2);
    }
    // 悬停效果处理(通用方法)
    private void setupHoverEffect(Button btn, ImageView normal, ImageView hover) {
        btn.setOnMouseEntered(e -> {
            if (btn != activeButton) { // 非激活状态才响应悬停
                normal.setVisible(false);
                hover.setVisible(true);
            }
        });

        btn.setOnMouseExited(e -> {
            if (btn != activeButton) { // 非激活状态才恢复
                normal.setVisible(true);
                hover.setVisible(false);
            }
        });
    }
    // 点击效果处理(特定按钮)
    private void setupClickEffect(Button btn, ImageView normal, ImageView active) {
        btn.setOnAction(e -> {
            if (btn == activeButton) {
                // 点击已激活的按钮:取消激活
                normal.setVisible(true);
                active.setVisible(false);
                activeButton = null;
            } else {
                // 取消之前的激活状态
                if (activeButton != null) {
                    resetPreviousActive();
                }

                // 设置新的激活状态
                normal.setVisible(false);
                active.setVisible(true);
                activeButton = btn;
            }
        });
    }

    private void resetPreviousActive() {
        // 根据按钮类型重置状态
        if (activeButton == friend) {
            friend1.setVisible(true);
            friend2.setVisible(false);
        } else if (activeButton == avatar) {
            avatar1.setVisible(true);
            avatar2.setVisible(false);
        } else if (activeButton == info) {
            info1.setVisible(true);
            info2.setVisible(false);
        } else if (activeButton == message) {
            message1.setVisible(true);
            message2.setVisible(false);
        }
    }

    @FXML
    void exchange(ActionEvent event) {

    }

    @FXML
    void exchangeAvatar(ActionEvent event) {

    }

    @FXML
    void exchangeFile(ActionEvent event) {

    }

    @FXML
    void exchangeInfo(ActionEvent event) {

    }

    @FXML
    void exchangeMemes(ActionEvent event) {

    }

    @FXML
    void exchangeMessage(ActionEvent event) {

    }

    @FXML
    void exchangePhoto(ActionEvent event) {

    }

    @FXML
    void exchangeVoice(ActionEvent event) {

    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2339905.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python 深度学习 第8章 计算机视觉中的深度学习 - 卷积神经网络使用实例

Python 深度学习 第8章 计算机视觉中的深度学习 - 卷积神经网络使用实例 内容概要 第8章深入探讨了计算机视觉中的深度学习&#xff0c;特别是卷积神经网络&#xff08;convnets&#xff09;的应用。本章详细介绍了卷积层和池化层的工作原理、数据增强技术、预训练模型的特征…

[免费]SpringBoot+Vue博物馆(预约)管理系统【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringBootVue博物馆(预约)管理系统&#xff0c;分享下哈。 项目视频演示 【免费】SpringBootVue博物馆(预约)管理系统 Java毕业设计_哔哩哔哩_bilibili 项目介绍 随着计算机科学技术的日渐成熟&#xff…

【python】pyCharm常用快捷键使用-(2)

pyCharm常用快捷键使用 快速导入任意类 【CTRLALTSPACE】代码补全【CTRLSHIFTENTER】代码快速修正【ALTENTER】代码调试快捷键

机器视觉lcd屏增光片贴合应用

在现代显示制造领域&#xff0c;LCD屏增光片贴合工艺堪称显示效果的"画龙点睛"之笔。作为提升屏幕亮度、均匀度和色彩表现的关键光学组件&#xff0c;增光片的贴合精度直接影响着终端用户的视觉体验。传统人工贴合方式难以满足当前超窄边框、高分辨率显示屏的严苛要求…

VScode-py环境

settings.json {"git.ignoreLimitWarning": true,"code-runner.runInTerminal": true,"code-runner.executorMap": {"python": "python3"} } 第二句话保证在终端里面进行IO 第三句话保证python3的用户不会执行python关键…

用键盘实现控制小球上下移动——java的事件控制

本文分享Java的一个有趣小项目&#xff0c;实现用键盘控制小球的移动 涉及java知识点&#xff1a;Swing GUI框架&#xff0c;绘图机制&#xff0c;事件处理&#xff0c;焦点控制 1.编写窗口和面板 (1.)定义面板类 Panel 继承自Java 自带类JPanel (2.)定义窗口类 window 继承…

《马尼拉》桌游期望计算器

《马尼拉》桌游期望计算器&#xff1a;做出最明智的决策 注&#xff1a;本项目仍在开发验证中&#xff0c;计算结果可能不够准确&#xff0c;欢迎游戏爱好者提供协助&#xff01; 在线使用 | GitHub 项目简介 马尼拉期望计算器是一个基于 Vue 3 Vite 开发的网页应用&#xff…

动态LOD策略细节层级控制:根据视角距离动态简化远距量子态渲染

动态LOD策略在量子计算可视化中的优化实现 1. 细节层级控制:动态简化远距量子态渲染 在量子计算的可视化中,量子态通常表现为高维数据(如布洛赫球面或多量子比特纠缠态)。动态LOD(Level of Detail)策略通过以下方式优化渲染性能: 距离驱动的几何简化: 远距离渲染:当…

线程池的介绍

目录 一、什么是线程池 二、线程池的详细内容 三、线程池的简化 一、什么是线程池 提到线程池&#xff0c;我们可能想到 常量池&#xff0c;可以先来说说常量池&#xff1a; 像是字符串常量&#xff0c;在Java程序最初构建的时候&#xff0c;就已经准备好了&#xff0c;等程…

安恒安全渗透面试题

《网安面试指南》https://mp.weixin.qq.com/s/RIVYDmxI9g_TgGrpbdDKtA?token1860256701&langzh_CN 5000篇网安资料库https://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247486065&idx2&snb30ade8200e842743339d428f414475e&chksmc0e4732df793fa3bf39…

计算机是如何工作的(上)

对于学习JavaEE初阶为什么要知道计算机是如何工作的&#xff0c;是因为在未来我们写代码的时候&#xff0c;会出现一些bug&#xff0c;而在代码层面是看不出来的&#xff0c;所以我们需要了解一些关于计算机内部是如何工作的&#xff0c;从而提高代码的健壮度。 计算机的组成&…

基础服务系列-Windows10 安装AnacondaJupyter

下载 https://www.anaconda.com/products/individual 安装 安装Jupyter 完成安装 启动Jupyter 浏览器访问 默认浏览器打开&#xff0c;IE不兼容&#xff0c;可以换个浏览器 修改密码 运行脚本

Kubernetes架构介绍

实验环境 安装好k8s集群 一、kubernetes组件构成 1、架构图 2、组件介绍 使用以下命令查看相关资源 kubectl get nodes 查看群集节点 kubectl get ns 查看名称空间 kubectl get pod -A …

远程服务器的mysql连接不上,问题出在哪里

使用本地ideal测试连接报错记录 排查 检查mysql服务是否正常,输入命令systemctl status mysql查看 检查端口netstat -plnt | grep mysql 最后检查服务器的防火墙设置 我以为在服务器厂商的控制面板设置放行规则就行&#xff0c;导致一直无法排查出问题&#xff0c;最后才发现由…

Java高频面试之并发编程-04

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本baby今天来报道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面试官&#xff1a;调用 start()方法时会执行 run()方法&#xff0c;那为什么不直接调用 run()方法&#xff1f; 多线程中调用 start() 方法…

【第16届蓝桥杯软件赛】CB组第一次省赛

个人主页&#xff1a;Guiat 归属专栏&#xff1a;算法竞赛 文章目录 A. 移动距离&#xff08;5分填空题&#xff09;B. 客流量上限&#xff08;5分填空题&#xff09;C. 可分解的正整数D. 产值调整E. 画展布置F. 水质检测G. 生产车间H. 装修报价 正文 总共10道题。 A. 移动距离…

云原生--基础篇-2--云计算概述(云计算是云原生的基础,IaaS、PaaS和SaaS服务模型)

1、云计算概念 云计算是一种通过互联网提供计算资源&#xff08;包括服务器、存储、数据库、网络、软件等&#xff09;和服务的技术模式。用户无需拥有和维护物理硬件&#xff0c;而是可以根据需要租用这些资源&#xff0c;并按使用量付费。 2、云计算特点 &#xff08;1&am…

vllm+vllm-ascend本地部署QwQ-32B

1 模型下载 可按照此处方法下载预热后的模型&#xff0c;速度较快&#xff08;推荐artget方式&#xff09; https://mirrors.tools.huawei.com/mirrorDetail/67b75986118b030fb5934fc7?mirrorNamehuggingface&catalogllms或者从hugging face官方下载。 2 vllm-ascend安…

栈和队列--数据结构初阶(2)(C/C++)

文章目录 前言理论部分栈的模拟实现STL中的栈容器队列的模拟实现STL中的队列容器 作业部分 前言 这期的话会给大家讲解栈和队列的模拟实现和在STL中栈和队列怎么用的一些知识和习题部分(这部分侧重于理论知识&#xff0c;习题倒还是不难) 理论部分 栈的模拟实现 typedef int…

C++常用函数合集

万能头文件&#xff1a;#include<bits/stdc.h> 1. 输入输出流&#xff08;I/O&#xff09;函数 1.1cin 用于从标准输入流读取数据。 1.2cout 用于向标准输出流写入数据。 // 输入输出流&#xff08;I/O&#xff09;函数 #include <iostream> using namespace…