问题
How can I add a button over an image created with JLabel? Even if I put the same coordinates on ".setbounds" the image usually gets behind the buttons.
public class Tatica extends JFrame {
JPanel jl = new JPanel();
JLabel jp = new JLabel();
public Tatica(){
jl.setLayout(null);
jp.setIcon(new ImageIcon("C:\\Users\\LG\\workspace\\Teste\\src\\snippet\\asdiuashd.Jpg"));
jl.add(jp);
add(jl);
jp.setBounds(100, 0, 1000, 1000);
validate();
JButton team2 = new JButton("Gk");
jl.add(team2);
team2.setBounds(400, 0, 100, 20);
team2.setVisible(true);
team2.setLayout(null);
JButton dc = new JButton("Dc");
jl.add(dc);
dc.setBounds(300, 200, 100, 20);
dc.setVisible(true);
JButton dc2 = new JButton("Dc");
jl.add(dc2);
dc2.setBounds(500, 200, 100, 20);
dc2.setVisible(true);
JButton dl = new JButton("Dl");
jl.add(dl);
dl.setBounds(100, 200, 100, 20);
dl.setVisible(true);
JButton dr = new JButton("Dr");
jl.add(dr);
dr.setBounds(700, 200, 100, 20);
dr.setVisible(true);
}
}
回答1:
How can I add a button over an image created with JLabel?
Add the buttons to the label, not the panel.
So the basic code is:
JPanel panel = new JPanel();
JLabel label = new JLabel( new ImageIcon(...) );
label.setLayout( new FlowLayout() );
JButton button1 = new JButton("Button1");
label.add(button1);
JButton button2 = new JButton("Button1");
label.add(button2);
So now the label will be the size of the image. The buttons will be displayed in a FlowLayout on the image. It is your responsibility to make sure the buttons fit on the image or the buttons will not be displayed properly.
The question is do you really need to add the label to the panel or should you just add the label to the frame?
回答2:
I'd instead slice up the image and use the sub-images as icons for either buttons or labels. Then arrange them all in a GridBagLayout
.
Here is an example of what I mean (special thanks to @camickr for solving the bug in my layout code!):
(It uses a an icon with a transparent shade of white for mouse hover, black for pressed. The mouse was pointing at the left center forward when the screen shot was taken. It is left as an exercise for the reader to implement the logic needed to alternate between labels and buttons as required, in the GUI formed from 81 sub images.)
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.net.URL;
import javax.imageio.ImageIO;
public class SoccerField {
private JPanel ui = null;
int[] x = {0, 35, 70, 107, 142, 177, 212, 247, 282, 315};
int[] y = {0, 45, 85, 140, 180, 225, 265, 280, 320, 345};
Color brighter = new Color(255,255,255,92);
Color darker = new Color(0,0,0,92);
SoccerField() {
initUI();
}
public void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new GridBagLayout());
ui.setBackground(Color.RED);
try {
URL url = new URL("http://i.stack.imgur.com/9E5ky.jpg");
BufferedImage img = ImageIO.read(url);
BufferedImage field = img.getSubimage(100, 350, 315, 345);
BufferedImage[] bi = subSampleImageColumns(field);
BufferedImage[][] fieldParts = new BufferedImage[bi.length][];
for (int ii=0; ii<bi.length; ii++) {
fieldParts[ii] = subSampleImageRows(bi[ii]);
}
for (int ii=0; ii<fieldParts[0].length; ii++) {
for (int jj=0; jj<fieldParts.length; jj++) {
addImageToPanel(ui, fieldParts[ii][jj], ii, jj);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void addImageToPanel(
JPanel panel, BufferedImage img, int row, int col) {
Insets insets = new Insets(0,0,0,0);
double weighty = img.getHeight()==40 ? .5 : .1;
GridBagConstraints gbc = new GridBagConstraints(
row, col,
1, 1,
.5, weighty,
GridBagConstraints.CENTER,
GridBagConstraints.BOTH,
insets, 0, 0);
ImageIcon ii = new ImageIcon(img);
JButton b = new JButton(ii);
b.setRolloverIcon(new ImageIcon(getFadeImage(img, brighter)));
b.setPressedIcon(new ImageIcon(getFadeImage(img, darker)));
b.setBorder(null);
b.setBorder(new EmptyBorder(0, 0, 0, 0));
b.setBorderPainted(false);
b.setContentAreaFilled(false);
b.setFocusPainted(false);
panel.add(b, gbc);
}
private BufferedImage[] subSampleImageColumns(BufferedImage img) {
BufferedImage[] imageRows = new BufferedImage[x.length - 1];
for (int ii = 0; ii < x.length - 1; ii++) {
BufferedImage bi = img.getSubimage(
x[ii], 0, x[ii + 1] - x[ii], img.getHeight());
imageRows[ii] = bi;
}
return imageRows;
}
private BufferedImage[] subSampleImageRows(BufferedImage img) {
BufferedImage[] imageRows = new BufferedImage[y.length - 1];
for (int ii = 0; ii < y.length - 1; ii++) {
BufferedImage bi = img.getSubimage(
0, y[ii], img.getWidth(), y[ii + 1] - y[ii]);
imageRows[ii] = bi;
}
return imageRows;
}
private BufferedImage getFadeImage(BufferedImage img, Color clr) {
BufferedImage bi = new BufferedImage(
img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics g = bi.getGraphics();
g.drawImage(img, 0, 0, ui);
g.setColor(clr);
g.fillRect(0, 0, img.getWidth(), img.getHeight());
g.dispose();
return bi;
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
SoccerField o = new SoccerField();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
来源:https://stackoverflow.com/questions/32529578/add-a-button-over-image