web-dev-qa-db-fra.com

Arrondi Swing JButton en utilisant Java

Eh bien, j'ai une image que je voudrais mettre en arrière-plan sur un bouton (ou quelque chose de clicable). Le problème est que cette image est ronde, je dois donc montrer cette image, sans aucune bordure, etc.

Le JComponent qui détient ce bouton a un arrière-plan personnalisé, le bouton n'a donc besoin que d'afficher l'image.

Après une recherche sur Google, je n'ai pas réussi à le faire. J'ai essayé tout ce qui suit, mais sans succès:

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

Et après avoir peint l’icône à l’arrière-plan, le bouton l’a peint, mais conserve un arrière-plan gris et laid avec des bordures, etc. J’ai également essayé d’utiliser un JLabel et un JButton. Et pour peindre un ImageIcon, mais si l'utilisateur redimensionne ou réduit la fenêtre, les icônes disparaissent!

Comment puis-je réparer cela?

J'ai juste besoin de peindre et arrondir une image à un JComponent et d'écouter les clics sur elle ...

16
José Leal

Créez un nouveau 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);

lors de la définition de la bordure d'un JButton, appelez la classe javax.swing.border.Border remplacée.

addBtn.setBorder(new RoundedBorder(10));

Voici la classe

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);
    }
}
14
Lalchand

Avez-vous essayé ce qui suit?

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

setBorder(null) pourrait fonctionner, mais il y a un bogue décrit par Sun , expliquant que c'est par sa conception que l'interface utilisateur définit une bordure sur un composant, à moins que le client ne définisse une bordure non null qui n'implémente pas l'interface UIResource.

Plutôt que de définir lui-même la frontière avec un EmptyBorder lorsque la valeur null est passée, les clients doivent définir eux-mêmes un EmptyBorder (solution de contournement très simple). De cette façon, il n'y a pas de confusion quant à qui fait quoi dans le code.

12
VonC

Je recommanderais de remplacer la méthode Paint (Graphics g) de la manière suivante:

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) {
    }
}
1
pek
  1. Faites glisser un bouton normal sur votre panneau

  2. Faites un clic droit sur votre bouton et accédez aux propriétés:

    boarder           = no barder
    boarder painted   = false
    contentAreaFilled = false
    focusPainted      = false
    opaque            = false
    
  3. Définissez un (icône) et un (rolloverIcon) en les important dans le projet.

1
user1477929

Vous pouvez essayer ce qui suit. Cela fonctionne bien pour moi, et j'ai également fait face au même problème avec le bouton.

// Jbutton
JButton imageButton = new JButton();

// Buffered Icon
BufferedImage buttonIcon = null;

try {
    // Get the image and set it to the imageicon
    buttonIcon = ImageIO.read(getClass().getClassLoader().getResource("images/login.png"));
}
catch(Exception ex) {

}

// Set the image icon here
imageButton = new JButton(new ImageIcon(buttonIcon));
imageButton.setBorderPainted(false);
imageButton.setContentAreaFilled(false);
imageButton.setFocusPainted(false);
imageButton.setOpaque(false);
1
Luffy

L'opacité doit être définie sur false, donc

button.setOpaque(false);

pourrait déjà être ce que vous voulez.

0
Bombe

Vous pouvez créer une bordure vide pour le bouton comme ceci: 

button.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
0
Reeba Babu

J'ai écrit un OvalButton class pouvant gérer des boutons JBovs de forme ovale, circulaire et en forme de capsule.

Dans votre cas, développez la classe OvalButton class et substituez la méthode getBackgroundImage() pour renvoyer l'image que vous souhaitez définir comme arrière-plan. Ajoutez ensuite des écouteurs et du texte comme d'habitude. Seul un clic sur la zone ovale/circulaire déclenche l'action.

Exemple de votre classe de boutons:

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;
    }
}
0
Luka Kralj