Reputation: 77
I would like to set two or more icons to one JButton (Java, Swing). Is it possible?
I add picture made in drawing. ;-)
Upvotes: 0
Views: 619
Reputation: 168825
Are those two icons (happy / sad) literally the icons required? If so, I'd suggest instead using a JCheckBox
and setting the icons as the default and selected icon (so the check box changes between them on selection).
Here's how (using a red icon for happy, and blue icon for sad).
import java.awt.*;
import java.io.IOException;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.net.*;
import javax.imageio.ImageIO;
public class CheckBoxWithIcons {
private JComponent ui = null;
Image happyImage;
Image sadImage;
CheckBoxWithIcons() {
try {
initUI();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public final void initUI() throws MalformedURLException, IOException {
if (ui!=null) return;
happyImage = ImageIO.read(new URL("https://i.sstatic.net/wCF8S.png"));
sadImage = ImageIO.read(new URL("https://i.sstatic.net/gJmeJ.png"));
ui = new JPanel(new BorderLayout(4,4));
ui.setBorder(new EmptyBorder(4,100,4,100));
JCheckBox checkBox = new JCheckBox("Mood", true);
checkBox.setIcon(new ImageIcon(sadImage));
checkBox.setSelectedIcon(new ImageIcon(happyImage));
ui.add(checkBox);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = () -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
CheckBoxWithIcons o = new CheckBoxWithIcons();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
};
SwingUtilities.invokeLater(r);
}
}
Upvotes: 1
Reputation: 962
The best way to achieve this is by creating a custom class that implements the Icon
interface, which simply paints two given icons side by side.
public class TwoIcon implements Icon {
private final int iconGap = 2;
private final Icon icon1;
private final Icon icon2;
public TwoIcon(final Icon icon1, final Icon icon2) {
this.icon1 = icon1;
this.icon2 = icon2;
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
int mid = getIconHeight() / 2;
int y1 = y + mid - icon1.getIconHeight() / 2;
int y2 = y + mid - icon2.getIconHeight() / 2;
icon1.paintIcon(c, g, x, y1);
icon2.paintIcon(c, g, x + icon1.getIconWidth() + iconGap, y2);
}
@Override
public int getIconWidth() {
return icon1.getIconWidth() + icon2.getIconWidth() + iconGap;
}
@Override
public int getIconHeight() {
return Math.max(icon1.getIconHeight(), icon2.getIconHeight());
}
}
The icons will be painted side by side with a padding of 2
and centered vertically.
Play around with the spacing if you want them to be aligned differently.
Icon leftIcon = ...
Icon rightIcon = ...
button.setIcon(new TwoIcon(leftIcon, rightIcon));
Result:
I am simply using Icons that paint a solid colour here. One is 16x16
and the other 20x20
in size to demonstrate the vertical alignment.
In fact this is not restricted to JButton
and will for any JComponent
that can use an icon e.g. JLabel
etc.
Upvotes: 7