JDesktopPane 中类似于桌面快捷方式的图标

Icons similar to desktop shortcuts inside JDesktopPane

由于我们在软件中使用 JDesktopPaneJInternalFrames,我想知道我们是否可以使用快捷方式图标(针对特定框架)放置在桌面窗格内(类似于 Windows 桌面快捷方式)。我搜索了这个但没有运气。

大家有什么想法可以实现这一点吗??

以下是不是的"good"解决方案,但对于某些应用案例来说可能还可以。主要的困难是这里发挥作用的中心 class 是 JInternalFrame.JDesktopIcon,而这个 class 的文档包含一个

警告:

This API should NOT BE USED by Swing applications, as it will go away in future versions of Swing as its functionality is moved into JInternalFrame.

然而,JInternalFrame 中的相应功能根本不存在。尽管必须接受 JDesktopIcon class 可能会 在未来的版本中被删除,但考虑到这个 [= 的广泛使用,对我来说这似乎不太可能39=] 在内部 Swing UI 实现中。

但是:实现此目的的一种选择是创建 BasicDesktopIconUI 的自定义扩展。幸运的是,这个 class 可以处理大部分的管理工作,例如拖动支持和双击时取消图标化框架。

因此,可以轻松地将自定义图标潜入这样的实现中(我在这里只使用了一个占位符:黑色背景上的红叉。但它可以是任意的 Image。)

这在此处作为 MCVE 实现。一般 UI 处理在实际应用程序中可能会有所不同,但基本思想是创建自定义 UI class 并将其分配给内部框架图标。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.LayoutManager;
import java.awt.image.BufferedImage;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicDesktopIconUI;

class SimpleDesktopIconUI extends BasicDesktopIconUI
{
    private final Icon icon;

    SimpleDesktopIconUI(Icon icon)
    {
        this.icon = icon;
    }

    @Override
    protected void installComponents()
    {
        frame = desktopIcon.getInternalFrame();
        String title = frame.getTitle();

        JLabel label = new JLabel(title, icon, SwingConstants.CENTER);
        label.setVerticalTextPosition(JLabel.BOTTOM);
        label.setHorizontalTextPosition(JLabel.CENTER);

        desktopIcon.setBorder(null);
        desktopIcon.setOpaque(false);
        desktopIcon.setLayout(new GridLayout(1, 1));
        desktopIcon.add(label);
    }

    @Override
    protected void uninstallComponents()
    {
        desktopIcon.setLayout(null);
        desktopIcon.removeAll();
        frame = null;
    }

    @Override
    public Dimension getMinimumSize(JComponent c)
    {

        LayoutManager layout = desktopIcon.getLayout();
        Dimension size = layout.minimumLayoutSize(desktopIcon);
        return new Dimension(size.width + 15, size.height + 15);
    }

    @Override
    public Dimension getPreferredSize(JComponent c)
    {
        return getMinimumSize(c);
    }

    @Override
    public Dimension getMaximumSize(JComponent c)
    {
        return getMinimumSize(c);
    }
}

public class InternalFrameIconTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(() -> createAndShowGUI());
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Icon icon = new ImageIcon(createImage());

        JDesktopPane desktopPane = new JDesktopPane();

        for (int i = 0; i < 5; i++)
        {
            String title = "Test " + i;
            if (i == 2)
            {
                title = "Test 2 with longer title";
            }
            JInternalFrame internalFrame =
                new JInternalFrame(title, true, true, true, true);
            internalFrame.setBounds(20 + 50 * i, 300 - 40 * i, 160, 80);
            internalFrame.setVisible(true);
            desktopPane.add(internalFrame);

            internalFrame.getDesktopIcon().setUI(new SimpleDesktopIconUI(icon));
        }

        f.getContentPane().add(desktopPane);
        f.setSize(600, 600);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private static BufferedImage createImage()
    {
        int w = 50;
        int h = 50;
        BufferedImage image =
            new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = image.createGraphics();
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, w, h);
        g.setColor(Color.RED);
        g.drawLine(0, 0, w, h);
        g.drawLine(0, h, w, 0);
        g.dispose();
        return image;
    }
}