效果如图
 
 
模态框是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);
    }
    
    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);
    }
    
    @Override
    protected void render() {
        view.add(layeredPane, "w 100%,h 100%");
        
        layeredPane.setLayout(new MigLayout("wrap 1,w 100%,h 100%"));
        layeredPane.setLayer(content, JLayeredPane.DEFAULT_LAYER);
        layeredPane.add(content, "w 100%,h 100%");
        
        layeredPane.setLayer(modalMask, JLayeredPane.PALETTE_LAYER);
        layeredPane.add(modalMask, "pos 0.5al 0.5al,w 100%,h 100%");
        
        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);
        });
    }
    
    void setContentEnables(boolean enable) {
        Component[] components = content.getComponents();
        for (Component comp : components) {
            comp.setEnabled(enable);
            System.out.println("当前节点:" + comp);
            
            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());
    }
}