边框带圆角和放大器;透明度 [英] Border with rounded corners & transparency

查看:307
本文介绍了边框带圆角和放大器;透明度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的截图显示 TextBubbleBorder 的考验 1 。我想提出的是矩形之外是完全透明和放大器部件的角落;无论显示组件是它下面。我找到了一种方法来限制​​标签​​的背景色,以通过设置剪辑的边界内(重presenting圆角以外的区域)上的的Graphics2D 实例并调用 clearRect()。可以在标签中可以看出1

但是你可以看到这个方法的缺点时,有一个红色的BG(或任何非标准色)父面板上。边角默认为默认的面板颜色(最容易看到面板2 )。

最后,我想这对于一个非标准的颜色在父容器工作,但它部分是由做什么我需要做的复制与渐变烤漆此组件?

有谁知道一个办法让那些弯道透明?

 进口java.awt中的*。
导入的java.awt.geom *。
进口的javax.swing *。
javax.swing.border中导入*。公共类BorderTest {    公共静态无效的主要(字串[] args){
        可运行R =新的Runnable(){            @覆盖
            公共无效的run(){
                JPanel的GUI =新JPanel(新网格布局(1,0,5,5));
                gui.setBorder(新EmptyBorder(10,10,10,10));
                gui.setBackground(Color.RED);                AbstractBorder中BRDR =新TextBubbleBorder(Color.BLACK,2,16,0);                的JLabel L1 =新的JLabel(标签1);
                l1.setBorder(BRDR);
                gui.add(L1);                的JLabel L2 =新的JLabel(标签2);
                l2.setBorder(BRDR);
                l2.setBackground(Color.YELLOW);
                l2.setOpaque(真);
                gui.add(12);                JPanel的P1 =新JPanel();
                p1.add(新的JLabel(专题1));
                p1.setBorder(BRDR);
                p1.setOpaque(假);
                gui.add(P1);                JPanel的P2 =新JPanel();
                p2.add(新的JLabel(面板2));
                p2.setBorder(BRDR);
                gui.add(P2);                JOptionPane.showMessageDialog(NULL,GUI);
            }
        };
        //摇摆的GUI应创建和更新的EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(R);
    }}类TextBubbleBorder扩展{AbstractBorder中    私人色彩的颜色;
    私人INT厚度= 4;
    私人INT半径= 8;
    私人INT pointerSize = 7;
    私人插图插图= NULL;
    私人的BasicStroke行程= NULL;
    私人诠释strokePad;
    私人INT pointerPad = 4;
    RenderingHints的提示;    TextBubbleBorder(
            色色){
        新TextBubbleBorder(颜色,4,8,7);
    }    TextBubbleBorder(
            色色,诠释厚度,诠释半径,诠释pointerSize){
        this.thickness =厚度;
        this.radii =半径;
        this.pointerSize = pointerSize;
        this.color =颜色;        行程=的新BasicStroke(厚度);
        strokePad =厚度/ 2;        提示=新的RenderingHints(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);        INT垫=半径+ strokePad;
        INT bottomPad =垫+ pointerSize + strokePad;
        插图=新的Insets(垫,垫,bottomPad,垫);
    }    @覆盖
    公共插图的getBorderInsets(Component c)将{
        返回插图;
    }    @覆盖
    公共插图的getBorderInsets(c成分,插图插图){
        返回的getBorderInsets(C);
    }    @覆盖
    公共无效的paintBorder(
            c成分,
            图形克,
            INT X,INT Y,
            INT宽度,高度INT){        Graphics2D的G2 =(Graphics2D的)克;        INT bottomLineY =高度 - 厚度 - pointerSize;        RoundRectangle2D.Double泡沫=新RoundRectangle2D.Double(
                0 + strokePad,
                0 + strokePad,
                宽度 - 厚度,
                bottomLineY,
                半径,
                半径);        多边形指针=新的多边形();        //左点
        pointer.addPoint(
                strokePad +半径+ pointerPad,
                bottomLineY);
        //右键点
        pointer.addPoint(
                strokePad +半径+ pointerPad + pointerSize,
                bottomLineY);
        //底部点
        pointer.addPoint(
                strokePad +半径+ pointerPad +(pointerSize / 2),
                高度 - strokePad);        区域面积=新Area(泡);
        area.add(新区域(指针));        g2.setRenderingHints(提示);        面积spareSpace =新区域(新的Rectangle(0,0,宽度,高度));
        spareSpace.subtract(区);
        g2.setClip(spareSpace);
        g2.clearRect(0,0,宽度,高度);
        g2.setClip(NULL);        g2.setColor(颜色);
        g2.setStroke(中风);
        g2.draw(区);
    }
}


  1. TextBubbleBorder 被设计用于为内部填充(安培;最后使用的JLabel ,因为文本区域是上述原因一塌糊涂),通过指定 pointerSize 我们结束了一个圆角矩形来代替。
    搜索结果


