【问题标题】:Component goes back to origin once JLayeredComponent moves them to front layer一旦 JLayeredComponent 将它们移动到顶层,组件就会返回原点
【发布时间】:2021-04-16 17:38:32
【问题描述】:

我有一个程序,当您单击并拖动它们时,它会将按钮移动到屏幕的前面。问题在于,一旦分层窗格将组件添加到其他层之上的层,它会将组件移回JFrame 的原点。

package Control;

import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;

public class LayeredPaneTest {
static JLayeredPane layeredPane;

static int screenX;
static int screenY;

public static MouseListener getMouseListener(JComponent component) {
    MouseListener mListener = new MouseListener() {
        @Override
        public void mouseClicked(MouseEvent e) {}

        @Override
        public void mousePressed(MouseEvent e) {
            screenX = e.getXOnScreen();
            screenY = e.getYOnScreen();

            layeredPane.add(component, new Integer(1), 0); //this method is the one that makes the component go back to the origin
            //If I delete this method, the buttons no longer go back to the origin, but the layered obviously doesn't work
            //I've tried adding a setBounds method here for component, but it still goes back to the origin
        }

        @Override
        public void mouseReleased(MouseEvent e) {}

        @Override
        public void mouseEntered(MouseEvent e) {}

        @Override
        public void mouseExited(MouseEvent e) {}
    };
    return mListener;
}

public static MouseMotionListener getMouseMotionListener(JComponent component) {
    MouseMotionListener mmListener = new MouseMotionListener() {
        @Override
        public void mouseDragged(MouseEvent e) {
            int deltaX = e.getXOnScreen() - screenX;
            int deltaY = e.getYOnScreen() - screenY;
                
            component.setLocation(deltaX, deltaY);
        }

        @Override
        public void mouseMoved(MouseEvent e) {}

    };
    return mmListener;
}

private static void createAndShowGUI() {
    JFrame frame = new JFrame();
    frame.setLocation(0, 0);
    frame.setSize(400, 400);
    frame.setVisible(true);
    
    layeredPane = new JLayeredPane();
    
    JButton button1 = new JButton("JButton 1");
    button1.setBackground(Color.RED);
    button1.setSize(100, 50);
    button1.addMouseListener(getMouseListener(button1));
    button1.addMouseMotionListener(getMouseMotionListener(button1));
    layeredPane.add(button1, new Integer(0), 0);
    button1.setBounds(0, 0, button1.getWidth(), button1.getHeight());
    
    JButton button2 = new JButton("JButton 2");
    button2.setBackground(Color.BLUE);
    button2.setSize(100, 50);
    button2.addMouseListener(getMouseListener(button2));
    button2.addMouseMotionListener(getMouseMotionListener(button2));
    layeredPane.add(button2, new Integer(0), 0);
    button1.setBounds(100, 100, button2.getWidth(), button2.getHeight());
    
    JButton button3 = new JButton("JButton 3");
    button3.setBackground(Color.GREEN);
    button3.setSize(100, 50);
    button3.addMouseListener(getMouseListener(button3));
    button3.addMouseMotionListener(getMouseMotionListener(button3));
    layeredPane.add(button3, new Integer(0), 0);
    button1.setBounds(200, 200, button3.getWidth(), button3.getHeight());
    
    frame.add(layeredPane);
}

public static void main(String[] args) {
    //Schedule a job for the event-dispatching thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
   }); 
}
}

我花了很多时间尝试切换方法、测试等等,但问题取决于方法layeredPane.add(component, new Integer(1), 0);。我对JLayeredPanes 很陌生,所以我一定缺少一些东西。

【问题讨论】:

    标签: java swing jlayeredpane


    【解决方案1】:

    问题不在于layeredPane.add() 方法,而在于您计算新组件位置的方式。

    假设按钮是一个位置,因此当您单击位置 (200, 100) 时,您会按下该按钮。那一刻你存储screenX=200; screenY=100;

    如果您现在将鼠标移动到 (210, 100),您将计算新位置为 deltaX = 210-200;deltaY = 100 - 100;,这会将组件放置在左上角。


    您可能应该在mousePressed 事件上存储鼠标相对于组件的偏移量,并在mouseDragged 事件上调整该偏移量的组件位置:

    static int offsetX;
    static int offsetY;
    
    public static MouseListener getMouseListener(JComponent component) {
        // [...]
        @Override
        public void mousePressed(MouseEvent e) {
            offsetX = e.getXOnScreen() - component.getX();
            offsetY = e.getYOnScreen() - component.getY();
    
            layeredPane.add(component, new Integer(1), 0);
        }
        // [...]
    }
    
    public static MouseMotionListener getMouseMotionListener(JComponent component) {
        MouseMotionListener mmListener = new MouseMotionListener() {
            @Override
            public void mouseDragged(MouseEvent e) {
                int posX = e.getXOnScreen() - offsetX;
                int posY = e.getYOnScreen() - offsetY;
                
                component.setLocation(posX, posY);
            }
            // [...]
        };
        return mmListener;
    }
    

    【讨论】:

    • 太棒了!非常感谢你让我开心!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-22
    • 1970-01-01
    • 2018-03-13
    • 2014-02-09
    相关资源
    最近更新 更多