Как сделать окно полностью (1) без заголовка (2) перемещаемым (3) только строкой меню [как прослушивать события мыши над строкой меню]

Мне бы хотелось, чтобы главное окно состояло только из строки меню и было подвижным.

Было бы лучше иметь некоторую оконную раму, чтобы перетащить. Но похоже, что это невозможно в Java. Итак, я пытался прослушивать события мыши напрямую, но не слышал их:

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 ответа

Решение

Проверьте Перемещение Windows.

Если у вас есть ссылка на рамку и строку меню, ComponentMover Класс может обеспечить эту функциональность одной строкой кода:

ComponentMover cm = new ComponentMover(frame, menuBar);

ComponentMover Класс - это класс общего назначения, перемещающий любой компонент, будь то рамка на рабочем столе или компонент на панели.

Я сделал это недавно в приложении, которое я сделал. Что я сделал, так это добавил MouseInputAdapter к фону, в моем случае на JPanel сидели все компоненты. Затем, если вы щелкнули в любом месте окна, которое не было другим компонентом, щелчок "прошел" до фона, и адаптер ввода получил его, что позволило мне перетащить все окно.

Чтобы это работало, вы должны добавить входной адаптер как MouseListener, так и MouseMotionListener.

Вот контроллер:

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

Окно - это окно верхнего уровня, которое слушатель должен переместить. Это на самом деле JFrame, который я назвал setUndecorated( true ); на. SView является разновидностью JPanel:

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

Мой входной адаптер:

   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 + '}';
      }      
   }
Другие вопросы по тегам