2012-08-07 154 views
8

我试图创建一个跟随鼠标并将点击传递给底层窗口的圆形窗口。Java透明窗口

我正在用Python和Qt(请参阅Python overlay window)这样做,但后来我切换到Java和Swing。但是我无法使窗口透明。我试过this method,但它不起作用,但我认为我的系统支持透明度,因为如果我开始Screencast-O-Matic(它是用Java),矩形实际上是透明的。

我该如何实现这样的目标? (我在Linux上的KDE4)

+0

你有这个问题的解决方案吗?我面临同样的问题..我已经提出了像Screencast-O-Matic这样的应用程序,它适用于Windows操作系统,但不适用于Linux ..请在这里建议如果您发现任何东西,http://stackoverflow.com/questions/25009276/swing-works-different-on-different-platform – tarkikshah 2014-07-30 09:28:22

+0

不,我为我的屏幕录像应用程序切换回PyQt,因为我有其他Java问题。 – 2014-07-30 10:29:10

+0

好的...谢谢.. – tarkikshah 2014-07-31 03:46:56

回答

2

如果你想这样做你自己,而无需使用外部的lib,你可以开始执行一个线程:

  • 设置透明窗口无形
  • 使桌面
  • 把这个截图作为你的窗口的背景图像的截图

或者你可以使用JavaFX

+0

我不能这样做,因为窗口会跟着鼠标,所以我不得不每隔一段时间都要截图,我认为这是一种效率低下的方法。 – 2012-08-07 11:44:07

+0

以及如何使用其他选项? – 2012-08-07 11:48:50

+0

对不起,我找不到JavaFX for Linux和JDK 6 – 2012-08-07 11:58:03

9

为什么Java教程How to Create Translucent and Shaped Windows无法正常工作?你使用的是最新版本的Java 6或Java 7吗? 在May/June issue of Java Magazine中,有一个关于需要java 7的形状和透明窗口的教程。您可能需要注册Java杂志才能阅读它。看看你是否可以在你的系统上运行:

import java.awt.*; //Graphics2D, LinearGradientPaint, Point, Window, Window.Type; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.SwingUtilities; 

/** 
* From JavaMagazine May/June 2012 
* @author josh 
*/ 
public class ShapedAboutWindowDemo { 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     //switch to the right thread 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame frame = new JFrame("About box"); 
       //turn of window decorations 
       frame.setUndecorated(true); 
       //turn off the background 
       frame.setBackground(new Color(0,0,0,0)); 
       frame.setContentPane(new AboutComponent()); 
       frame.pack(); 
       //size the window 
       frame.setSize(500, 200); 
       frame.setVisible(true); 
       //center on screen 
       frame.setLocationRelativeTo(null); 
      } 
     } 
     ); 
    } 

    private static class AboutComponent extends JComponent { 
     public void paintComponent(Graphics graphics) { 
      Graphics2D g = (Graphics2D) graphics; 

      //create a translucent gradient 
      Color[] colors = new Color[]{ 
          new Color(0,0,0,0) 
          ,new Color(0.3f,0.3f,0.3f,1f) 
          ,new Color(0.3f,0.3f,0.3f,1f) 
          ,new Color(0,0,0,0)}; 
      float[] stops = new float[]{0,0.2f,0.8f,1f}; 
      LinearGradientPaint paint = new LinearGradientPaint(
             new Point(0,0), new Point(500,0), 
             stops,colors); 
      //fill a rect then paint with text 
      g.setPaint(paint); 
      g.fillRect(0, 0, 500, 200); 
      g.setPaint(Color.WHITE); 
      g.drawString("My Killer App", 200, 100); 
     } 
    } 
} 
+0

