JLayeredPane分层面板叠加

wen java案例 2

JLayeredPane 分层面板叠加详解

JLayeredPane 是 Java Swing 中用于实现图层叠加管理的容器,允许组件在 Z 轴方向分层显示。

JLayeredPane分层面板叠加

核心概念

层级结构:底层 → 高层

Integer.MAX_VALUE (Draggable组件)
      ↓
300 (弹出窗口/对话框)
      ↓
200 (调色板/浮动工具)
      ↓
100 (默认层)
      ↓
-30000 (最低层)

预定义层级常量

常量 用途
DEFAULT_LAYER 0 标准组件层
PALETTE_LAYER 100 工具面板层
MODAL_LAYER 200 模态对话框层
POPUP_LAYER 300 弹出窗口层
DRAG_LAYER 400 拖拽组件层

基本使用方法

import javax.swing.*;
import java.awt.*;
public class LayeredPaneExample extends JFrame {
    public LayeredPaneExample() {
        setTitle("JLayeredPane 示例");
        setSize(400, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 创建分层面板
        JLayeredPane layeredPane = new JLayeredPane();
        layeredPane.setPreferredSize(new Dimension(400, 300));
        // 创建三个不同颜色的面板
        JPanel redPanel = createColoredPanel(Color.RED, 300, 200);
        redPanel.setBounds(20, 20, 300, 200);
        JPanel greenPanel = createColoredPanel(Color.GREEN, 250, 150);
        greenPanel.setBounds(50, 50, 250, 150);
        JPanel bluePanel = createColoredPanel(Color.BLUE, 200, 100);
        bluePanel.setBounds(80, 80, 200, 100);
        // 添加到不同层级
        layeredPane.add(redPanel, JLayeredPane.DEFAULT_LAYER);    // 层级0
        layeredPane.add(greenPanel, JLayeredPane.PALETTE_LAYER); // 层级100
        layeredPane.add(bluePanel, JLayeredPane.MODAL_LAYER);    // 层级200
        add(layeredPane);
        pack();
        setLocationRelativeTo(null);
    }
    private JPanel createColoredPanel(Color color, int width, int height) {
        JPanel panel = new JPanel();
        panel.setBackground(color);
        panel.setSize(width, height);
        return panel;
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new LayeredPaneExample().setVisible(true);
        });
    }
}

图层操作核心方法

// 添加组件到指定层级
layeredPane.add(component, layer);
layeredPane.add(component, new Integer(layer));
// 同时设置位置
layeredPane.add(component, JLayeredPane.MODAL_LAYER, 1); // 第二个参数是层,第三个是位置索引
// 移动图层
layeredPane.setLayer(component, newLayer);
// 获取组件的层级
int layer = layeredPane.getLayer(component);
// 获取某层上的组件
Component[] components = layeredPane.getComponentsInLayer(layer);
// 改变图层顺序
layeredPane.moveToFront(component);    // 移到最前
layeredPane.moveToBack(component);     // 移到最后

完整示例:可拖拽的卡片

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class DragCardExample extends JFrame {
    private JLayeredPane layeredPane;
    private Point mouseOffset;
    public DragCardExample() {
        setTitle("可拖拽卡片示例");
        setSize(500, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        layeredPane = new JLayeredPane();
        layeredPane.setPreferredSize(new Dimension(500, 400));
        // 创建三个卡片
        JPanel card1 = createCard("卡片1", Color.RED, 100, 100);
        JPanel card2 = createCard("卡片2", Color.GREEN, 200, 150);
        JPanel card3 = createCard("卡片3", Color.BLUE, 150, 80);
        // 添加卡片到不同层级
        layeredPane.add(card1, JLayeredPane.DEFAULT_LAYER);
        layeredPane.add(card2, JLayeredPane.PALETTE_LAYER);
        layeredPane.add(card3, JLayeredPane.MODAL_LAYER);
        add(layeredPane);
        pack();
        setLocationRelativeTo(null);
    }
    private JPanel createCard(String text, Color bgColor, int x, int y) {
        JPanel card = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                setBackground(bgColor);
            }
        };
        card.setBounds(x, y, 120, 80);
        card.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
        JLabel label = new JLabel(text, SwingConstants.CENTER);
        label.setForeground(Color.WHITE);
        label.setFont(new Font("Arial", Font.BOLD, 14));
        card.add(label);
        // 添加拖拽功能
        addDragFunctionality(card);
        return card;
    }
    private void addDragFunctionality(JPanel card) {
        card.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                // 当点击时,将卡片移到最上层
                layeredPane.moveToFront(card);
                // 记录鼠标偏移
                mouseOffset = SwingUtilities.convertPoint(
                    card, e.getPoint(), layeredPane);
                // 更新卡片位置
                Point cardLocation = card.getLocation();
                mouseOffset.x -= cardLocation.x;
                mouseOffset.y -= cardLocation.y;
            }
        });
        card.addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                // 计算新位置
                Point parentPoint = SwingUtilities.convertPoint(
                    card, e.getPoint(), layeredPane);
                int newX = parentPoint.x - mouseOffset.x;
                int newY = parentPoint.y - mouseOffset.y;
                // 边界限制
                newX = Math.max(0, Math.min(newX, layeredPane.getWidth() - card.getWidth()));
                newY = Math.max(0, Math.min(newY, layeredPane.getHeight() - card.getHeight()));
                card.setLocation(newX, newY);
            }
        });
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new DragCardExample().setVisible(true);
        });
    }
}

注意事项

  1. 必须设置组件位置和大小:使用 setBounds()setLocation() + setSize()
  2. 图层顺序:层级值越大,显示在最上面
  3. 透明度:上层组件的透明部分会显示下层组件
  4. 布局管理器:建议不使用布局管理器,手动设置位置
  5. 性能:大量图层叠加可能影响性能

应用场景

  • 图像编辑软件(图层管理)
  • 游戏开发(角色、背景、特效分层)
  • 桌面应用(浮动工具栏、弹窗)
  • 地图应用(不同信息层)

通过 JLayeredPane,你可以轻松实现复杂的界面叠加效果,创建更丰富的用户交互体验。

抱歉,评论功能暂时关闭!