【Swing 7】坐标陷阱与单个组件拖放

时间:2021-12-13 07:10:23

  之前模仿QQ界面的时候,一直很苦恼布局的问题。虽说绝对定位相对于JFrame默

认的BorderLayout(布局管理器),,JPanel的FlowLayout(流式管理器)方便了不少。可

以通过setBounds()直接设置坐标,可要是组件一多起来。非把你累死不可。

  好了,不多说,为什么说会有陷阱呢。大家看看下面这两个有界面。源代码贴在这。

两个界面就差了句setUndecorated(true); 可以看出,无论有无边框,它们的大小都是

一样的。到这里倒是还没出现问题!接着往下看。

1 package demo; 2 3 import javax.swing.*; 4 import java.awt.*; 5 6 public class DrawPanel { 7 public static void main(String[] args) { 8 new DrawPanel(); 9 } 10 public DrawPanel() { 11 JFrame f = new JFrame(); 12 13 f.setUndecorated(true); // 去掉界面的边框 14 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 关掉界面时结束javaw.exe进程 15 f.setBounds(200, 200, 400, 300); // 参数分别是界面左上角的横, 纵坐标, 长和宽 16 f.setVisible(true); 17 } 18 }

去掉边框的界面

上面是什么都没加,空空如也的情况。接下来我们给它们加一个按钮,看看会有什么变化。

1 package demo; 2 3 import javax.swing.*; 4 import java.awt.*; 5 6 public class DrawPanel { 7 public static void main(String[] args) { 8 new DrawPanel(); 9 } 10 public DrawPanel() { 11 JFrame f = new JFrame(); 12 f.setUndecorated(true); // 去掉界面的边框 13 f.setLayout(null); // null即不使用JFrame默认的边界布局, 而是设置布局为绝对定位 14 15 JButton b = new JButton("点击"); 16 b.setBounds(50, 50, 60, 20); // 参数分别是界面左上角的横, 纵坐标, 长和宽 17 f.add(b); 18 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 关掉界面时结束javaw.exe进程 19 f.setBounds(200, 200, 400, 300); 20 f.setVisible(true); 21 } 22 }

添加按钮的对比

问题来了,来两张对比的图片。一目了然。

水平坐标(x值)的对比。

纵坐标(y值)的对比 

从上面两幅图很容易看出,有边框的按钮无论是左上角的x值或是y值都比没边框的

大了点。当然,这是相对于窗口来说的。现在,让我们来寻找真相。

System.out.println("按钮在界面上的坐标: " + b.getX() + ", " + b.getY());

很不幸,输出都是50, 50

这和前面我们设置按钮的位置时用的代码相符的。横纵坐标均是50。

b.setBounds(50, 50, 60, 20); // 参数分别是界面左上角的横, 纵坐标, 长和宽

咦,那就奇怪了。明明有边框的按钮横纵坐标明显都偏大。(事实上,那个多出来的坐

就是左边框和上边框啦!),我们再来证明一下。先要解决怎么获得坐标的问题,也就

是怎么得到界面上任一点的坐标呢?

有没有想到监听窗口呢?其实就是使用鼠标事件!