Swing:如何制作具有软边框的非矩形窗口?

发布于 2024-07-23 10:12:24 字数 856 浏览 7 评论 0原文

如何在 Java 中制作带有软边框的非矩形窗口?
软边框(也称为软剪切)是没有锯齿伪影的边框。

我在网上进行了大量搜索,发现了几篇有关半透明和/或非矩形窗口的帖子。

“软边界”这个话题很令人困惑。 我发现的信息似乎涉及将软边框应用于另一个 Java 组件内部的组件。

但是,我可以或者不能将软边框应用于仅放置在桌面上的自定义形状的 JWindow 吗?

我主要指的是以下帖子:
http://today.java.net/pub/a/today/2008/03/18/translucent-and-shape-swing-windows.html

当它出现时软剪辑,文章转发至
http://weblogs.java.net/blog/campbell/archive/2006/07/java_2d_tricker.html
但这里描述了对现有 Graphics2D 对象的软裁剪。

How could I make non-rectangular windows with soft borders in Java?
Soft borders (also known as soft clipping) are borders without aliasing artifacts.

I searched the web a lot and found several posts about translucent and/or non-rectangular windows.

The topic "soft border" is confusing. It seems that the information I found deals with applying soft borders to component which are inside another Java components.

But, can I, or can I not apply soft borders to custom shaped JWindow which is placed just on the desktop?

I am primely referring to following post:
http://today.java.net/pub/a/today/2008/03/18/translucent-and-shaped-swing-windows.html

When it comes to soft clipping, the article forwards to
http://weblogs.java.net/blog/campbell/archive/2006/07/java_2d_tricker.html
But here, soft clipping on an existing Graphics2D object is described.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

天邊彩虹 2024-07-30 10:12:24

这是我对软剪辑、成形的顶层窗户的看法。

注意:异形窗口曾经是专有 API (com.sun.awt.AWTUtilities),但是,在 JDK 7 中,它成为 AWT 的 Window 类的一部分。

软剪辑窗口技巧

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;

public class MySoftClippedWindow extends JPanel {
  public MySoftClippedWindow() {
    super();
    setLayout(new GridBagLayout());
    JButton button = new JButton(new AbstractAction("Close") {
      @Override
      public void actionPerformed(ActionEvent e) {
        System.exit(0);
      }
    });
    button.setOpaque(false);
    add(button);
  }

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

    int width = getWidth();
    int height = getHeight();

    // Create a soft clipped image for the background
    BufferedImage img = java_2d_tricker(g2d, width, height);
    // Copy our intermediate image to the screen
    g2d.drawImage(img, 0, 0, null);

    g2d.dispose();
  }

  public static void main() {
    JFrame.setDefaultLookAndFeelDecorated(true);
    SwingUtilities.invokeLater(() -> {
      final JWindow w = new JWindow();
      Container cp = w.getContentPane();
      cp.setLayout(new BorderLayout());
      cp.add(new MySoftClippedWindow());
      w.setAlwaysOnTop(true);
      // This makes the window transparent, but kept opaque
      w.setBackground(new Color(0, true));
      w.setSize(200, 200);
      w.setVisible(true);
    });
  }

  /*
   * This code is taken from
   * https://web.archive.org/web/20120603053853/http://weblogs.java.net/blog/campbell/archive/2006/07/java_2d_tricker.html
   *
   * by Chris Campbell
   */
  private BufferedImage java_2d_tricker(Graphics2D g2d, int width, int height) {
    // Create a translucent intermediate image in which we can perform
    // the soft clipping
    GraphicsConfiguration gc = g2d.getDeviceConfiguration();
    BufferedImage img = gc.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
    Graphics2D g2 = img.createGraphics();
    // Clear the image so all pixels have zero alpha
    g2.setComposite(AlphaComposite.Clear);
    g2.fillRect(0, 0, width, height);

    // Render our clip shape into the image.  Note that we enable
    // antialiasing to achieve the soft clipping effect.  Try
    // commenting out the line that enables antialiasing, and
    // you will see that you end up with the usual hard clipping.
    g2.setComposite(AlphaComposite.Src);
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setColor(Color.WHITE);
    g2.fillOval(width / 4, height / 4, width / 2, height / 2);

    // Here's the trick... We use SrcAtop, which effectively uses the
    // alpha value as a coverage value for each pixel stored in the
    // destination.  For the areas outside our clip shape, the destination
    // alpha will be zero, so nothing is rendered in those areas.  For
    // the areas inside our clip shape, the destination alpha will be fully
    // opaque, so the full color is rendered.  At the edges, the original
    // antialiasing is carried over to give us the desired soft clipping
    // effect.
    g2.setComposite(AlphaComposite.SrcAtop);
    g2.setPaint(new GradientPaint(0, 0, Color.RED, 0, height, Color.YELLOW));
    g2.fillRect(0, 0, width, height);
    g2.dispose();
    return img;
  }
}

