You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JDesktopPane内的InternalFrame上方显示错误消息

在JDesktopPane内显示错误消息的解决方案

你遇到的问题根源是JDialog是顶层窗口,默认会脱离JDesktopPane的层级,显示在所有窗口上方。要在JDesktopPane内部嵌入消息窗口,应该使用JInternalFrame——这是Swing专门为JDesktopPane设计的内部容器组件。

核心修改步骤

  • 将自定义类从继承JDialog改为继承JInternalFrame
  • 调整构造方法,适配JInternalFrame的初始化参数
  • 修改显示逻辑:将内部窗口添加到JDesktopPane中,而非直接调用setVisible(true)
  • 保留原有动画、UI组件和交互逻辑,仅替换容器类型

修改后的完整代码

自定义错误消息内部窗口类

package com.mutale.posapplication.dialogs;

import com.mutale.posapplication.scroll.ScrollBarCustom;
import com.mutale.posapplication.swing.icons.GoogleMaterialDesignIcons;
import com.mutale.posapplication.swing.icons.IconFontSwing;
import java.awt.Color;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;
import org.jdesktop.animation.timing.Animator;
import org.jdesktop.animation.timing.TimingTargetAdapter;
import javax.swing.JInternalFrame;

public class ErrorDisplay extends JInternalFrame {
    private String icon; 
    private boolean ok;
    private final Animator animator;
    private boolean show = true;

    public boolean isOk() {
        return ok;
    }

    public void setOk(boolean ok) {
        this.ok = ok;
    }

    public ErrorDisplay(String icon1) {
        // 初始化JInternalFrame:关闭可交互,其余功能禁用(保持原弹窗样式)
        super("", false, false, false, false);
        initComponents();
        icon = "1";
        panel(error_ScrollPane);
        lbMessage.setLineWrap(true);
        lbMessage.setWrapStyleWord(true);
        setOpacity(0f);
        
        // 保留原图标设置逻辑
        if(icon.equals(icon1)){      
            lbIcon.setIcon(IconFontSwing.buildIcon(GoogleMaterialDesignIcons.STORAGE, 60, new Color(254, 86, 96), new Color(113, 74, 67)));
        }else{
            lbIcon.setIcon(IconFontSwing.buildIcon(GoogleMaterialDesignIcons.REPORT_PROBLEM, 40, new Color(254, 86, 96), new Color(113, 74, 67)));
        }
        
        getContentPane().setBackground(Color.WHITE);
        // 保留原动画逻辑
        TimingTargetAdapter target = new TimingTargetAdapter() {
            @Override
            public void timingEvent(float fraction) {
                if (show) {
                    setOpacity(fraction);
                } else {
                    setOpacity(1f - fraction);
                }
            }

            @Override
            public void end() {
                if (!show) {
                    setVisible(false);
                    // 关闭后从JDesktopPane移除组件,避免内存泄漏
                    getDesktopPane().remove(ErrorDisplay.this);
                    getDesktopPane().repaint();
                }
            }
        };
        animator = new Animator(200, target);
        animator.setResolution(0);
        animator.setAcceleration(0.5f);
    }

    public void showMessage(String message, javax.swing.JDesktopPane desktopPane) {
        lbMessage.setText(message);
        // 设置窗口在JDesktopPane中居中显示
        setSize(getPreferredSize());
        int x = (desktopPane.getWidth() - getWidth()) / 2;
        int y = (desktopPane.getHeight() - getHeight()) / 2;
        setLocation(x, y);
        
        // 添加到JDesktopPane并显示
        desktopPane.add(this);
        animator.start();
        setVisible(true);
        moveToFront(); // 确保窗口在内部层级最上层
    }

    public final void panel(JScrollPane scroll) {
        scroll.getViewport().setBackground(Color.WHITE);
        scroll.setVerticalScrollBar(new ScrollBarCustom());
        JPanel p = new JPanel();
        p.setBackground(Color.WHITE);
        scroll.setCorner(JScrollPane.UPPER_RIGHT_CORNER, p);
        scroll.setBorder(new EmptyBorder(0, 0, 0, 0));
    }

    @SuppressWarnings("unchecked")
    private void initComponents() {
        jPanel1 = new javax.swing.JPanel();
        lbIcon = new javax.swing.JLabel();
        cancele = new com.mutale.posapplication.swings.Button();
        error_ScrollPane = new javax.swing.JScrollPane();
        lbMessage = new javax.swing.JTextArea();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setUndecorated(true);
        setResizable(false);

        jPanel1.setBackground(new java.awt.Color(255, 255, 255));
        jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(204, 0, 0), 2));    
        lbIcon.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);

        cancele.setBackground(new java.awt.Color(202, 5, 5));
        cancele.setText("X");
        cancele.setToolTipText("close");
        cancele.setColorGradient(new java.awt.Color(202, 5, 5));
        cancele.setEnabled(false);
        cancele.setFont(new java.awt.Font("Tahoma", 1, 12));
        cancele.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                canceleMousePressed(evt);
            }
        });

        lbMessage.setEditable(false);
        lbMessage.setColumns(3);
        lbMessage.setFont(new java.awt.Font("Times New Roman", 0, 14));
        lbMessage.setRows(4);
        lbMessage.setAutoscrolls(false);
        lbMessage.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        error_ScrollPane.setViewportView(lbMessage);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addComponent(lbIcon, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(cancele, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addComponent(error_ScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 540, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(cancele, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(lbIcon, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(1, 1, 1)
                .addComponent(error_ScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 331, Short.MAX_VALUE))
        );    

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(      
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(       
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        pack();
    }    

    private void canceleMousePressed(java.awt.event.MouseEvent evt) {                                     
        ok = true;
        closeMenu();
    }

    private void closeMenu() {
        if (animator.isRunning()) {
            animator.stop();
        }
        show = false;
        animator.start();
    }

    // Variables declaration - do not modify                     
    private com.mutale.posapplication.swings.Button cancele;
    private javax.swing.JScrollPane error_ScrollPane;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JLabel lbIcon;
    private javax.swing.JTextArea lbMessage;
    // End of variables declaration                   
}

修改后的调用代码

private boolean showAdmin_T() {
    // 获取主窗口中的JDesktopPane
    javax.swing.JDesktopPane desktopPane = fram.getDesktopPane();
    ErrorDisplay obj = new ErrorDisplay("1");
    // 传入JDesktopPane并显示消息
    obj.showMessage("你的错误消息内容", desktopPane);
    return obj.isOk();
}

关键说明

  • JInternalFrame是JDesktopPane的专属内部窗口,会受JDesktopPane的层级管理,不会跳出到外部窗口
  • 调用时必须传入JDesktopPane实例,才能将内部窗口添加到其中
  • 保留了原有的动画效果和UI样式,仅替换容器类型
  • 关闭窗口时主动从JDesktopPane移除组件,避免内存泄漏

内容的提问来源于stack exchange,提问作者kabwe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 20:55:51