如何在透明窗口上绘制图像? [英] How to draw images on transparent window?

查看:135
本文介绍了如何在透明窗口上绘制图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在JFrame上使用Graphics2D绘制图像。

但是这段代码只显示空白背景。

怎么做?

I'm trying to draw Images with Graphics2D on JFrame.
But this code only displays blank background.
How to do that?


Java版本:SE-1.6

IDE:Eclipse

Java Version: SE-1.6
IDE: Eclipse

我的代码如下所示:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import java.awt.geom.Line2D;
import java.util.TimerTask;

import javax.swing.JFrame;

public class GraphicTest extends JFrame{

    public static void main(String[] args) {
        GraphicTest gt = new GraphicTest();
        gt.start();
    }

    JFrame frame;
    BufferStrategy strategy;

    GraphicTest(){
        int width = 320;
        int height = 240;

        this.frame = new JFrame("test");

        this.frame.setSize(width, height);
        this.frame.setLocationRelativeTo(null);
        this.frame.setLocation(576, 336);
        this.frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);

        this.frame.setUndecorated(true);
        this.frame.setBackground(new Color(0, 0, 0, 50));

        this.frame.setVisible(true);

        this.frame.setIgnoreRepaint(true);
        this.frame.createBufferStrategy(2);
        this.strategy = this.frame.getBufferStrategy();
    }

    public void onExit(){
        System.exit(0);
    }

    void start(){
        java.util.Timer timer = new java.util.Timer();
        timer.schedule(new RenderTask(), 0, 16);
    }

    class RenderTask extends TimerTask{
        int count = 0;

        @Override
        public void run() {
            GraphicTest.this.render();
        }
    }

    void render() {
        // Some moving images
        Graphics2D g2 = (Graphics2D)this.strategy.getDrawGraphics();
        g2.setStroke(new BasicStroke(5.0f));
        Line2D line = new Line2D.Double(20, 40, 120, 140);
        g2.draw(line);
        this.strategy.show();
    }
}

感谢您提供任何帮助。

推荐答案


  • BufferStrategy 通常与重量相关组件,没有任何透明概念。

  • 透明和半透明(每个alpha像素)在Java 6下没有正式支持

  • 制作一个半透明的窗口会影响其他任何东西......这非常烦人,无论你使用的是Java 6还是7

    • BufferStrategy is normally associated with heavy weight components, which don't have any concept of transparency.
    • Transparent and translucent (per alpha pixeling) is not "officially" supported under Java 6
    • Making a window translucent effects anything else painted to it...this very annoying, regardless if you are using Java 6 or 7
    • 秘诀是让Window开始透明,然后覆盖一个具有特殊半透明绘画效果的透明组件。

      The secret is to make the Window transparent to begin with, then overlay a transparent component that has a special "translucent" paint effect.

      在Java 6下(我认为更新10) ),有一个名为 AWTUtilities 的私有API,它提供了使窗口透明或半透明的能力,以下示例基于该API。

      Under Java 6 (update 10 I think), there became available a private API called AWTUtilities which provide the ability to make a window transparent or translucent, the following example is based on that API.

      import java.awt.BorderLayout;
      import java.awt.Color;
      import java.awt.Dimension;
      import java.awt.EventQueue;
      import java.awt.Graphics;
      import java.awt.Graphics2D;
      import java.awt.Window;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.awt.image.BufferedImage;
      import java.io.File;
      import java.io.IOException;
      import java.lang.reflect.Method;
      import javax.imageio.ImageIO;
      import javax.swing.JFrame;
      import javax.swing.JPanel;
      import javax.swing.Timer;
      import javax.swing.UIManager;
      import javax.swing.UnsupportedLookAndFeelException;
      
      public class TransparentWindowAnimation {
      
          public static void main(String[] args) {
              new TransparentWindowAnimation();
          }
      
          public TransparentWindowAnimation() {
              EventQueue.invokeLater(new Runnable() {
                  @Override
                  public void run() {
                      try {
                          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                      } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                      }
      
                      if (supportsPerAlphaPixel()) {
                          try {
                              JFrame frame = new JFrame("Testing");
                              frame.setUndecorated(true);
                              setOpaque(frame, false);
                              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                              frame.setLayout(new BorderLayout());
                              frame.add(new PaintPane());
                              frame.pack();
                              frame.setLocationRelativeTo(null);
                              frame.setVisible(true);
                          } catch (Exception exp) {
                              exp.printStackTrace();
                          }
                      } else {
                          System.err.println("Per pixel alphering is not supported");
                      }
                  }
              });
          }
      
          public static boolean supportsPerAlphaPixel() {
              boolean support = false;
              try {
                  Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
                  support = true;
              } catch (Exception exp) {
              }
              return support;
          }
      
          public static void setOpaque(Window window, boolean opaque) throws Exception {
              try {
                  Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
                  if (awtUtilsClass != null) {
                      Method method = awtUtilsClass.getMethod("setWindowOpaque", Window.class, boolean.class);
                      method.invoke(null, window, opaque);
                  }
              } catch (Exception exp) {
                  throw new Exception("Window opacity not supported");
              }
          }
      
          public class PaintPane extends JPanel {
      
              private BufferedImage img;
      
              private int xPos, yPos = 100;
              private int xDelta = 0;
              private int yDelta = 0;
      
              public PaintPane() {
                  while (xDelta == 0) {
                      xDelta = (int)((Math.random() * 8)) - 4;
                  }
                  while (yDelta == 0) {
                      yDelta = (int)((Math.random() * 8)) - 4;
                  }
                  setOpaque(false);
                  try {
                      img = ImageIO.read(new File("AngryBird.png"));
                  } catch (IOException ex) {
                      ex.printStackTrace();
                  }
      
                  Timer timer = new Timer(40, new ActionListener() {
                      @Override
                      public void actionPerformed(ActionEvent e) {
                          xPos += xDelta;
                          yPos += yDelta;
                          if (xPos - (img.getWidth() / 2) <= 0) {
                              xPos = img.getWidth() / 2;
                              xDelta *= -1;
                          }
                          if (xPos + (img.getWidth() / 2) >= getWidth()) {
                              xPos = getWidth() - (img.getWidth() / 2);
                              xDelta *= -1;
                          }
                          if (yPos - (img.getHeight() / 2) <= 0) {
                              yPos = img.getHeight() / 2;
                              yDelta *= -1;
                          }
                          if (yPos + (img.getHeight() / 2) >= getHeight()) {
                              yPos = getHeight() - (img.getHeight() / 2);
                              yDelta *= -1;
                          }
                          repaint();
                      }
                  });
                  timer.start();
              }
      
              @Override
              public Dimension getPreferredSize() {
                  return new Dimension(200, 200);
              }
      
              @Override
              protected void paintComponent(Graphics g) {
                  super.paintComponent(g);
                  Graphics2D g2d = (Graphics2D) g.create();
                  g2d.setColor(new Color(128, 128, 128, 128));
                  g2d.fillRect(0, 0, getWidth(), getHeight());
                  int x = xPos - (img.getWidth() / 2);
                  int y = yPos - (img.getHeight()/ 2);
                  g2d.drawImage(img, x, y, this);
                  g2d.dispose();
              }
          }
      
      }
      

      这篇关于如何在透明窗口上绘制图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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