Here's my take on a soft-clipped, shaped, top-level window.

Note: shaped windows used to be a proprietary API (com.sun.awt.AWTUtilities), however, in JDK 7 it became part of the AWT's Window class.

soft clipped window trick

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;

public class MySoftClippedWindow extends JPanel {
  public MySoftClippedWindow() {
    super();
    setLayout(new GridBagLayout());
    JButton button = new JButton(new AbstractAction("Close") {
      @Override
      public void actionPerformed(ActionEvent e) {
        System.exit(0);
      }
    });
    button.setOpaque(false);
    add(button);
  }

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

    int width = getWidth();
    int height = getHeight();

    // Create a soft clipped image for the background
    BufferedImage img = java_2d_tricker(g2d, width, height);
    // Copy our intermediate image to the screen
    g2d.drawImage(img, 0, 0, null);

    g2d.dispose();
  }

  public static void main() {
    JFrame.setDefaultLookAndFeelDecorated(true);
    SwingUtilities.invokeLater(() -> {
      final JWindow w = new JWindow();
      Container cp = w.getContentPane();
      cp.setLayout(new BorderLayout());
      cp.add(new MySoftClippedWindow());
      w.setAlwaysOnTop(true);
      // This makes the window transparent, but kept opaque
      w.setBackground(new Color(0, true));
      w.setSize(200, 200);
      w.setVisible(true);
    });
  }

  /*
   * This code is taken from
   * https://web.archive.org/web/20120603053853/http://weblogs.java.net/blog/campbell/archive/2006/07/java_2d_tricker.html
   *
   * by Chris Campbell
   */
  private BufferedImage java_2d_tricker(Graphics2D g2d, int width, int height) {
    // Create a translucent intermediate image in which we can perform
    // the soft clipping
    GraphicsConfiguration gc = g2d.getDeviceConfiguration();
    BufferedImage img = gc.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
    Graphics2D g2 = img.createGraphics();
    // Clear the image so all pixels have zero alpha
    g2.setComposite(AlphaComposite.Clear);
    g2.fillRect(0, 0, width, height);

    // Render our clip shape into the image.  Note that we enable
    // antialiasing to achieve the soft clipping effect.  Try
    // commenting out the line that enables antialiasing, and
    // you will see that you end up with the usual hard clipping.
    g2.setComposite(AlphaComposite.Src);
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setColor(Color.WHITE);
    g2.fillOval(width / 4, height / 4, width / 2, height / 2);

    // Here's the trick... We use SrcAtop, which effectively uses the
    // alpha value as a coverage value for each pixel stored in the
    // destination.  For the areas outside our clip shape, the destination
    // alpha will be zero, so nothing is rendered in those areas.  For
    // the areas inside our clip shape, the destination alpha will be fully
    // opaque, so the full color is rendered.  At the edges, the original
    // antialiasing is carried over to give us the desired soft clipping
    // effect.
    g2.setComposite(AlphaComposite.SrcAtop);
    g2.setPaint(new GradientPaint(0, 0, Color.RED, 0, height, Color.YELLOW));
    g2.fillRect(0, 0, width, height);
    g2.dispose();
    return img;
  }
}
爺獨霸怡葒院 2024-07-30 10:12:24

您读过这篇文章吗:

http://www.pushing-pixels.org/?p= 272

它提到了软裁剪和你之前提到的文章,还包括一些实现软裁剪窗口的源代码,直接链接在这里:

http://www.pushing-pixels.org/wp-content/uploads/2008/03/softclippedwindow.java

这应该为您提供一个可能的解决方案来实现您想要做的事情。

Have you read this article:

http://www.pushing-pixels.org/?p=272

It mentions soft clipping and the previous articles you mentioned, but also includes some source code to implement a soft clipped window, the direct link is here:

http://www.pushing-pixels.org/wp-content/uploads/2008/03/softclippedwindow.java

That should provide you with a possible solution for what you want to do.

无戏配角 2024-07-30 10:12:24
import java.awt.*;

public class First extends Applet
   {
   public void paint(Graphics g)
             {
             g.drawRect(100,50,500,800);
             }
   }
/*<Applet code="First.class"height=500 width=500>
  </Applet>
*/
import java.awt.*;

public class First extends Applet
   {
   public void paint(Graphics g)
             {
             g.drawRect(100,50,500,800);
             }
   }
/*<Applet code="First.class"height=500 width=500>
  </Applet>
*/
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文