使用自定义夹点/手柄栏移动JFrame

时间:2014-04-12 20:13:25

标签: java swing awt mouseevent

我正在制作自定义JFrame。我已经有了这个布局,它完全正常:

enter image description here

框架未修饰,但我希望能够移动它。我希望我的自定义面板成为移动手柄,所以我所做的就是添加MouseMotionListener。 mouseDragged函数如下所示:

@Override
public void mouseDragged(MouseEvent e) {
    parent.setBounds(e.getX(), e.getY(), parent.getWidth(), parent.getHeight());

}

parent字段在构造函数中设置,并且是最终的。

当我尝试使用面板拖动框架时,它可以正常工作,但不是很正确。框架在屏幕上的两个位置之间不断闪烁。我能够移动框架,但它看起来很可怕。当我不拖动框架时,它不会闪烁。这两个位置是相对的,所以如果你移动框架,另一个移动框架(但不会与另一个保持相同的距离)。另一个问题是框架不能用鼠标移动。因此,如果您在x方向上移动100像素的帧,则帧会朝同一方向移动较少的像素。

如果没有发生这种情况,你怎么能为JFrame做一个移动的握把(实际上是什么导致它这样做?)

如果需要更多代码,请告诉我。

2 个答案:

答案 0 :(得分:2)

您还需要提供mousePressed以获取点击的初始点。然后使用该点进行一些计算。

尝试这样的事情,其中​​pXpY是类字段(并假设在面板构造函数中添加了侦听器

addMouseListener(new MouseAdapter() {
    public void mousePressed(MouseEvent me) {
        // Get x,y and store them
        pX = me.getX();
        pY = me.getY();
    }
});
addMouseMotionListener(new MouseMotionAdapter() {
    public void mouseDragged(MouseEvent me) {
        parent.setLocation(parent.getLocation().x + me.getX() - pX, 
                parent.getLocation().y + me.getY() - pY);
    }
});

这是一个完整的例子

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.LineBorder;

public class UndecoratedExample {

    private JFrame frame = new JFrame();

    class MainPanel extends JPanel {

        public MainPanel() {
            setBackground(Color.gray);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }
    }

    class BorderPanel extends JPanel {

        private JLabel label;
        int pX, pY;

        public BorderPanel() {
            label = new JLabel(" X ");
            label.setOpaque(true);
            label.setBackground(Color.RED);
            label.setForeground(Color.WHITE);

            setBackground(Color.black);
            setLayout(new FlowLayout(FlowLayout.RIGHT));

            add(label);

            label.addMouseListener(new MouseAdapter() {
                public void mouseReleased(MouseEvent e) {
                    System.exit(0);
                }
            });
            addMouseListener(new MouseAdapter() {
                public void mousePressed(MouseEvent me) {
                    // Get x,y and store them
                    pX = me.getX();
                    pY = me.getY();
                }
            });
            addMouseMotionListener(new MouseMotionAdapter() {
                public void mouseDragged(MouseEvent me) {
                    frame.setLocation(frame.getLocation().x + me.getX() - pX,
                            frame.getLocation().y + me.getY() - pY);
                }
            });
        }
    }

    class OutsidePanel extends JPanel {

        public OutsidePanel() {
            setLayout(new BorderLayout());
            add(new MainPanel(), BorderLayout.CENTER);
            add(new BorderPanel(), BorderLayout.PAGE_START);
            setBorder(new LineBorder(Color.BLACK, 5));
        }
    }

    private void createAnsShowGui() {
        frame.setUndecorated(true);
        frame.add(new OutsidePanel());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new UndecoratedExample().createAnsShowGui();
            }
        });
    }
}

答案 1 :(得分:1)

  

我希望我的自定义面板成为移动手柄,

查看Moving Windows,其中包含一个允许您在屏幕周围拖动窗口或在其父容器周围拖动任何组件的类。