Unselected overlay in java

My question, essentially, is that in Java there is a way to have some type of disjoint overlay on the screen. By "un-selectable" I mean that if I overlay a JWindow / JFrame on a window from another process, for example, I can still interact with the window as usual, but I can display the content in a JWindow / JFrame that appears on top of the same time.

Just create a component and set the following flags. AutoRequestFocus / Focusable / Enabled to false does not reach my goal, because the overlay blocks the mouse click on anything behind it.

This will be on a Windows system, but is preferably not limited to the OS.

+4
source share
3 answers

, , JNA, . JNA

public class Main
{
    public static void main(String[] args)
    {
        TestFrame frame = new TestFrame();
        frame.setVisible(true);
        WinDef.HWND hwnd = User32.INSTANCE.FindWindow("SunAwtFrame", "Transparent Window");

        int wl =  User32.INSTANCE.GetWindowLong(hwnd, WinUser.GWL_EXSTYLE);
        wl = wl | 0x80000 | 0x20;
        User32.INSTANCE.SetWindowLong(hwnd, WinUser.GWL_EXSTYLE, wl);
    }

    public static long getHWnd(Frame f) {
        return f.getPeer() != null ? ((WComponentPeer) f.getPeer()).getHWnd() : 0;
    }

    static class TestFrame extends JFrame
    {
        public TestFrame()
        {
            super("Transparent Window");
            setUndecorated(true);
            setBackground(new Color(0, 0, 0, 0));
            setAlwaysOnTop(true);
            setSize(800, 600);
            // Without this, the window is draggable from any non transparent
            // point, including points  inside textboxes.
            getRootPane().putClientProperty("apple.awt.draggableWindowBackground", false);

            getContentPane().setLayout(new java.awt.BorderLayout());
            getContentPane().add(new JTextField("text field north"), java.awt.BorderLayout.NORTH);
            getContentPane().add(new JTextField("text field south"), java.awt.BorderLayout.SOUTH);
        }

        @Override
        public void paint(Graphics g)
        {
            super.paint(g);
            g.setColor(Color.BLUE);
            g.fill3DRect(0,0,100,100,false);
        }
    }
}
+1

, , . , , .

, ( SWT). , , . , , .

, .

paintloop .

, .

0

Watch this demo, it shows how to transmit click events from the glass panel (where you draw additional content) to the underlying "real" panel (where you want clicks / events to happen). See Method redispatchMouseEvent. The following are some relevant parts of the code:

glass = new FixedGlassPane(jFrame.getContentPane());
jFrame.setGlassPane(glass);

public class FixedGlassPane extends JPanel
    ...
    addMouseListener(this);
    addMouseMotionListener(this);
    addFocusListener(this);
    ...
  }

  public void mouseDragged(MouseEvent e) {
    if (needToRedispatch)
      redispatchMouseEvent(e);
  }

  public void mouseMoved(MouseEvent e) {
    if (needToRedispatch)
      redispatchMouseEvent(e);
  }

  ... other mouse event methods ...

 private void redispatchMouseEvent(MouseEvent e) {
    boolean inButton = false;
    boolean inMenuBar = false;
    Point glassPanePoint = e.getPoint();
    Component component = null;
    Container container = contentPane;
    Point containerPoint = SwingUtilities.convertPoint(this,
        glassPanePoint, contentPane);
    int eventID = e.getID();

    if (containerPoint.y < 0) {
      inMenuBar = true;
      container = menuBar;
      containerPoint = SwingUtilities.convertPoint(this, glassPanePoint,
          menuBar);
      testForDrag(eventID);
    }

    //XXX: If the event is from a component in a popped-up menu,
    //XXX: then the container should probably be the menu's
    //XXX: JPopupMenu, and containerPoint should be adjusted
    //XXX: accordingly.
    component = SwingUtilities.getDeepestComponentAt(container,
        containerPoint.x, containerPoint.y);

    if (component == null) {
      return;
    } else {
      inButton = true;
      testForDrag(eventID);
    }

    if (inMenuBar || inButton || inDrag) {
      Point componentPoint = SwingUtilities.convertPoint(this,
          glassPanePoint, component);
      component.dispatchEvent(new MouseEvent(component, eventID, e
          .getWhen(), e.getModifiers(), componentPoint.x,
          componentPoint.y, e.getClickCount(), e.isPopupTrigger()));
    }
  }

  private void testForDrag(int eventID) {
    if (eventID == MouseEvent.MOUSE_PRESSED) {
      inDrag = true;
    }
  }
}
0
source

All Articles