La frontière avec les coins arrondis & la transparence

La capture d'écran suivante montre un test de TextBubbleBorder1. Je voudrais faire les coins de la pièce qui sont à l'extérieur du rectangle d'être entièrement transparent & montrer tout ce que le composant est en-dessous d'elle. J'ai trouvé un moyen de limiter le BG de la couleur de l'étiquette à l'intérieur de la frontière " par la définition d'une Clip (représentant la zone à l'extérieur des coins arrondis) sur la Graphics2D instance et d'appel clearRect(). Qui peut être vu dans Label 1.

La frontière avec les coins arrondis & la transparence

Cependant, vous pouvez voir l'inconvénient de cette approche lorsqu'il y a un rouge BG (ou non-standard de couleur) sur le panneau parent. Les coins par défaut la valeur par défaut de la couleur de façade (plus facile à voir dans Panel 2).

En fin de compte, je voudrais que cela fonctionne pour un non-standard de couleur dans le conteneur parent, mais il a été en partie inspiré par Que dois-je faire pour répliquer ce composant avec un dégradé de peinture?

Quelqu'un connais un moyen d'obtenir ces coins transparents?

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.border.*;
public class BorderTest {
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
JPanel gui = new JPanel(new GridLayout(1,0,5,5));
gui.setBorder(new EmptyBorder(10,10,10,10));
gui.setBackground(Color.RED);
AbstractBorder brdr = new TextBubbleBorder(Color.BLACK,2,16,0);
JLabel l1 = new JLabel("Label 1");
l1.setBorder(brdr);
gui.add(l1);
JLabel l2 = new JLabel("Label 2");
l2.setBorder(brdr);
l2.setBackground(Color.YELLOW);
l2.setOpaque(true);
gui.add(l2);
JPanel p1 = new JPanel();
p1.add(new JLabel("Panel 1"));
p1.setBorder(brdr);
p1.setOpaque(false);
gui.add(p1);
JPanel p2 = new JPanel();
p2.add(new JLabel("Panel 2"));
p2.setBorder(brdr);
gui.add(p2);
JOptionPane.showMessageDialog(null, gui);
}
};
//Swing GUIs should be created and updated on the EDT
//http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}
class TextBubbleBorder extends AbstractBorder {
private Color color;
private int thickness = 4;
private int radii = 8;
private int pointerSize = 7;
private Insets insets = null;
private BasicStroke stroke = null;
private int strokePad;
private int pointerPad = 4;
RenderingHints hints;
TextBubbleBorder(
Color color) {
new TextBubbleBorder(color, 4, 8, 7);
}
TextBubbleBorder(
Color color, int thickness, int radii, int pointerSize) {
this.thickness = thickness;
this.radii = radii;
this.pointerSize = pointerSize;
this.color = color;
stroke = new BasicStroke(thickness);
strokePad = thickness / 2;
hints = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int pad = radii + strokePad;
int bottomPad = pad + pointerSize + strokePad;
insets = new Insets(pad, pad, bottomPad, pad);
}
@Override
public Insets getBorderInsets(Component c) {
return insets;
}
@Override
public Insets getBorderInsets(Component c, Insets insets) {
return getBorderInsets(c);
}
@Override
public void paintBorder(
Component c,
Graphics g,
int x, int y,
int width, int height) {
Graphics2D g2 = (Graphics2D) g;
int bottomLineY = height - thickness - pointerSize;
RoundRectangle2D.Double bubble = new RoundRectangle2D.Double(
0 + strokePad,
0 + strokePad,
width - thickness,
bottomLineY,
radii,
radii);
Polygon pointer = new Polygon();
//left point
pointer.addPoint(
strokePad + radii + pointerPad,
bottomLineY);
//right point
pointer.addPoint(
strokePad + radii + pointerPad + pointerSize,
bottomLineY);
//bottom point
pointer.addPoint(
strokePad + radii + pointerPad + (pointerSize / 2),
height - strokePad);
Area area = new Area(bubble);
area.add(new Area(pointer));
g2.setRenderingHints(hints);
Area spareSpace = new Area(new Rectangle(0, 0, width, height));
spareSpace.subtract(area);
g2.setClip(spareSpace);
g2.clearRect(0, 0, width, height);
g2.setClip(null);
g2.setColor(color);
g2.setStroke(stroke);
g2.draw(area);
}
}
  1. Tandis que le TextBubbleBorder a été conçu pour Rembourrage interne pour JTextArea avec l'Image de fond (& fini à l'aide d'un JLabel depuis la zone de texte a été un gâchis pour les raisons mentionnées ci-dessus), en spécifiant un pointerSize de 0 nous nous retrouvons avec un "rectangle arrondi" à la place.

    La frontière avec les coins arrondis & la transparence

  • La chose merveilleuse au sujet des frontières de l'est, elles ne fournissent que des encarts, ils ne donnent pas de conseils à propos de la forme, de sorte qu'il n'est pas vraiment possible pour le composant afin de remplir la zone à l'intérieur de la frontière. Ce que j'ai fait dans le passé est trompé. Essentiellement, j'ai créer un panneau avec la forme que je veux, puis placé dans sur un autre composant qui fournit l'arrière-plan des caractéristiques, comme une ombre portée ou ce que jamais je cherchais...
  • Que faire si vous remplacez paint (oui paint et pas paintComponent) et de régler le clip à la forme exacte que vous souhaitez avoir?
  • Merci @mKorbel, je vais faire un peu de chasse basée sur la "mre+Course'.
  • Je ne sais pas s'il faut rire ou pleurer. Il semble que cette question est une question directe double de cette question, et j'avais même vu avant et voté la question et 2 de l'réponses (y compris les vraiment cool frontière que vous avez posté)! Vous permettra de savoir si j'ai des ennuis..
  • Merci pour l'astuce. Je vais vérifier si je ne peux pas obtenir les réponses dans la copie (lié par mKorbel) à travailler pour moi.