Mayukh Nair
Mayukh Nair

Reputation: 653

Layering text over JLabel

enter image description here

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.

Upvotes: 0

Views: 916

Answers (2)

MadProgrammer
MadProgrammer

Reputation: 347184

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...

Speech Bubble

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...

Upvotes: 1

mttdbrd
mttdbrd

Reputation: 1831

It sounds like you just want to add a z-order. If so, you need a LayeredPane:

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

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

Upvotes: 0

Related Questions