Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rounded Swing JButton using Java

Well, I have an image that I would like to put as a background to a button (or something clicable). The problem is that this image is round, so I need to show this image, without any borders, etc.

The JComponent that holds this button has a custom background, so the button really needs to only show the image.

After searching Google, I couldn't manage to do so. I have tried all the following, but with no luck:

button.setBorderPainted(false);
button.setContentAreaFilled(false);
button.setOpaque(true);

And after I paint the icon at the background, the button paints it, but holds an ugly gray background with borders, etc. I have also tried to use a JLabel and a JButton. And to paint an ImageIcon at it, but if the user resizes or minimizes the window, the icons disappear!

How can I fix this?

I just need to paint and round an image to a JComponent and listen for clicks at it...

like image 746
José Leal Avatar asked Jan 08 '09 11:01

José Leal


4 Answers

Create a new Jbutton:

    JButton addBtn = new JButton("+");     addBtn.setBounds(x_pos, y_pos, 30, 25);     addBtn.setBorder(new RoundedBorder(10)); //10 is the radius     addBtn.setForeground(Color.BLUE); 

while setting the border for a JButton, call the overridden javax.swing.border.Border class.

addBtn.setBorder(new RoundedBorder(10)); 

Here is the class

private static class RoundedBorder implements Border {      private int radius;       RoundedBorder(int radius) {         this.radius = radius;     }       public Insets getBorderInsets(Component c) {         return new Insets(this.radius+1, this.radius+1, this.radius+2, this.radius);     }       public boolean isBorderOpaque() {         return true;     }       public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {         g.drawRoundRect(x, y, width-1, height-1, radius, radius);     } } 
like image 113
Lalchand Avatar answered Sep 30 '22 02:09

Lalchand


Did you try the following?

button.setOpaque(false); button.setFocusPainted(false); button.setBorderPainted(false); button.setContentAreaFilled(false); setBorder(BorderFactory.createEmptyBorder(0,0,0,0)); // Especially important 

setBorder(null) might work, but there is a bug described at Sun explaining it is by design that the UI sets a border on a component unless the client sets a non-null border which does not implement the UIResource interface.

Rather than the JDK itself setting the border to an EmptyBorder when null is passed in, the clients should set an EmptyBorder themselves (a very easy workaround). That way there is no confusion about who's doing what in the code.

like image 31
VonC Avatar answered Sep 30 '22 03:09

VonC


I wrote an OvalButton class that can handle oval, circular and capsule-like shaped JButtons.

In your case, extend the OvalButton class and override getBackgroundImage() method to return the image you want to set as the background. Then add listeners and text as usually. Only a click on the oval/circular area triggers the action.

Example of your button class:

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class ImageButton extends OvalButton {

    private BufferedImage image;

    public ImageButton() {
        super(); // Default is oval/circle shape.

        setBorderThickness(0); // Oval buttons have some border by default.

        try {
            image = ImageIO.read(new File("your_image.jpg")); // Replace with the path to your image.
        } 
        catch (IOException e) {
            e.printStackTrace();
            image = null;
        }
    }

    @Override
    protected BufferedImage getBackgroundImage() {
        return image;
    }
}
like image 29
Luka Kralj Avatar answered Sep 30 '22 02:09

Luka Kralj


I would recommend overriding paint(Graphics g) method as so:

class JImageButton extends JComponent implements MouseListener {
    private BufferedImage img = null;

    public JImageButton(BufferedImage img) {
        this.img = img;
        setMinimumSize(new Dimension(img.getWidth(), img.getHeight()));
        setOpaque(false);
        addMouseListener(this);
    }

    public void paintComponent(Graphics g) {
        g.drawImage(img, 0, 0, img.getWidth(), img.getHeight(), null);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

    @Override
    public void mousePressed(MouseEvent e) {
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }
}
like image 31
pek Avatar answered Sep 30 '22 04:09

pek