开发者

How would you make a frame visible if the mouse is inside it and invisible when it's not in Java?

开发者 https://www.devze.com 2022-12-14 17:01 出处:网络
So if I was writing pseudo code: if(mouseInsideFrame==true) frame.setVisible(true); else frame.setVisible开发者_Python百科(false);

So if I was writing pseudo code:

if(mouseInsideFrame==true)
    frame.setVisible(true);
else
    frame.setVisible开发者_Python百科(false);

What method would I use for the mouseInsideFrame in the if statement?

Thanks


I came across a post on java.net that covers visibility options, including this one using a private AWT API.

public class TransparentFrame {
  private static final float OPAQUE = 1.0f;
  private static final float TRANSLUCENT = 0.1f;

  public static void main(String[] args) {
    final JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(600, 400);
    frame.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseEntered(MouseEvent e) {
        com.sun.awt.AWTUtilities.setWindowOpacity(frame, OPAQUE);
      }

      @Override
      public void mouseExited(MouseEvent e) {
        com.sun.awt.AWTUtilities.setWindowOpacity(frame, TRANSLUCENT);
      }
    });
    frame.setVisible(true);
  }
}

This is OK for toy code, but obviously I wouldn't use a private com.sun class for portable production code.


Update: Same method as before, but with more explicit step-by-step explanation.

Other respondents wonder what you want to achieve with this and question the design behind an app that unexpectedly jumps up at the user. I guess it's a matter of how dead set you are to implement this functionality exactly as you described. The technique itself may be useful for other purposes too, which is my main motivation for my new, improved revision of this answer.


As far as I know, a frame that's not visible can't capture mouse events. So it won't know if the mouse is inside it or not.

There's a loophole around this problem: If you make your frame visible but borderless and fully transparent, it will be visible in the technical sense but invisible to the user for practical purposes.

The borderless part is easy: setUndecorated(true).

It would be great if JFrame had a method like setOpaque() or setTranslucent() where you could make it fully transparent, but alas, it doesn't.

Another answer mentions a solution based on a Sun private class which does permit you to make the window transparent. This will work for current and probably near-future Sun JREs but is far from guaranteed to work with other and future JREs, so I can't recommend it. Sun expliticly advises against using their private classes this way.

There's an alternate, somewhat hacky alternative: The frame is left fully visible but it displays the image of a screenshot of the screen behind it. Because this means we're effectively looking through the frame, it's effectively invisible. This solution is described here: http://onjava.com/pub/a/onjava/excerpt/swinghks_hack41/index.html?CMP=OTC-FP2116136014 . The author and I both admit to this being a a bit clumsy; it also involves a lot more code than should be necessary. But it's based on standard Java coding and should be supported unchanged in many Java environments upward of about version 1.4 or so.

The tip describes how to create a Component that displays the screen background. That's fine for when you want the frame to be invisible, but what happens when you want it to be normally visible?

The thing to do is to give the JFrame's ContentPane a CardLayout and add both the TransparentBackground component and your intended main visible component (likely a JPanel) to it. With that set up, switching between "invisible" and visible involves simply:

  • setUndecorated(false) // (true)
  • cardLayout.last() // (first)

This switching, of course, will be controlled by a MouseListener you can add to the JFrame.


Out of the top of my head, there is a fairly easy way to get the position of the mouse on the screen (I think it has something to do with Toolkit). Now, if you can combine that with a way to find out your frame's position on the screen (if you don't already know), you have your solution.

I'm curious what you're trying to do though.


Given what you are trying to do, I would say you need two frames (or perhaps just JPanels and frame that does a lot of changing. One is to capture the mouse moving over it (make it transparent, undecorated or otherwise acceptably out of the way) and when the mouse moves over it, show the new frame (or panel) and then hide that when the mouse moves out of it.

The other answers here give you the basics on how to capture the mouse events and set the frame undecorated and transparent.


Normally you could use listeners. Specifically:

frame.addMouseListener(new MouseListener() {
    public void mouseEntered(MouseEvent evt) {
        frame.setVisible(true);
    }

    public void mouseExited(MouseEvent evt) {
        frame.setVisible(false);
    }
});

But the problem is that since your JFrame is not visible, there is no way to listen to mouse events!!!! At least, from what I know....

0

精彩评论

暂无评论...
验证码 换一张
取 消