import javax.swing.*; import javax.swing.border.AbstractBorder; import javax.swing.border.Border; import javax.swing.border.CompoundBorder; import java.awt.*; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; /** * "Crazy JButton painters" from * http://weblogs.java.net/blog/alexfromsun/ * * Note: please consider this code as a joke, * I don't recommend using all this dirty tricks * * @author Alexander Potochkin */ public class ButtonPainter extends JFrame { private JButton button; public ButtonPainter() { setTitle("Crazy JButton painters"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setResizable(false); JPanel buttonPanel = new JPanel(new GridBagLayout()); button = new JButton("Hello World !", new TestIcon()); button.setPreferredSize(new Dimension(150, 70)); buttonPanel.add(button); buttonPanel.setBorder(BorderFactory.createEtchedBorder()); add(buttonPanel); add(createOptionsPanel(), BorderLayout.WEST); setSize(400, 200); setLocationRelativeTo(null); } private JComponent createOptionsPanel() { Box panel = new Box(BoxLayout.Y_AXIS); panel.add(Box.createVerticalGlue()); final JCheckBox componentButton = new JCheckBox("Component"); componentButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { button.removeAll(); if (componentButton.isSelected()) { button.setLayout(new BorderLayout()); button.add(new ComponentPainter()); } button.revalidate(); button.repaint(); } }); panel.add(componentButton); panel.add(Box.createVerticalGlue()); final JCheckBox borderButton = new JCheckBox("Border"); borderButton.addActionListener(new ActionListener() { private Border oldBorder = button.getBorder(); public void actionPerformed(ActionEvent e) { if (borderButton.isSelected()) { button.setBorder(new CompoundBorder(oldBorder, new BorderPainter())); } else { button.setBorder(oldBorder); } } }); panel.add(borderButton); panel.add(Box.createVerticalGlue()); final JCheckBox iconButton = new JCheckBox("Icon"); iconButton.addActionListener(new ActionListener() { private Icon oldIcon = button.getIcon(); public void actionPerformed(ActionEvent e) { if (iconButton.isSelected()) { button.setIcon(new IconPainter(oldIcon)); } else { button.setIcon(oldIcon); } } }); panel.add(iconButton); panel.add(Box.createVerticalGlue()); panel.setBorder(BorderFactory.createEtchedBorder()); return panel; } class ComponentPainter extends JPanel { protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g.create(); // It enables painting outside the component's border g2.setClip(null); // Make it translucent g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f)); // Take button's insets into account Insets insets = button.getInsets(); // Custom painting g2.setColor(Color.ORANGE); g2.fillOval(-insets.left, -insets.top, button.getWidth(), button.getHeight()); g2.setColor(Color.GRAY); g2.drawOval(-insets.left, -insets.top, button.getWidth(), button.getHeight()); g2.dispose(); } } class BorderPainter extends AbstractBorder { public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { Graphics2D g2 = (Graphics2D) g.create(); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f)); g2.setPaint(new GradientPaint(0, 10, Color.BLACK, 10, 10, Color.RED, true)); // We are free to paint wherever we want :-) g2.fillRect(0, 0, button.getWidth(), button.getHeight()); } } class IconPainter implements Icon { private final Icon delegateeIcon; public IconPainter(Icon innerIcon) { this.delegateeIcon = innerIcon; } public int getIconWidth() { if (delegateeIcon != null) { return delegateeIcon.getIconWidth(); } return 0; } public int getIconHeight() { if (delegateeIcon != null) { return delegateeIcon.getIconHeight(); } return 0; } public void paintIcon(Component c, Graphics g, int x, int y) { if (delegateeIcon != null) { delegateeIcon.paintIcon(c, g, x, y); } Graphics2D g2 = (Graphics2D) g.create(); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f)); g2.setPaint(new GradientPaint(10, 0, Color.RED, 10, 10, Color.BLUE, true)); // It is special icon, it is not interesed in x, y and icon's size g2.fillRect(0, 0, button.getWidth(), button.getHeight()); } } public static void main(String[] args) throws Exception { new ButtonPainter().setVisible(true); } } class TestIcon implements Icon { public int getIconHeight() { return 20; } public int getIconWidth() { return 20; } public void paintIcon(Component c, Graphics g, int x, int y) { g.setColor(Color.GREEN.darker()); g.fillOval(x, y, getIconWidth(), getIconHeight()); } }