在具有图像的JLabel上方放置另一个JLabel

5

我相信这个问题以前已经被问过了,但我的情况略有不同,因为我试图将一个JLabel放在充当背景的另一个JLabel的顶部,我想使用JLabels显示变化的数字,并且这些数字需要显示在背景上方,但我对Swing不太熟悉,提前感谢,Jonathan


1
可以做到,但是如果你只说出你想要的而不告诉我们你尝试过什么或者你卡在哪里了,那就有点难帮助你了。请通过改进这个问题来帮助我们帮助你,包括展示你的代码尝试,最好是一个sscce。关于如何帮助我们,请查看Jon Skeet的博客:提问的完美方式 - Hovercraft Full Of Eels
你有什么问题吗?即使你认为很明显,加上一个明确的问题也是值得的。 - Andrew Thompson
这是Jon Skeet博客中编写好问题的新简短清单。此处链接到该清单。 - Adil
3个回答

10

如果您只需要在背景图像上显示文本,而没有充分了解您的需求,最好将标签放置在自定义面板的顶部,该面板能够绘制您的背景。

这样您就能获得布局管理器的好处,不会出现混乱。

我建议首先阅读执行自定义绘制Graphics2D Trail

如果那似乎令人生畏,JLabel实际上是一种Container类型,这意味着它实际上可以“包含”其他组件。

示例

背景窗格...

public class PaintPane extends JPanel {

    private Image background;

    public PaintPane(Image image) {     
        // This is just an example, I'd prefer to use setters/getters
        // and would also need to provide alignment options ;)
        background = image;            
    }

    @Override
    public Dimension getPreferredSize() {
        return background == null ? new Dimension(0, 0) : new Dimension(background.getWidth(this), background.getHeight(this));            
    }

    @Override
    protected void paintComponent(Graphics g) {

        super.paintComponent(g);

        if (background != null) {                
            Insets insets = getInsets();

            int width = getWidth() - 1 - (insets.left + insets.right);
            int height = getHeight() - 1 - (insets.top + insets.bottom);

            int x = (width - background.getWidth(this)) / 2;
            int y = (height - background.getHeight(this)) / 2;

            g.drawImage(background, x, y, this);                
        }

    }

}

用以下参数构造...

public TestLayoutOverlay() throws IOException { // Extends JFrame...

    setTitle("test");
    setLayout(new GridBagLayout());
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    PaintPane pane = new PaintPane(ImageIO.read(new File("fire.jpg")));
    pane.setLayout(new BorderLayout());
    add(pane);

    JLabel label = new JLabel("I'm on fire");
    label.setFont(label.getFont().deriveFont(Font.BOLD, 48));
    label.setForeground(Color.WHITE);
    label.setHorizontalAlignment(JLabel.CENTER);
    pane.add(label);

    pack();
    setLocationRelativeTo(null);
    setVisible(true);

}

为了证明我没有偏见,这里提供一个使用标签的例子...

public TestLayoutOverlay() {

    setTitle("test");
    setLayout(new GridBagLayout());
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    JLabel background = new JLabel(new ImageIcon("fire.jpg"));
    background.setLayout(new BorderLayout());
    add(background);

    JLabel label = new JLabel("I'm on fire");
    label.setFont(label.getFont().deriveFont(Font.BOLD, 48));
    label.setForeground(Color.WHITE);
    label.setHorizontalAlignment(JLabel.CENTER);
    background.add(label);

    pack();
    setLocationRelativeTo(null);
    setVisible(true);

}

着火了


1
是的,我在最后暗示了那个,但对我来说似乎有些混乱,不是说不能做,只是我没有问题的上下文 :P - MadProgrammer
谢谢,我认为这将是最好的方法,你能给我提供一个代码示例吗? - Excalibur
程序员的便宜笑话真是让人爱不释手 :) 非常感谢,这是我正在开发的一套测验系统所需。 - Excalibur

0

在运行时:

  • 从其父级中移除标签
  • 添加一个支持层的容器
  • 添加2x层,但保持Z顺序

享受吧。(没有完整的可复制粘贴的代码)


2
“将标签从其父级中移除”是什么意思?为什么不能将JLabel添加到另一个JLabel上,因为这是完全可行和可行的呢? - Hovercraft Full Of Eels

-3

你可以通过以下方式实现:

JLabel l1=new JLabel();
JLabel l2=new JLabel();
l1.add(l2, JLabel.NORTH);

2
JLabel 具有与 JComponent 相同的默认 null 布局。 - trashgod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接