Reputation: 653
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
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...
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
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