【Swing 填坑】JFrame的背景颜色和消失的组件+坐标的范围+ 设置组件大小

  记得有人说过Swing的坑多,使用了一个多月的我,这两天在想拖放组件的问

题时遇到了两个坑。

   参考: 设置界面背景颜色

       http://blog.csdn.net/pc620/article/details/6056507

 

附: 今天在做鼠标手势的时候,又他妈发现一个坑,看来,哥的人生就是注定来填坑

  的。假如我们设置的窗口/界面是new JFrame().setSize(100, 100);那么, 实际上

  横纵坐标的取值都是0~99像素                                            

                                 ——2017.3/6 

1. 背景颜色的坑

  你想和其它组件(如按钮)或JPanel容器一样用setBackground()为JFrame

设置背景颜色嘛?好吧,甭捣鼓了。看看下面的示例

 1 package demo;
 2 
 3 import javax.swing.*;
 4 
 5 public class MiniMusic {
 6     public static void main(String[] args) {
 7         new MiniMusic();
 8     }
 9     public MiniMusic() {
10         JFrame f = new JFrame();
11         
12         f.add(new JButton("提交"));  // 添加按钮
13         
14         // 在关闭窗口时结束javaw.exe进程, 释放内存
15         f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
16         f.setLocation(200, 200);
17         f.pack();   // 让JFrame自适应大小, 也就是显示刚好能够容纳按钮的空间
18         f.setVisible(true);
19     }
20 }

    一切正常。按钮被添加到JFrame中, 如果没加方位的话, 默认加到窗口的中间

。但是,当我们把JFrame的ContentPane容器隐藏之后, 

f.getContentPane().setVisible(false);

 

  看到了吧,一切空白。只是因为我们把Content Pane给设成了不可见。这

说明组件都是加在JFrame的Content Pane容器上。(即f.getContentPane())

也就是说,是不能直接在顶级容器类JFrame上添加组件的。而上面的f.add(),

其实就是f.getContentPane().add(); 所以,如果不想把Content Pane容器隐

藏掉的话,(这样就不能再添加组件了)。正确设置背景颜色的方式应该是

f.getContentPane().setBackground(Color.pink);

2. 消失的组件

  这一切都不会发生,如果你在f.setVisible(true);之前就都添加好所有组件

和话。可是,如果你一不小心,比如像下面这样,

  【注意: setLayout(null), 也就是绝对定位不受下面示例的影响】

      情景1: f.setSize()和f.setVisible(true)顺序正常, 所有组件在setVisible()

之后被添加。(包括声明和初始化组件后再add()或者直接add())。

      结果: 只有标签会显示, 其它组件不可见。但标签的add()不能被其它不可见的

组件挡住, 如 JLabel lab = ...; JTextField text = ...; f.add(lab); 这样标签即不可见,

把 f.add(lab); 放前面就OK了。

      特例: 如果组件在f.setVisible(true)之前, (可以是f.setSize()之后)被声明并初始化

,则该组件可见。

 1  package demo;
 2  
 3  import javax.swing.*;
 4   
 5  public class MiniMusic {
 6       public static void main(String[] args) {
 7           new MiniMusic();
 8       }
 9       public MiniMusic() {
10          JFrame f = new JFrame();
11          
12          // 在关闭窗口时结束javaw.exe进程, 释放内存
13          f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
14          f.setSize(400, 300);  
15          f.setVisible(true);
16          f.add("North", new JButton("北风")); // 添加按钮
17          f.add("South", new JButton("南阳")); 
18          f.add(new JTextField("请输入内容")); // 添加文本框
19      }
20  }

    情景2: 顺序是f.setVisible(true);和f.setSize(); 所有组件的声明和初始

化(或是直接add())都是放在f.setSize()后。

      结果: 只有文本框会被隐藏,且它的声明和初始化代码会让在它后面声明和

初始化(或者是直接add())的组件不可见。

      特例: 如果文本框的声明和初始化是放在f.setVisible(true)之前, 则所有不

