在JLabel上分层文本 [英] Layering text over JLabel

查看:126
本文介绍了在JLabel上分层文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

请注意,我正在使用NetBeans.它不允许我编辑许多JFrame或JLabel代码.

解决方案

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个部分,并根据内容的需要缩放外部部分,例如...

This is how I want my app to look like.

Trouble is, if I drag the JLabel with the "Hello, I'm Myra" over another JLabel (whose icon is the speech bubble), rather than superimposing or layering, NetBeans shifts the JLabels to be adjacent.

How do I superimpose ie. place the text JLabel on top of another JLabel?

Do note, I'm using NetBeans. It doesn't allow me to edit much of the JFrame or JLabel code.

解决方案

Netbeans won't let you add components to a JLabel, it doesn't see them as a valid Container.

This won't be easily achieved using component labels, as the icon placement is outside of your control. A better solution might be to use a custom component, such as a JPanel and manually draw the speech bubble image yourself, then using a combination of Border and LayoutManager it would allow you to add other components to it

This is a very basic example...

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();
            }
        }
    }

}

If I was doing this, I would consider developing up a "9-path" which would allow you to break the image down into 9 parts and scale the outer sections based on what the content requires, for example...

这篇关于在JLabel上分层文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