解决方案

N.B。有这code,它被固定在接受答案的paintComponent(剪贴BUG)对其他组件正在制定。这应该只被看作是如果裁剪错误修复结合的解决方案。


  //漆母公司的背景色,处处剪辑外
//文本泡沫。

请参阅在code的源这一点上,正确地显示为:

 进口java.awt中的*。
java.awt.image中导入*。
导入的java.awt.geom *。
进口的javax.swing *。
javax.swing.border中导入*。公共类BorderTest {    公共静态无效的主要(字串[] args){
        可运行R =新的Runnable(){            @覆盖
            公共无效的run(){
                JPanel的GUI =新JPanel(新网格布局(2,0,5,5));
                gui.setBorder(新EmptyBorder(10,10,10,10));
                gui.setBackground(Color.RED);                AbstractBorder中brdrLeft =新TextBubbleBorder(Color.BLACK,2,16,16);
                AbstractBorder中brdrRight =新TextBubbleBorder(Color.BLACK,2,16,16,FALSE);                的JLabel L1 =新的JLabel(标签1);
                l1.setBorder(brdrRight);
                gui.add(L1);                的JLabel L2 =新的JLabel(标签2);
                l2.setBorder(brdrLeft);
                l2.setBackground(Color.YELLOW);
                l2.setOpaque(真);
                gui.add(12);                JPanel的P1 =新JPanel();
                p1.add(新的JLabel(专题1));
                p1.setBorder(brdrRight);
                p1.setOpaque(假);
                gui.add(P1);                JPanel的P2 =新JPanel();
                p2.add(新的JLabel(面板2));
                p2.setBorder(brdrLeft);
                gui.add(P2);                JOptionPane.showMessageDialog(NULL,GUI);
            }
        };
        //摇摆的GUI应创建和更新的EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(R);
    }}类TextBubbleBorder扩展{AbstractBorder中    私人色彩的颜色;
    私人INT厚度= 4;
    私人INT半径= 8;
    私人INT pointerSize = 7;
    私人插图插图= NULL;
    私人的BasicStroke行程= NULL;
    私人诠释strokePad;
    私人INT pointerPad = 4;
    私人布尔左= TRUE;
    RenderingHints的提示;    TextBubbleBorder(
            色色){
        新TextBubbleBorder(颜色,4,8,7);
    }    TextBubbleBorder(
            色色,诠释厚度,诠释半径,诠释pointerSize){
        this.thickness =厚度;
        this.radii =半径;
        this.pointerSize = pointerSize;
        this.color =颜色;        行程=的新BasicStroke(厚度);
        strokePad =厚度/ 2;        提示=新的RenderingHints(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);        INT垫=半径+ strokePad;
        INT bottomPad =垫+ pointerSize + strokePad;
        插图=新的Insets(垫,垫,bottomPad,垫);
    }    TextBubbleBorder(
            色色,诠释厚度,诠释半径,诠释pointerSize,布尔左){
        这个(颜色,厚度,半径,pointerSize);
        this.left =左;
    }    @覆盖
    公共插图的getBorderInsets(Component c)将{
        返回插图;
    }    @覆盖
    公共插图的getBorderInsets(c成分,插图插图){
        返回的getBorderInsets(C);
    }    @覆盖
    公共无效的paintBorder(
            c成分,
            图形克,
            INT X,INT Y,
            INT宽度,高度INT){        Graphics2D的G2 =(Graphics2D的)克;        INT bottomLineY =高度 - 厚度 - pointerSize;        RoundRectangle2D.Double泡沫=新RoundRectangle2D.Double(
                0 + strokePad,
                0 + strokePad,
                宽度 - 厚度,
                bottomLineY,
                半径,
                半径);        多边形指针=新的多边形();        如果(左){
            //左点
            pointer.addPoint(
                    strokePad +半径+ pointerPad,
                    bottomLineY);
            //右键点
            pointer.addPoint(
                    strokePad +半径+ pointerPad + pointerSize,
                    bottomLineY);
            //底部点
            pointer.addPoint(
                    strokePad +半径+ pointerPad +(pointerSize / 2),
                    高度 - strokePad);
        }其他{
            //左点
            pointer.addPoint(
                    宽度 - (strokePad +半径+ pointerPad)
                    bottomLineY);
            //右键点
            pointer.addPoint(
                    宽度 - (strokePad +半径+ pointerPad + pointerSize)
                    bottomLineY);
            //底部点
            pointer.addPoint(
                    宽度 - (strokePad +半径+ pointerPad +(pointerSize / 2)),
                    高度 - strokePad);
        }        区域面积=新Area(泡);
        area.add(新区域(指针));        g2.setRenderingHints(提示);        //漆母公司的背景色,处处剪辑外
        //文本泡沫。
        组件父= c.getParent();
        如果(父!= NULL){
            颜色BG = parent.getBackground();
            矩形RECT =新的Rectangle(0,0,宽,高);
            区borderRegion =新的区域(矩形);
            borderRegion.subtract(区);
            g2.setClip(borderRegion);
            g2.setColor(BG);
            g2.fillRect(0,0,宽度,高度);
            g2.setClip(NULL);
        }        g2.setColor(颜色);
        g2.setStroke(中风);
        g2.draw(区);
    }
}

