当前位置: 首页 > 面试题库 >

Java - rounded corner panel with compositing in paintComponent

孟永望
2023-03-14
问题内容

From the original question (below), I am now offering a bounty for the
following:

An AlphaComposite based solution for rounded corners.

  • Please demonstrate with a JPanel.
  • Corners must be completely transparent.
  • Must be able to support JPG painting, but still have rounded corners
  • Must not use setClip (or any clipping)
  • Must have decent performance

Hopefully someone picks this up quick, it seems easy.

I will also award the bounty if there is a well-explained reason why this can
never be done, that others agree with.

Here is a sample image of what I have in mind (but
usingAlphaComposite)enter image description
here

Original question

I’ve been trying to figure out a way to do rounded corners using compositing,
very similar to How to make a rounded corner image in
Java or
http://weblogs.java.net/blog/campbell/archive/2006/07/java_2d_tricker.html.

However, my attempts without an intermediate BufferedImage don’t work - the
rounded destination composite apparently doesn’t affect the source. I’ve tried
different things but nothing works. Should be getting a rounded red rectangle,
instead I’m getting a square one.

So, I have two questions, really:

1) Is there a way to make this work?

2) Will an intermediate image actually generate better performance?

SSCCE:

the test panel 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);
    }
}

and its Sandbox

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

问题答案:

With respect to your performance concerns the Java 2D Trickery article
contains a link to a very good explanation by Chet Haase on the usage of
Intermediate
Images.

I think the following excerpt from O’Reilly’s Java Foundation Classes in a
Nutshell
could be helpful to you in order to make sense of the
AlphaComposite behaviour and why intermediate images may be the necessary
technique to use.

The AlphaComposite Compositing Rules

The SRC_OVER compositing rule draws a possibly translucent source color over
the destination color. This is what we typically want to happen when we
perform a graphics operation. But the AlphaComposite object actually allows
colors to be combined according to seven other rules as well.

Before we consider the compositing rules in detail, there is an important
point you need to understand. Colors displayed on the screen never have an
alpha channel. If you can see a color, it is an opaque color. The precise
color value may have been chosen based on a transparency calculation, but,
once that color is chosen, the color resides in the memory of a video card
somewhere and does not have an alpha value associated with it. In other
words, with on-screen drawing, destination pixels always have alpha values
of 1.0.

The situation is different when you are drawing into an off-screen image,
however. As you’ll see when we consider the Java 2D BufferedImage class
later in this chapter, you can specify the desired color representation when
you create an off-screen image. By default, a BufferedImage object
represents an image as an array of RGB colors, but you can also create an
image that is an array of ARGB colors. Such an image has alpha values
associated with it, and when you draw into the images, the alpha values
remain associated with the pixels you draw.

This distinction between on-screen and off-screen drawing is important
because some of the compositing rules perform compositing based on the alpha
values of the destination pixels, rather than the alpha values of the source
pixels. With on-screen drawing, the destination pixels are always opaque
(with alpha values of 1.0), but with off-screen drawing, this need not be
the case. Thus, some of the compositing rules only are useful when you are
drawing into off-screen images that have an alpha channel.

To overgeneralize a bit, we can say that when you are drawing on-screen, you
typically stick with the default SRC_OVER compositing rule, use opaque
colors, and vary the alpha value used by the AlphaComposite object. When
working with off-screen images that have alpha channels, however, you can
make use of other compositing rules. In this case, you typically use
translucent colors and translucent images and an AlphaComposite object with
an alpha value of 1.0.



 类似资料:
  • 在完成一个模块后,应该从那几个方面对代码进行优化,有哪些方法可以进行优化

  • 我想知道是否可以(以及使用哪种工具)在Java中执行类型安全i18n。可能还不清楚,所以这里有一些细节,假设我们使用基于的东西 1)使用类型安全参数进行转换 我希望避免像这样的接口,其中的值是非类型化的。应该不可能使用错误的参数类型进行调用。 注我可以指定所有键的类型。我正在寻找的解决方案应该是可伸缩的,并且不应该显著增加后端启动时间。 2)应该在编译时知道哪些键还在使用 我不希望我的翻译键库像许

  • 我们已经知道,Clojure代码最终在Java虚拟环境中运行。 因此,只有Clojure能够利用Java的所有功能才有意义。 在本章中,我们将讨论Clojure和Java之间的关联。 调用Java方法 可以使用点表示法调用Java方法。 一个例子是字符串。 由于Clojure中的所有字符串都是Java字符串,因此可以在字符串上调用普通的Java方法。 有关如何完成此操作的示例,请参见以下程序。 例

  • 问题内容: 我正在学习Spring 3,但似乎并没有掌握背后的功能。 从我读过他们似乎处理不同的注解(等等V,,等),而且从我读过他们注册相同什么bean后置处理器类。 为了更迷惑我,还有一个 属性上。 有人可以阐明这些标签吗?有什么相似之处,有什么不同之处,一个被另一个取代,它们彼此完成,我是否需要其中一个? 问题答案: 用于激活已经在应用程序上下文中注册的bean中的注释(无论它们是使用XML

  • 我在从使用SpringBoot和Faign构建的Java应用程序连接外部API时遇到问题。应用程序部署到docker容器中的VM。我正在尝试访问外部服务endpoint来检索一些数据,但到目前为止运气不佳。 我已经从VM命令行和docker容器内部也从命令行执行了相同的curl命令,但是当试图从java代码中命中它时,我只是收到一个超时。 任何关于可能发生的事情的想法,显然hosts文件和代理都是

  • 我正在使用BlueJ在java中开发一个虽然循环,但是 int m=0;int-ssum=0;

  • java.* 属性 表示 java.* 包层级的 JavaPackage 语法: java 说明: 在包含了 LiveConnect 或其他用于脚本化 Java 的技术的 JavaScript 实现中,全局 java 属性就是一个 JavaPackage 对象,它表示 java. 包层级。这个属性的存在意味着像 java.util 这样的一个 JavaScript 表示式引用的是 java.

  • java java 格式的 chaincode。