2012-08-07 26 views
8

Estoy intentando crear una ventana en forma de círculo que siga al mouse y pase clics a las ventanas subyacentes.Ventana transparente de Java

Estaba haciendo esto con Python y Qt (vea Python overlay window) pero luego cambié a Java y Swing. Sin embargo, no puedo hacer que la ventana sea transparente. Intenté this method pero no funciona, sin embargo creo que mi sistema admite la transparencia porque si comienzo Screencast-O-Matic (que está en Java), el rectángulo es realmente transparente.

¿Cómo puedo lograr algo así? (Estoy en Linux KDE4)

+0

¿Tiene alguna solución para este problema? Estoy enfrentando el mismo problema. He hecho una aplicación como Screencast-O-Matic que funciona bien para el sistema operativo Windows pero no funciona para Linux. Sugiera aquí si encuentra algo, http://stackoverflow.com/questions/25009276/swing-works-different-on-different-platform – tarkikshah

+0

No, cambié a PyQt para mi aplicación de screencast porque tenía otros problemas con Java. –

+0

ok ... Gracias .. – tarkikshah

Respuesta

2

Si desea hacerlo por su cuenta, sin necesidad de utilizar una librería externa, se puede iniciar un hilo que realiza:

  • configurar la ventana transparente invisible
  • hacer una captura de pantalla del escritorio
  • poner esta imagen de fondo de pantalla de la ventana como

O usted podría utilizar JavaFX

+0

No puedo hacer esto porque la ventana seguirá el mouse, así que tendré que tomar capturas de pantalla cada cierto tiempo, y creo que es un método ineficiente. –

+0

y ¿qué pasa con el uso de la otra opción? –

+0

Lo siento pero no puedo encontrar JavaFX para Linux y JDK 6 –

9

¿Por qué no funcionó el tutorial de Java How to Create Translucent and Shaped Windows? ¿Estás usando la última versión de Java 6 o Java 7? En el May/June issue of Java Magazine, había un tutorial sobre ventanas formadas y transparentes que requieren Java 7. Probablemente necesites registrarte en la revista Java para poder leerlo. Ver si se puede conseguir que esto se ejecuta en el sistema:

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

Estoy en Java 6, es por eso que usó los métodos de compatibilidad en la parte inferior de la página ... Con su ejemplo obtengo [esto] (https://dl.dropbox.com/u/9287758/Immagini/JavaNoTransparency.png) –

+0

OK. El sitio tutorial de Java requiere la actualización 10 de Java 6, de modo que, mientras lo tenga, debería funcionar. De lo contrario, debe haber un problema de compatibilidad con Linux y en ese caso recomiendo que actualice a JDK 7 y vea si eso lo soluciona. – Thorn

3

Si está utilizando Java 6, es necesario hacer uso de las API AWTUtilities privadas. Echa un vistazo a la Java SE 6 Update 10 API para más detalles

Ejemplo

Esto es un poco de corte rápido, pero tiene la idea a través de

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; 

    } 
} 

En Windows 7 se produce

Bajo Java 6 Java6

Unde r Java 7 Java7

+0

Lo hice, con el otro ni siquiera compiló –

+0

No estoy seguro de lo que quiere decir, consulte mis ejemplos – MadProgrammer

+0

Estoy en Java 6, solo compila con AWTUtilities, pero no tiene transparencia cuando lo ejecuto . –

3

que supongo que esto va a funcionar, ya intentó hacer una it..to JFrame o una ventana transparente que necesita para undecorate Undecorated(true) el marco de la primera. Aquí está el código de muestra:

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

    } 

El único problema es que necesita agregar su propio código para cerrar y minimizar con los botones.