2012-08-07 4 views
8

J'essaie de créer une fenêtre en forme de cercle qui suit la souris et passe des clics aux fenêtres sous-jacentes. Je le faisais avec Python et Qt (voir Python overlay window) mais j'ai ensuite basculé vers Java et Swing. Cependant je ne suis pas capable de rendre la fenêtre transparente. J'ai essayé this method mais cela ne fonctionne pas, cependant je pense que mon système supporte la transparence car si je commence Screencast-O-Matic (qui est en Java), le rectangle est en fait transparent.Fenêtre transparente Java

Comment puis-je réaliser quelque chose comme ça? (Je suis sous Linux KDE4)

+0

Avez-vous une solution à ce problème? Je suis confronté au même problème .. J'ai fait une application comme Screencast-O-Matic qui fonctionne bien pour Windows OS mais ne fonctionne pas pour le Linux..S'il vous plaît suggérer ici si vous avez trouvé quelque chose, http://stackoverflow.com/questions/25009276/swing-works-different-on-different-platform – tarkikshah

+0

Non, je suis revenu à PyQt pour mon application screencast, parce que j'avais d'autres problèmes avec Java. –

+0

ok ... Merci .. – tarkikshah

Répondre

2

Si vous voulez le faire vous-même, sans l'aide d'un lib externe, vous pouvez démarrer un thread qui effectue:

  • définir la fenêtre transparente invisible
  • faire une capture d'écran du bureau
  • mettre cette capture d'écran comme image de fond de votre fenêtre

Ou vous pouvez utiliser JavaFX

+0

Je ne peux pas faire cela parce que la fenêtre suivra la souris, donc je vais devoir prendre des captures d'écran à chaque fois, et je pense que c'est une méthode inefficace. –

+0

et qu'en est-il de l'utilisation de l'autre option? –

+0

Désolé mais je ne trouve pas JavaFX pour Linux et JDK 6 –

9

Pourquoi le didacticiel Java How to Create Translucent and Shaped Windows n'a pas fonctionné? Utilisez-vous la dernière version de Java 6 ou Java 7? Dans le May/June issue of Java Magazine, il y avait un tutoriel sur les fenêtres en forme et transparentes nécessitant java 7. Vous devrez probablement vous inscrire au magazine Java pour le lire. Voyez si vous pouvez obtenir ce pour fonctionner sur votre système:

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

Je suis sur Java 6, c'est pourquoi je utilisé les méthodes de compatibilité sur le bas de la page ... Avec votre exemple, je reçois [this] (https://dl.dropbox.com/u/9287758/Immagini/JavaNoTransparency.png) –

+0

OK. Le tutoriel Java sur votre site nécessite Java 6 mise à jour 10, donc tant que vous avez cela, cela devrait fonctionner. Si ce n'est pas le cas, il doit y avoir un problème de compatibilité avec Linux et dans ce cas, je vous recommande de passer à JDK 7 et de voir si cela le corrige. – Thorn

3

Si vous utilisez Java 6, vous devez utiliser les AWTUtilities API privées. Consultez la Java SE 6 Update 10 API pour plus de détails

EXEMPLE

C'est un peu de hack, mais il a l'idée à travers

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; 

    } 
} 

Sur Windows 7, il produit

Sous Java 6 Java6

Unde r Java 7 Java7

+0

Je l'ai fait, avec l'autre il n'a même pas compilé –

+0

Je ne suis pas sûr de ce que vous voulez dire, vérifiez mes exemples – MadProgrammer

+0

Je suis sur Java 6, il compile seulement avec AWTUtilities, mais il n'a aucune transparence quand je l'exécute . –

3

Je suppose que cela va fonctionner, je l'ai déjà essayé it..to faire une JFrame ou une fenêtre transparente, vous devez undecorate Undecorated(true) la première image. Voici un exemple de code:

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

    } 

Le seul problème est que vous devez ajouter votre propre code pour fermer et minimiser l'utilisation des boutons.

Questions connexes