swing-组件modal模态框1

本文详细介绍了如何在Swing中利用JLayeredPane实现模态框组件,包括创建文本域、按钮、遮罩层及模态框内容,并讨论了在模态框弹出时禁用底层组件可能遇到的样式问题。通过事件监听控制模态框的显示与关闭,以及对组件启用状态的管理,实现了类似iframe的层级效果。
摘要由CSDN通过智能技术生成

效果如图

在这里插入图片描述

模态框是web开发中常用的一种组件,可以用作页面的内容的拓展\交互\提示等等, swing常见的组件不包含模态框, 窗口内组件jdialog或者jwindow的弹窗更像iframe那种二级窗口.
思路
  • JLayeredPane 是一种层级面板,和h5中通过堆加zindex实现模态框层级是一样的.
  • 所以默认内容作为第一层, 遮罩作为第二层(某些场景可以去除遮罩,或者设置透明度为0),模态框作为第三层
  • 模态框弹出时禁用第一层的所有按钮, 当然也可以在事件中控制 点击第一层关闭第三层的模态框.(点击蒙层可关闭效果)
问题
  • 禁用第一层的面板组件之后,带来的问题就是模态框弹出时, 按钮的样式变了.

demo测试代码

dependencies:
  • hutool (常用工具)
  • flatlaf (美化)
  • miglayout (布局)
  • swingx-all (拓展组件)
com.mynote.core.**
  • ColorBuilder 只是我常用的一些颜色汇总
  • FrameUtil 只是为了快速测试JFrame使用
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.formdev.flatlaf.FlatLightLaf;
import com.mynote.core.ui.ColorBuilder;
import com.mynote.core.util.FrameUtil;
import net.miginfocom.swing.MigLayout;
import org.jdesktop.swingx.JXPanel;

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

/**
 * 模态框效果
 */
public class ModalPanelTest extends AbstractDefaultPanel {

    private JButton showModal;

    private JTextArea textArea;

    private JLayeredPane layeredPane;

    private JPanel content;

    private JXPanel modalMask;

    private JButton closeModal;

    private JXPanel modalContent;


    /**
     * 初始化成员对象
     */
    @Override
    protected void init() {
        layeredPane = new JLayeredPane();
        createTextArea();
        createModalButton();
        createModalMask();
        createModalContent();
        content = new JPanel();
        content.setLayout(new MigLayout("wrap 1"));
        content.add(showModal, "align right");
        content.add(new JScrollPane(textArea), "w 100%,h 100%");
    }

    /**
     * 创建按钮
     */
    void createModalButton() {
        showModal = new JButton("showModal");
        showModal.setBackground(ColorBuilder.BG_RED_COLOR1);
        showModal.setForeground(ColorBuilder.LABEL_WHITE_COLOR1);
        closeModal = new JButton("closeModal");
    }

    /**
     * 创建文本域
     */
    void createTextArea() {
        textArea = new JTextArea(RandomUtil.randomString(3000));
        textArea.setLineWrap(true);
    }

    /**
     * 创建遮罩层
     */
    void createModalMask() {
        modalMask = new JXPanel();
        modalMask.setLayout(new MigLayout("w 100%,h 100%"));
        modalMask.setAlpha(0.5F);
        modalMask.setOpaque(false);
        modalMask.setBackground(ColorBuilder.LABEL_GRAY_COLOR1);
        modalMask.setVisible(false);
    }


    /**
     * 创建modal面板
     */
    void createModalContent() {
        modalContent = new JXPanel();
        modalContent.setLayout(new MigLayout("wrap 1,center"));
        modalContent.add(new JLabel(DateUtil.now()),"gaptop 50");
        modalContent.add(new JTextField(), "w 200");
        modalContent.setBackground(ColorBuilder.LABEL_WHITE_COLOR1);
        modalContent.add(closeModal, "pos 1al 1al");
        modalContent.setVisible(false);
    }


    /**
     * render视图
     */
    @Override
    protected void render() {
        view.add(layeredPane, "w 100%,h 100%");
        // content 默认显示
        layeredPane.setLayout(new MigLayout("wrap 1,w 100%,h 100%"));
        layeredPane.setLayer(content, JLayeredPane.DEFAULT_LAYER);
        layeredPane.add(content, "w 100%,h 100%");

        // modalmask 绝对位置显示遮罩
        layeredPane.setLayer(modalMask, JLayeredPane.PALETTE_LAYER);
        layeredPane.add(modalMask, "pos 0.5al 0.5al,w 100%,h 100%");

        // modalcontent 绝对位置显示模态框
        layeredPane.setLayer(modalContent, JLayeredPane.MODAL_LAYER);
        layeredPane.add(modalContent, "pos 0.5al 0.5al,w 70%,h 70%");

        super.add(view, "w 100%,h 100%");
    }


    /**
     * 绑定事件
     */
    @Override
    protected void bindEvents() {
        showModal.addActionListener((e) -> {
            modalMask.setVisible(true);
            modalContent.setVisible(true);
            setContentEnables(false);
        });

        closeModal.addActionListener((e) -> {
            modalMask.setVisible(false);
            modalContent.setVisible(false);
            setContentEnables(true);
        });
    }

    /**
     * 是否禁用content面板
     *
     * @param enable
     */
    void setContentEnables(boolean enable) {
        Component[] components = content.getComponents();
        for (Component comp : components) {
            comp.setEnabled(enable);
            System.out.println("当前节点:" + comp);
            // jscrollpanel 需要找到viewport 特殊处理
            if (comp instanceof JScrollPane) {
                JViewport scrollView = (JViewport) ((JScrollPane) comp).getComponent(0);
                Component[] scrollViewComps = scrollView.getComponents();
                for (Component scrollViewComp : scrollViewComps) {
                    System.out.println("scroll节点:" + scrollViewComp);
                    scrollViewComp.setEnabled(enable);
                }
            }
        }
    }


    public static void main(String[] args) {
        FlatLightLaf.install();
        FrameUtil.launchTest(new ModalPanelTest());
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值