我在Java 6上,这就是为什么我使用页面底部的兼容性方法...用你的例子我得到[this](https://dl.dropbox.com/u/9287758/Immagini/JavaNoTransparency.png) – 2012-08-07 12:07:04

+0

OK。 Java站点的Java教程需要Java 6更新10,所以只要你有这个,它应该可以工作。如果没有,那么必须有一个linux兼容性问题,在这种情况下,我建议你升级到JDK 7,看看是否修复它。 – Thorn 2012-08-07 15:41:05

3

如果你使用Java 6,你需要使用私有的API AWTUtilities。退房Java SE 6 Update 10 API更多细节

这是一个有点快劈,但它得到的想法跨越

public class TransparentWindow { 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 

     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 

       MyFrame frame = new MyFrame(); 
       frame.setUndecorated(true); 

       String version = System.getProperty("java.version"); 
       if (version.startsWith("1.7")) { 


        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
        GraphicsDevice graphicsDevice = ge.getDefaultScreenDevice(); 

        System.out.println("Transparent from under Java 7"); 
        /* This won't run under Java 6, uncomment if you are using Java 7 
        System.out.println("isPerPixelAlphaTranslucent = " + graphicsDevice.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSLUCENT)); 
        System.out.println("isPerPixelAlphaTransparent = " + graphicsDevice.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT)); 
        System.out.println("isPerPixelAlphaTranslucent = " + graphicsDevice.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.TRANSLUCENT)); 
        */ 
        frame.setBackground(new Color(0, 0, 0, 0)); 

       } else if (version.startsWith("1.6")) { 

        System.out.println("Transparent from under Java 6"); 
        System.out.println("isPerPixelAlphaSupported = " + supportsPerAlphaPixel()); 
        setOpaque(frame, false); 

       } 

       frame.setSize(400, 400); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 

      } 
     }); 

    } 

    public static class MyFrame extends JFrame { 

     public MyFrame() throws HeadlessException { 

      setContentPane(new MyContentPane()); 
      setDefaultCloseOperation(EXIT_ON_CLOSE); 

      addMouseListener(new MouseAdapter() { 
       @Override 
       public void mouseClicked(MouseEvent e) { 

        if (e.getClickCount() == 2) { 

         dispose(); 

        } 

       } 
      }); 

     } 
    } 

    public static class MyContentPane extends JPanel { 

     public MyContentPane() { 

      setLayout(new GridBagLayout()); 
      add(new JLabel("Hello, I'm a transparent frame under Java " + System.getProperty("java.version"))); 

      setOpaque(false); 

     } 

     @Override 
     protected void paintComponent(Graphics g) { 

      super.paintComponent(g); 

      Graphics2D g2d = (Graphics2D) g.create(); 
      g2d.setColor(Color.BLUE); 

      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)); 
      g2d.fillRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 20, 20); 

     } 
    } 

    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) { 

     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); 
//    com.sun.awt.AWTUtilities.setWindowOpaque(this, opaque); 
//    ((JComponent) window.getContentPane()).setOpaque(opaque); 

      } 

     } catch (Exception exp) { 
     } 

    } 

    public static void setOpacity(Window window, float opacity) { 

     try { 

      Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities"); 
      if (awtUtilsClass != null) { 

       Method method = awtUtilsClass.getMethod("setWindowOpacity", Window.class, float.class); 
       method.invoke(null, window, opacity); 

      } 

     } catch (Exception exp) { 

      exp.printStackTrace(); 

     } 

    } 

    public static float getOpacity(Window window) { 

     float opacity = 1f; 
     try { 

      Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities"); 
      if (awtUtilsClass != null) { 

       Method method = awtUtilsClass.getMethod("getWindowOpacity", Window.class); 
       Object value = method.invoke(null, window); 
       if (value != null && value instanceof Float) { 

        opacity = ((Float) value).floatValue(); 

       } 

      } 

     } catch (Exception exp) { 

      exp.printStackTrace(); 

     } 


     return opacity; 

    } 
} 

在Windows 7中产生

下的Java 6 Java6

Unde [R Java 7的 Java7

+0

我做了另一个它甚至没有编译 – 2012-08-07 22:10:56

+0

我不确定你的意思,检查我的例子 – MadProgrammer 2012-08-07 23:25:22

+0

我在Java 6上,它只编译AWTUtilities,但它运行时没有透明度。 – 2012-08-08 15:39:15

3

我想这会的工作,我已经尝试过it..to做一个JFrame或透明的,你需要先去除装饰Undecorated(true)框架的窗口。这里是示例代码:

import javax.swing.*; 
import com.sun.awt.AWTUtilities; 
import java.awt.Color; 

    class transFrame { 
     private JFrame f=new JFrame(); 
     private JLabel msg=new JLabel("Hello I'm a Transparent Window"); 

    transFrame() { 
     f.setBounds(400,150,500,500); 
     f.setLayout(null); 
     f.setUndecorated(true);  // Undecorates the Window 
     f.setBackground(new Color(0,0,0,25)); // fourth index decides the opacity 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     msg.setBounds(150,250,300,25); 
     f.add(msg); 
     f.setVisible(true); 
     } 

     public static void main(String[] args) { 
     new transFrame(); 
     } 

    } 

唯一的问题是你需要添加自己的代码关闭和最小化使用按钮。