简体   繁体   English

MouseListener 和 MouseMotionListener 不适用于 JPanel 里面有 JComponents

[英]MouseListener & MouseMotionListener don't work for JPanel with JComponents inside

I'm trying to drag JComponents which are inside a JPanel on a JFrame or better on the rootPane of the JFrame.我正在尝试在 JFrame 上的 JPanel 内或在 JFrame 的 rootPane 上拖动 JComponents。

The JPanel which contains the components is using a horizontal BoxLayout.包含组件的 JPanel 使用水平 BoxLayout。

When I run the code below I observed the following issues:当我运行下面的代码时,我观察到以下问题:

  1. The MouseListener & MouseMotionListener are only working for the JLabel MouseListener 和 MouseMotionListener 仅适用于 JLabel
  2. The JLabel seems to be not visible JLabel 似乎不可见
  3. On trying to drag, the JPanel with the JComponents inside the JTextfield & JButton disapper once I hover over the location where the JButton was dragged it becomes visible again.在尝试拖动时,一旦我在 JButton 被拖动的位置上 hover,JTextfield 和 JButton 内的 JComponents 的 JPanel 就会消失,它再次变得可见。

What am I doing wrong here?我在这里做错了什么? Such a little code and so many unexpected issues.这么少的代码和这么多意想不到的问题。

Please help!请帮忙!

Code to reproduce the issues:重现问题的代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

public class Main extends JFrame implements MouseListener, MouseMotionListener {
    private volatile int screenX = 0;
    private volatile int screenY = 0;
    private volatile int myX = 0;
    private volatile int myY = 0;
    private JPanel myPane;

public Main() {
    setSize(500,500);
    myPane = new JPanel();
    //myPane.setLayout(new BoxLayout(myPane, BoxLayout.X_AXIS));

    JTextField tf = new JTextField("Some text");
    tf.setEnabled(false);
    tf.setSize(110,20);
    JLabel l = new JLabel("°C");
    l.setSize(40,20);
    JButton b = new JButton("Button");

    myPane.setSize(new Dimension(tf.getWidth()+l.getWidth(), tf.getHeight()));

    myPane.add(tf);
    myPane.add(l);
    myPane.add(b);
    rootPane.add(myPane);

    myPane.addMouseListener(this);
    myPane.addMouseMotionListener(this);
}
public static void main(String[] args) {
    Main f = new Main();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setVisible(true);
}

@Override
public void mouseClicked(MouseEvent e) {

}

@Override
public void mousePressed(MouseEvent e) {
    screenX = e.getXOnScreen();
    screenY = e.getYOnScreen();
    myX = myPane.getX();
    myY = myPane.getY();
}

@Override
public void mouseReleased(MouseEvent e) {

}

@Override
public void mouseEntered(MouseEvent e) {
    System.out.println("Entered");
}

@Override
public void mouseExited(MouseEvent e) {

}

@Override
public void mouseDragged(MouseEvent e) {
    // only move when edit mode selected
    System.out.println("Dragged");
    int deltaX = e.getXOnScreen() - screenX;
    int deltaY = e.getYOnScreen() - screenY;

    myPane.setLocation(myX + deltaX, myY + deltaY);

    revalidate();
}

@Override
public void mouseMoved(MouseEvent e) {

}
}

Don't add components to the root pane.不要将组件添加到根窗格。 There are other components that will be added on top and cover your components.还有其他组件将添加到顶部并覆盖您的组件。

The panel should be added to the content pane and the content pane needs to use a null layout when dragging components.面板应添加到内容窗格中,并且内容窗格在拖动组件时需要使用 null 布局。

Read the section from the Swing tutorial on Using Top Level Containers .阅读 Swing 教程中有关使用顶级容器的部分。 There is also a link that goes into more detail on the root pane.还有一个链接可以在根窗格上进行更详细的说明。 As you will see the content pane covers the root pane.正如您将看到的,内容窗格覆盖了根窗格。

You can also check out Moving Windows the Basic Dragging section provides a simple reusable class that can be used to drag any component so you don't need to hardcode variable names in the class.您还可以查看移动 Windows基本拖动部分提供了一个简单的可重复使用的 class,可用于拖动任何组件,因此您无需在 class 中硬编码变量名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM