Java - 在paintComponent中使用合成的圆角面板

Ben*_*Ben 14 java swing compositing rounded-corners paintcomponent

从最初的问题(下面),我现在提供以下奖励:

AlphaComposite圆角的基础解决方案.

  • 请用一个演示JPanel.
  • 角落必须完全透明.
  • 必须能够支持JPG绘画,但仍然有圆角
  • 不得使用setClip(或任何剪辑)
  • 必须有不错的表现

希望有人快速选择这个,这似乎很容易.

如果有一个充分解释的原因,为什么永远不会这样做,其他人同意,我也会奖励赏金.

这是我想到的一个示例图像(但使用AlphaComposite)在此输入图像描述


原始问题

我一直试图找到一种使用合成来做圆角的方法,非常类似于如何用Java制作圆角图像http://weblogs.java.net/blog/campbell/archive/2006/07/ java_2d_tricker.html.

但是,我没有中间BufferedImage的尝试不起作用 - 圆形目标合成显然不会影响源.我尝试了不同的东西,但没有任何作用.应该得到一个圆形的红色矩形,而不是我得到一个正方形.

所以,我有两个问题,真的:

1)有没有办法使这项工作?

2)中间图像是否会实际产生更好的性能?

SSCCE:

测试面板TPanel

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JLabel;

public class TPanel extends JLabel {
int w = 300;
int h = 200;

public TPanel() {
    setOpaque(false);
    setPreferredSize(new Dimension(w, h));
        setMaximumSize(new Dimension(w, h));
        setMinimumSize(new Dimension(w, h));
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g.create();

    // Yellow is the clipped area.
    g2d.setColor(Color.yellow);
    g2d.fillRoundRect(0, 0, w, h, 20, 20);
    g2d.setComposite(AlphaComposite.Src);

    // Red simulates the image.
    g2d.setColor(Color.red);
    g2d.setComposite(AlphaComposite.SrcAtop);

    g2d.fillRect(0, 0, w, h);
    }
}
Run Code Online (Sandbox Code Playgroud)

和它的沙盒

import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.JFrame;

public class Sandbox {
public static void main(String[] args) {
    JFrame f = new JFrame();
        f.setMinimumSize(new Dimension(800, 600));
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLayout(new FlowLayout());

        TPanel pnl = new TPanel();
        f.getContentPane().add(pnl);

        f.setVisible(true);
    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ren 7

关于您的性能问题,Java 2D Trickery文章包含了Chet Haase关于中间图像使用的非常好的解释的链接.

我认为以下摘自O'Reilly的Java基础类的Nutshell可能对您有所帮助,以便了解AlphaComposite行为以及为什么中间图像可能是必要的技术.

AlphaComposite合成规则

SRC_OVER合成规则在目标颜色上绘制可能半透明的源颜色.这是我们在执行图形操作时通常希望发生的事情.但是AlphaComposite对象实际上允许根据其他七个规则组合颜色.

在我们详细考虑合成规则之前,您需要了解一个重点.屏幕上显示的颜色从不具有Alpha通道.如果你能看到一种颜色,它就是一种不透明的颜色.可以基于透明度计算来选择精确的颜色值,但是,一旦选择了该颜色,颜色就存在于某处的视频卡的存储器中并且不具有与其相关联的α值.换句话说,使用屏幕绘制时,目标像素的alpha值始终为1.0.

但是,当您绘制屏幕外图像时,情况会有所不同.正如您将在本章后面考虑Java 2D BufferedImage类时所看到的那样,您可以在创建屏幕外图像时指定所需的颜色表示.默认情况下,BufferedImage对象将图像表示为RGB颜色数组,但您也可以创建一个ARGB颜色数组的图像.此类图像具有与其关联的Alpha值,当您绘制图像时,Alpha值仍与您绘制的像素相关联.

屏幕上和屏幕外绘图之间的这种区别很重要,因为一些合成规则基于目标像素的alpha值而不是源像素的alpha值执行合成.使用屏幕绘制时,目标像素始终是不透明的(alpha值为1.0),但是对于屏幕外绘图,情况并非如此.因此,某些合成规则仅在您绘制具有Alpha通道的屏幕外图像时才有用.

为了过度概括,我们可以说当你在屏幕上绘图时,你通常会坚持使用默认的SRC_OVER合成规则,使用不透明的颜色,并改变AlphaComposite对象使用的alpha值.但是,在处理具有Alpha通道的屏幕外图像时,您可以使用其他合成规则.在这种情况下,您通常使用半透明颜色和半透明图像以及Alpha值为1.0的AlphaComposite对象.