How to make window all of (1) no title (2) moveable (3) only menu bar [how to listen mouse events over menu bar]

111 Views Asked by At

I would like to have main window consisting only of menu bar and moveable.

It would be better to have some window frame, to drag with. But looks like it is impossible in Java. So, I tried to listen mouse events directly, but can't hear them:

package tests.javax.swing;

import java.awt.Dimension;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Try_NarrowWindow {

    private static final Logger log = LoggerFactory.getLogger(Try_NarrowWindow.class);

    public static void main(String[] args) {




        SwingUtilities.invokeLater(new Runnable() {

            @SuppressWarnings({ "serial" })
            @Override
            public void run() {


                JFrame frame = new JFrame() {

                    Point mouseDownCompCoords;

                    {

                    setDefaultCloseOperation(EXIT_ON_CLOSE);
                    setResizable(false);
                    setUndecorated(true);

                    setMenuBar(new MenuBar() {{

                        add(new Menu("File") {{

                            add(new MenuItem("Open..."));
                            add(new MenuItem("Close"));
                            addSeparator();
                            add(new MenuItem("Exit") {{
                                addActionListener(new ActionListener() {
                                    @Override
                                    public void actionPerformed(ActionEvent e) {
                                        dispose();
                                    }
                                });
                            }});

                        }});

                        add(new Menu("Edit") {{

                            add(new MenuItem("Copy"));
                            add(new MenuItem("Cut"));
                            add(new MenuItem("Paste"));

                        }});


                    }});


                    addMouseListener(new MouseAdapter() {

                        public void mouseReleased(MouseEvent e) {
                            log.info("mouseReleased({})", e);
                            mouseDownCompCoords = null;
                        }
                        public void mousePressed(MouseEvent e) {
                            log.info("mousePressed({})", e);
                            mouseDownCompCoords = e.getPoint();
                        }
                    });

                    addMouseMotionListener(new MouseMotionAdapter() {
                        public void mouseDragged(MouseEvent e) {
                            log.info("mouseDragged({})", e);
                            Point currCoords = e.getLocationOnScreen();
                            setLocation(currCoords.x - mouseDownCompCoords.x, currCoords.y - mouseDownCompCoords.y);
                        }
                    });


                }};


                frame.setLocation(0,0);
                frame.pack();
                frame.setSize(new Dimension((int)Toolkit.getDefaultToolkit().getScreenSize().getWidth()*2/3, frame.getHeight()));
                frame.setVisible(true);

            }
        });

    }

}
2

There are 2 best solutions below

2
On BEST ANSWER

Check out Moving Windows.

Assuming you have a reference to the frame and the menu bar, the ComponentMover class can provide this functionality with a single line of code:

ComponentMover cm = new ComponentMover(frame, menuBar);

The ComponentMover class is s general purpose class move dragging any component, either a frame on the desktop, or a component on a panel.

0
On

I did this recently in an app I made. What I did was to add a MouseInputAdapter to the background, in my case the JPanel all the components were sitting on. Then if you clicked anywhere on the window that wasn't another component, the click went "through" to the background and the input adapter got it, allowing me to drag the whole window.

To make that work you have to add the input adapter as both a MouseListener and a MouseMotionListener.

Here's the controller:

   GuiController( SView sView, Window win )
   {
      view = sView;
      ...
      DragFrame dragListener = new DragFrame( win );
      view.addMouseListener( dragListener );
      view.addMouseMotionListener( dragListener );
   }

Window is the top level window that the listener needs to move. It's actually a JFrame that I called setUndecorated( true ); on. SView is a kind of JPanel:

public class SView extends javax.swing.JPanel
{ ...

My input adapter:

   private static class DragFrame extends MouseInputAdapter
   {
      private final Window window;
      int originalX;
      int originalY;
      int frameX;
      int frameY;

      public DragFrame( Window win )
      {
         if( win == null ) throw new IllegalArgumentException( 
                 "window cannot be null here.");
         window = win;
      }

      @Override
      public void mousePressed( MouseEvent e ) {
         Point loc = window.getLocationOnScreen();
         frameX = loc.x;
         frameY = loc.y;
         originalX = e.getXOnScreen();
         originalY = e.getYOnScreen();
//         System.out.println( this );
      }

      @Override
      public void mouseDragged( MouseEvent e )
      {
         int newX = frameX + e.getXOnScreen() - originalX;
         int newY = frameY + e.getYOnScreen() - originalY;
         window.setLocation( newX, newY );
//         System.out.println( this );
      }

      @Override
      public String toString()
      {
         return "DragFrame{" + "originalX=" + originalX +
                 ", originalY=" + originalY + ", frameX=" + frameX +
                 ", frameY=" + frameY + '}';
      }      
   }