可见的组件都可见。

 1  package demo;
 2 
 3 import javax.swing.*;
 4 
 5 public class MiniMusic {
 6    public static void main(String[] args) {
 7        new MiniMusic();
 8     }
 9    public MiniMusic() {
10        JFrame f = new JFrame();
11          
12          // 在关闭窗口时结束javaw.exe进程, 释放内存
13          f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
14          f.setVisible(true);
15          f.setSize(400, 300);   // 让JFrame自适应大小, 也就是显示刚好能够容纳按钮的空间
16          f.add("North", new JButton("北风")); // 添加按钮
17          f.add("South", new JButton("南阳")); 
18          f.add(new JTextField("请输入内容")); // 添加文本框
19   }
20 }

  这里面只有文本框被隐藏了。那么,如果我们调换文本框和南边的按钮顺序呢?

1 // 其它内容不变,调换文本框和位于南边的按钮的顺序
2 f.add(new JTextField("请输入内容")); // 添加文本
3 f.add("South", new JButton("南阳")); 

  这下连南边的按钮也消失了。这是为什么呢?So sorry! 这个坑,我也不知道

原因。写在这里只是想提醒自己和大家。尽量把要添加的组件都放在JFrame容器的

fsetSize()和f.setVisible(true); 前面,要是实在得放在后面的话, 在所有组件都

加完后加上必杀技:

      f.setVisible(true);

或   f.setValidate(); 

或   f.setSize() / f.pack();  

  最后一句重新绘制界面大小, 效果和我们直接拉伸窗口, 组件就会显示出来一样, 其

实就相当于再刷新一次, f.pack()同理。所以要和原来的大小不一样才行, 所以设置的

长和宽不能和原来完全一样。(至少要有一个改变的.)

                                                                                             —— 2017/3/3

3. setBounds()和setLocation()不要乱用

  今天,又有坑出现了,真不幸又被我撞到了,就是当setBounds()或者setLocatin()

用在三大布局管理器时,对FlowLayout和BoxLayout都是无效的, 但是若用在边界管理器, 

那事就多了。

   因为在BorderLayout管理器的管理下,所有组件或者容器必须放在东南西北中的其中

一个地方,所以如果被你用setBounds()设置的那个组件所在的方位(add()时设置的那个方

位)刚好被其它组件占据了, 那么这条语句才有用,别以为这样就值得高兴。更大的麻烦还在

后面。

 1 JFrame f = new JFrame();
 2 
 3 JButton b = new JButton("按钮");
 4 b.setBounds(300, 300, 80, 20);
 5 
 6 // 像这样按钮的方位刚好被其它组件占去的话,上面绝对定位设置的坐标才会管用
 7 f.add(b);
 8 f.add(new JButton("中间位置的按钮"));
 9 
10 f.setSize(400, 400);
11 f.setVisible(true);

  如果该按钮是被标签挡住了,那真是不幸中的万幸,因为按钮会覆盖在标签上面; 如果是

被文本框挡住了,那真是棋差一招, 被文本框挡住的话,就需要用鼠标移动到按钮上面,这样

它自己就会显示出来了。如果你拉伸窗口的话,按钮一会消失,一会又出现。能力有限,无法

解释; 如果是被另一个更大的按钮挡住的话, I'm so sorry, 只要鼠标一离开小按钮, 它又会被

挡住。

       所以千万不要在不是绝对定位的时候使用setBounds()或setLocation();

       只有取消使用布局管理器的时候,f.setLayout(null); 才去用这两种语句

4. 在BorderLayout和FlowLayout布局中setSize()无法对组件发挥作用

  这个我也解释不了

       解决方法: 使用setPreferredSize(new Dimension(int width, int height)); 设置首选

大小, 当然了, 对于边界布局和流式布局, 就算能改变大小, 也只是改变高度而已。

5. BoxLayout布局只适用于JPanel, 不能用于JFrame, 而三大布局管理器都能用于JPanel

   别问我了,天知道。

                                                                                                                  ——2017/3/7

posted @ 2017-03-03 09:26  坏小孩D_R  阅读(1344)  评论(0编辑  收藏  举报