The following screenshot shows a test of TextBubbleBorder1. I would like to make the corners of the component that are outside the rectangle to be entirely transparent & show whatever component is beneath it. I found a way to restrict the BG color of a label to 'inside the border' by setting a Clip (representing the area outside the rounded corners) on the Graphics2D instance and calling clearRect(). That can be seen in Label 1.

However you can see the downside of this approach when there is a red BG (or any non-standard color) on the parent panel. The corners default to the default panel color (easiest to see in Panel 2).

Ultimately I would like this to work for a non-standard color in the parent container, but it was partly inspired by What do I need to do to replicate this component with gradient paint?

Does anybody know a way to get those corners transparent?

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. While the TextBubbleBorder was devised for Internal padding for JTextArea with background Image (& ended up using a JLabel since the text area was a mess for the reasons mentioned above), by specifying a pointerSize of 0 we end up with a 'rounded rectangle' instead.

解决方案

N.B. There is a clipping bug in this code, which is fixed in the accepted answer to paintComponent() is drawing on other components. This should only be considered as a solution if the 'clipping bug fix' is incorporated.


// Paint the BG color of the parent, everywhere outside the clip
// of the text bubble.

See this point in the code for the source that shows correctly as:

import java.awt.*;
import java.awt.image.*;
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(2,0,5,5));
                gui.setBorder(new EmptyBorder(10,10,10,10));
                gui.setBackground(Color.RED);

                AbstractBorder brdrLeft = new TextBubbleBorder(Color.BLACK,2,16,16);
                AbstractBorder brdrRight = new TextBubbleBorder(Color.BLACK,2,16,16,false);

                JLabel l1 = new JLabel("Label 1");
                l1.setBorder(brdrRight);
                gui.add(l1);

                JLabel l2 = new JLabel("Label 2");
                l2.setBorder(brdrLeft);
                l2.setBackground(Color.YELLOW);
                l2.setOpaque(true);
                gui.add(l2);

                JPanel p1 = new JPanel();
                p1.add(new JLabel("Panel 1"));
                p1.setBorder(brdrRight);
                p1.setOpaque(false);
                gui.add(p1);

                JPanel p2 = new JPanel();
                p2.add(new JLabel("Panel 2"));
                p2.setBorder(brdrLeft);
                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;
    private boolean left = true;
    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);
    }

    TextBubbleBorder(
            Color color, int thickness, int radii, int pointerSize, boolean left) {
        this(color, thickness, radii, pointerSize);
        this.left = left;
    }

    @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();

        if (left) {
            // 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);
        } else {
            // left point
            pointer.addPoint(
                    width - (strokePad + radii + pointerPad),
                    bottomLineY);
            // right point
            pointer.addPoint(
                    width - (strokePad + radii + pointerPad + pointerSize),
                    bottomLineY);
            // bottom point
            pointer.addPoint(
                    width - (strokePad + radii + pointerPad + (pointerSize / 2)),
                    height - strokePad);
        }

        Area area = new Area(bubble);
        area.add(new Area(pointer));

        g2.setRenderingHints(hints);

        // Paint the BG color of the parent, everywhere outside the clip
        // of the text bubble.
        Component parent  = c.getParent();
        if (parent!=null) {
            Color bg = parent.getBackground();
            Rectangle rect = new Rectangle(0,0,width, height);
            Area borderRegion = new Area(rect);
            borderRegion.subtract(area);
            g2.setClip(borderRegion);
            g2.setColor(bg);
            g2.fillRect(0, 0, width, height);
            g2.setClip(null);
        }

        g2.setColor(color);
        g2.setStroke(stroke);
        g2.draw(area);
    }
}

这篇关于边框带圆角和放大器;透明度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