【问题标题】:Layering text over JLabel在 JLabel 上分层文本
【发布时间】:2014-04-29 04:55:29
【问题描述】:

这就是我希望我的应用看起来的样子。

问题是,如果我将带有“你好,我是 Myra”的 JLabel 拖到另一个 JLabel(其图标是对话气泡)上,而不是叠加或分层,NetBeans 会将 JLabel 移动到相邻的位置。

我如何叠加ie。将文本 JLabel 放在另一个 JLabel 之上?

请注意,我使用的是 NetBeans。它不允许我编辑大部分 JFrame 或 JLabel 代码。

【问题讨论】:

    标签: java swing netbeans jpanel jlabel


    【解决方案1】:

    Netbeans 不允许您将组件添加到 JLabel,它不会将它们视为有效的 Container

    使用组件标签很难做到这一点,因为图标的位置不在您的控制范围内。更好的解决方案可能是使用自定义组件,例如 JPanel 并自己手动绘制语音气泡图像,然后使用 BorderLayoutManager 的组合,它可以让您向其中添加其他组件

    这是一个非常基本的例子……

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GridLayout;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.border.EmptyBorder;
    
    public class SpeechBubble {
    
        public static void main(String[] args) {
            new SpeechBubble();
        }
    
        public SpeechBubble() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    SpeechBubblePane bubble = new SpeechBubblePane();
                    JLabel hello = new JLabel("Hello, I'm Myra");
                    hello.setFont(hello.getFont().deriveFont(28f));
                    hello.setForeground(Color.CYAN);
    
                    JLabel message = new JLabel("<html>What would you like to know today?</html>");
                    message.setFont(message.getFont().deriveFont(22f));
                    message.setForeground(Color.WHITE);
    
                    bubble.setLayout(new GridLayout(2, 1));
                    bubble.add(hello);
                    bubble.add(message);
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.getContentPane().setBackground(Color.BLACK);
                    frame.add(bubble);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class SpeechBubblePane extends JPanel {
    
            private BufferedImage background;
    
            public SpeechBubblePane() {
                setOpaque(false);
                try {
                    background = ImageIO.read(getClass().getResource("/speechbubble.png"));
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                setBorder(new EmptyBorder(19, 19, 66, 19));
            }
    
            @Override
            public Dimension getPreferredSize() {
                Dimension size = new Dimension(200, 200);
                if (background != null) {
                    size = new Dimension(background.getWidth(), background.getHeight());
                }
                return size;
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                if (background != null) {
                    Graphics2D g2d = (Graphics2D) g.create();
                    int x = (getWidth() - background.getWidth()) / 2;
                    int y = (getHeight()- background.getHeight()) / 2;
                    g2d.drawImage(background, x, y, this);
                    g2d.dispose();
                }
            }
        }
    
    }
    

    如果我这样做,我会考虑开发一个“9 路径”,它允许您将图像分解为 9 个部分并根据内容需要缩放外部部分,例如...

    【讨论】:

    • OP 只想将一个标签放在另一个标签之上,即添加一个 z 顺序。使用 LayeredPanes 非常有可能。
    • @mttdbrd 这是一种方法,但没有考虑到当对话气泡上方的内容超出其界限时会发生什么。同样,您可以使用GridBagLayout 实现此目的;)
    • 哇。我认为我的解决方案更简单、更干净,但如果你在 5 分钟内编写了一个非常完整的代码示例,你会得到 +1。
    • @mttdbrd 您也可以使用OverlayLayout 经理创建相同的效果,这比JLayeredPane 更容易...根据我的经验...但这些都没有考虑到什么如果顶级内容超出图像范围,则会发生...
    • @mttdbrd 这就是我解决问题的方法,但我希望使用 9-patch 图像来处理可变大小的内容...
    【解决方案2】:

    听起来您只想添加 z 顺序。如果是这样,你需要一个LayeredPane

    http://docs.oracle.com/javase/7/docs/api/index.html

    http://docs.oracle.com/javase/7/docs/api/javax/swing/JLayeredPane.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-31
      • 1970-01-01
      • 2013-03-17
      • 1970-01-01
      • 2021-08-06
      • 1970-01-01
      相关资源
      最近更新 更多