在使用android布局管理器器的时候Setsize()不是失效的吗?为什么JScrollpane的setsize

2014华为Java笔试题+数据库题(4)
当前位置:>>> 2014华为Java笔试题+数据库题(4)
2014华为Java笔试题+数据库题(4)
来源:笔试题目
  29、38.在JavaSwing编程中,要获取每次选择的JComboBox对象的选项值,可以使用()类型的监听器. (选择两项)
  A、ActionListener
  B、ltemListener
  C、KeyListener
  D、SelectionListener
  30、在Java中,下面关于包的陈述中正确的是()。(选择两项)
  A、包的声明必须是源文件的第一句代码
  B、包的声明必须紧跟在import语句的后面
  C、只有公共类才能放在包中
  D、可以将多个源文件中的类放在同一个包中
  31、在Java中,要想使只有定义该类所在的包内的类可以访问该类,应该用( )关键字。(选择一项)
  A、不需要任何关键字
  B、private
  C、final
  D、protected
  32、包pack1的类class1中有成员方法: protected void method_1(){&}, private void method_2(){&}, public void method_3(){&}和void method_4(){&},在包pack2中的类class2是class1的子类,你在class2中可以调用方法()。(选择两项)
  A、method_1
  B、method_2
  C、method_3
  D、method_4
  33、在Java语言中,小明在他的包mypackage中定义了类My_Class,在mypackage的子包mysubpackage中也有个类My_Class。小明用.import mypackage:引入包,执行其中的语句:My_Class NewClass=New My_Class();时,将发生()。(选择一项)
  A、创建一个类mypackage.My_Class对象
  B、创建一个类mypackage. Mysubpackage.My_Class的对象
  C、该语句是错误的
  D、创建一个类mypackage.My_Class的对象和一个类mypackage. Mysubpackage.My_Class的对象
  34、41.在JavaSwing编程中,给定一个java程序main方法的代码片段如下: JFrame jf=new JFrame(); jf.getContentpane().setLayout(null); jf.setSize(200,200); jf.setVisible(true); //a 要在界面上显示如下组件,则应在A处填入(). (选择一项)
  A、JTextArea text = text JTextArea(100,100);text.setBounds(10,10,150,100);jf.getContentpane().add(text);
  B、JTextField text = text JTextField(100,100);JScrollpane text=new JScrollpane(text);jf.setBounds(10,10,150,100);jf.getContentpane().add(jp);
  C、JTextArea text = new JTextArea(100,1);JScrollpane jp=new
  JScrollpane(text);jp.setBounds(10,10,150,100);jf.getContentpane().add(jp);
  D、JTextArea text = new JTextArea(100,100);JScrollpane jp=new JScrollpane(text);jp.setBounds(10,10,150,100);jf.getContentpane().add(jp);
  35、在JAVA语言中,你的按钮要实现下面的功能:当鼠标按下按钮时,显示&鼠标已按下&;当释放按键时,显示&鼠标已释放&。你必须具体定义接口MouseListener的()方法。(选择两项)
  A、mouseClicked
  B、mouseEntered
  C、mouseExited
  D、mousePressed
  E、mouseReleaseed
  36、JAVA中,为了辨别用户关闭窗口的时间,要实现监听器接口()。(选择一项)
  A、MouseListener
  B、ActionListener
  C、WindowListener
  D、以上都要
  37、在Java语言中,当一个类的某个变量声明为protected时下列说法正确的是()。(选择两项)
  A、只有同一类中的成员才能访问它
  B、不同包中的任何其他类都能够访问它
  C、同包中的任何其他类能够访问它
  D、不同包中的子类可以访问该变量
  38、在Java事件处理模型中,当按下鼠标按钮时,处理()事件。(选择一项)
  A、mouseReleased
  B、mouseExited
  C、mousePressed
  D、mouseDown
  39、 String s1=new String(&Hello&); String s2=new String(&there&); String s3=new String(&0&); 上面是JAVA程序的一些声明,以下选项中能够通过编译的是()。(选择一项)
  A、a) s3=s1+s2
  B、b) s3=s1&s2
  C、c) s3=s1||s2
  D、d) s3=s1&&s2
  40、在Java中,调用Math.random() 方法可能返回的结果是()。(选择一项)
  A、132.34
  B、0.342
  C、29.34E10
  D、1.0009
  41、 在Java语言中,Panel默认的布局管理器是()。(选择一项)
  A、BorderLayout
  B、FlowLayout
  C、GridLayout
  D、GridBagLayout
  42、public class MyClass1 { public static void main(String argv[]){} ______class MyInner{} } 在以上Java代码的横线上,可放置()修饰符。(选择两项)
  A、public
  B、private
  C、implements
  D、friend
  43、在java中,下列赋值语句正确的是()。(选择二项)
  A、char c='a';
  B、char c=&a&;
  C、char c=97;
  D、char c=new Character('a');
  44、与传统的过程编程不同,面向对象方法的主要思想是()。(选择两项)
  A、真实反映用户的实际需求
  B、将现实世界的一切抽象为实体或对象
  C、将现实世界细分为一个过程化实现
  D、将软件组织成为对象的集合,将数据结构和行为结合在一起
  45、在Java中,根据你的理解,下列方法()可能是类Orange的构造方法。(选择3项)
  A、Orange(){&}
  B、Orange(&){&}
  C、Public void Orange(){&}
  D、Public Orange(){&}
  E、Public Orange Constuctor(){&}
  46、45.在Java中,()借口位于集合框架的顶层. (选择一项)
  A、Map
  B、Collection
  C、Set
  D、List
  47、给定某java程序片段,如下: int i=1; int j=i++; if((i&++j)&&(i++==j)) i+=j; System.out.println(i); 该程序运行后,i的输出结果为()。(选择一项)
  48、在Java中,假设我们有一个实现ActionListener接口的类,以下方法中()能够为一个Button类注册这个类。(选择一项)
  A、addListener()
  B、addActionListener()
  C、addButtonListener()
  D、setListener()
  49、44.在JAVA中的布局管理器,以下说法中错误的是(). (选择一项)
  A、FlowLayout以由上到下的方式从左到右排列组件
  B、BorderLayout使用 &东&.&西&.&南&.&北&,&居中&来指定组件的位置
  C、GridLayout可以创建网格布局,网格布局中各组的大小可以任意调整
  D、可以通过容器的setLayout方法为容器指定布局管理
  50、研究下面的Java代码: public class testException{ public static void main(String args[]){ int n[]={0,1,2,3,4}; int sum=0; try { for(int i=1;i&6;i++) sum=sum+n[i]; System.out.println(&sum=&+sum); } catch(ArrayIndexOutOfBoundsExpception e) { System.out.println(&数组越界&); } finally{System.out.println(&程序结束&);} } } 输出结果将是()。(选择一项)
  A、10 数组越界 程序结束
  B、10 程序结束
  C、数组越界 程序结束
  D、程序结束
  1、在java中如果声明一个类为final,表示什么意思?
  答:final是最终的意思,final可用于定义变量、方法和类但含义不同,声明为final的类不能被继承。
  2、父类的构造方法是否可以被子类覆盖(重写)?
  答:父类的构造方法不可以被子类覆盖,因为父类和子类的类名是不可能一样的。
  3、请讲述String 和StringBuffer的区别。
  答:String 类所定义的对象是用于存放&长度固定&的字符串。
  StringBuffer类所定义的对象是用于存放&长度可变动&的字符串。
  4、如果有两个类A、B(注意不是接口),你想同时使用这两个类的功能,那么你会如何编写这个C类呢?
  答:因为类A、B不是接口,所以是不可以直接继承的,但可以将A、B类定义成父子类,那么C类就能实现A、B类的功能了。假如A为B的父类,B为C的父类,此时C就能实现A、B的功能。
  5、结合JavaLesson5(多线程),分析sleep()和wait()方法的区别。
  答: Sleeping睡眠的意思 : sleep() 方法用来暂时中止执行的线程。在睡眠后,线程将进入就绪状态。
  waiting等待的意思: 如果调用了 wait() 方法,线程将处于等待状态。用于在两个或多个线程并发运行时。
  6、谈谈你对抽象类和接口的理解。
  答:定义抽象类的目的是提供可由其子类共享的一般形式、子类可以根据自身需要扩展抽象类、抽象类不能实例化、抽象方法没有函数体、抽象方法必须在子类中给出具体实现。他使用extends来继承。
  接口:一个接口允许一个类从几个接口继承而来,Java 程序一次只能继承一个类但可以实现几个接口,接口不能有任何具体的方法,接口也可用来定义可由类使用的一组常量。其实现方式是interface来实现。
下页更精彩:1
2014华为Java笔试题+数据库题(4)相关推荐网格包布局管理是最复杂和灵活的布局管理,在下面会作详细的介绍。
与网格布局管理器不同的是,网格包布局管理器允许容器中各个组件的大小各不相同,还允许组件跨越多个网格,也允许组件之间相互部分重叠。
网格包布局理解为网格单元布局更合理,因为一个容器被划分为若干个网格单元,而每个组件放置在一个或多个网格单元中。
要注意的是,网格包布局不能指定一个容器的网格单元的大小其网格单元的划分是通过和参数来设置的,但也不是直接指定其网格单元的大小。当把一个组件放置在网格单元中时,组件所占据的位置和大小是由一组与他们相关联的约束来决定的。这些约束是由类型的对象来设置的,关于类型,后面会做专门的介绍。
由上所述使用网格包布局的一般步骤为:
1、创建一个网格包布局对象,并使其成为当前容器的布局管理器。
2、创建一个类型的约束对象,然后使用该对象设置各种约束条件,注意这里设置的约束条件并没有针对某一组件,要使某一组件具有设置的约束,需要使用第步骤的方法。
3、然后使用网格包布局中的方法将类型对象设置的约束添加到被设置的组件中,这样该组件就具有了设置的约束。其中的第一个参数是将要添加的组件,第二个参数是类型的约束对象。
4、最后将设置了约束的组件添加到容器中。
使用网格包布局的第二种方法为:
1、使布局成为当前容器的布局管理器,这里也可以不用创建对象。
2、创建一个类型的约束对象,然后使用该对象设置约束条件。注意这里设置的约束条件并没有针对某一组件,要使某一组件具有设置的约束,需要使用第步骤的方法。
3、然后使用方法将组件和约束同时添加进容器中,这样添加进容器的组件就具有了第步的约束。注意其中的第一个参数是将要添加的组件,第二个参数是要添加的类型的约束对象。
GridBagConstraints类型的约束参数:
double weightx和参数默认值为
这是两个非常重要的参数,该参数直接影响到怎样设置网格单元的大小,因此常握好该参数就可以对网格包布局应用自如。
该参数对方向和方向指定一个加权值。这个加权值直接影响到网格单元的大小,比如的值分别为,,,则在容器的方向也就是列的方向,按一定的比例比如其具体算法请参看文件分配三个网格单元,其中加权值越大网格单元就越大,可以看出值的大小是没有关系的,加权值的作用是让容器以设定的值的比例在横向和纵向分配网格,且在容器的大小改变时这个比例不改变。
如果只设置了一个值,而组件却不只一个以上,则被设置了的这个组件的网格单元的大小为容器在方向的大小减去那两个组件的最小尺寸就是该组件的网格单元大小。默认情况下组件的最小尺寸是比较小的。
如果两个参数都为默认值,则组件会被显示在容器的中央,不管容器是放大还是缩小组件都只会显示在容器的中央。
由上所述,在使用网格包布局时首先应先使用和来划分网格单元不是直接划分而是按一定比例来划分,网格单元划分出来后,组件放置在网格单元中的位置和大小就由后面介绍的约束来决定。
一定要注意的是设置权值后要使当前的设置生效应使用函数一次,如果连续设置多个同一方向的权值,则只有最后一次设置的权值有效,比如出现同时两行都设置了方向的权值,则以最后一行设置的方向的权值为标准来划分网格单元。
因此在使用网格包布局管理器之前应先设置好网格单元,即要把容器划分为几行几列的网格单元,每行每列在容器中的宽度和高度比例,每个组件应在哪个网格单元。
int fill参数默认值为
fill参数指定组件填充网格的方式,当某组件的网格单元大于组件的大小时被使用,一般情况下组件是以最小的方式被显示的,如果不使用参数,则有可能组件占不完整个网格单元,也就是说组件占据的空间比划分的网格单元小,这时组件将显示在网格单元中的某个位置具体在什么位置由网格包中的参数来设置。其可取的值如下:
GridBagConstraints.NONE默认值,不改变组件的大小。
GridBagConstraints.HORIZONTAL使组件足够大,以填充其网格单元的水平方向,但不改变高度,其值等于整数。
GridBagConstraints.VERTICAL使组件足够大,以填充其网格单元的垂直方向,但不改变宽度,其值等于整数。
GridBagConstraints.BOTH使组件足够大,以填充其整个网格单元,其值等于整数。
int gridwidth和参数默认值为
该参数指定组件占据多少个网格单元,指定组件占据多少个网格单元的宽度,指定组件占据多少个网格单元的高度。两个参数的默认值都为。其中值表示当前组件在其行或列上为最后一个组件,也就是说如果是行上的最后一个组件的话,那么下一个组件将会被添加到容器中的下一行,如果在行上不指定该值同时也不指定和参数,那么无论添加多少个组件都是在同一行上,同样如果在列上不指定该值同时也不指定和参数则无论添加多少行组件,都无法把容器填满。值表示当前组件在其行或列上为倒数第二个组件。
import java.awt.*;
public class Program
{public static void main(String[] args)
{ Frame ff = new Frame();
GridBagLayout gr = new GridBagLayout();
GridBagConstraints gc = new GridBagConstraints();
//创建一个名为gc的约束对象
ff.setLayout(gr);
//将容器ff的布局设为GridBagLayout
//创建一组按钮组件
Button bb1 = new Button(“bb1”);
Button bb2 = new Button(“bb2”);
Button bb3 = new Button(“bb3”);
Button bb4 = new Button(“bb4”);
Button bb5 = new Button(“bb5”);
Button bb6 = new Button(“bb6”);
Button bb7 = new Button(“bb7”);
Button bb8 = new Button(“bb8”);
GridBagConstraints.BOTH;//设置约束的fill参数,该参数表示当组件的大小小于网格单元的大小时在水平和垂直方向都填充,
gc.weightx =11; //设置x方向的加权值为11。
gc.weighty = 11;//设置y方向的加权值为11。
gr.setConstraints(bb1, gc); //将以上gc所设置的约束应用到按钮组件bb1
gc.weightx = 22;//设置x方向的加权值为22,如果不设置weightx则以下的组件都将自动应用上面所设置的weightx值11。
gr.setConstraints(bb2, gc);
//将以上所设置的约束应用到按钮组件bb2。
//gc.weighty=111; //注意如果不注释掉该行,则以后使用gc约束的按钮组件在y方向的加权值将为111,而在前面设置的y方向的加权值11将失去作用。
gc.weightx =33;
gc.gridwidth = GridBagConstraints.REMAINDER;//设置gridwidth参数的值为REMAINDER这样在后面使用该约束的组件将是该行的最后一个组件。
gr.setConstraints(bb3, gc); //第一行添加了三个按钮组件bb1,bb2,bb3,且这3个按钮的宽度按weightx设置的值11,22,33按比例设置宽度
GridBagConstraints gc1 = new GridBagConstraints();//创建第二个约束gc1
gc1.fill = GridBagConstraints.BOTH;
gc1.weighty = 22;
//将第2行的y方向加权值设为22
gr.setConstraints(bb4, gc1);
gr.setConstraints(bb5, gc1);
gc1.gridwidth = GridBagConstraints.REMAINDER;
gr.setConstraints(bb6, gc1);
//第二行添加了三个按钮组件bb4,bb5,bb6
gc1.weighty =33;
gc1.gridwidth = GridBagConstraints.REMAINDER;
gr.setConstraints(bb7, gc1);//第三行添加了一个按钮组件bb7
gc1.weighty=0;
gr.setConstraints(bb8, gc1); //第四行添加了一个按钮组件bb8,bb8并没有添加到bb7的后面,因为bb8使用了bb7前面的gridwidth参数设置的值,所以bb8也是单独的一行。
ff.setSize(500, 300);
ff.add(bb1); ff.add(bb2);ff.add(bb3);
ff.add(bb4); ff.add(bb5); ff.add(bb6);
ff.add(bb7); ff.add(bb8);
ff.setVisible(true);} }
int gridx和参数默认值为
该参数表示组件被添加到容器中的或者坐标处,坐标以网格单元为单位,也就是说不管网格单元有多大,一个网格单元就是的大小,也就是说如果把和都设为,那么该组件会被显示到第二行的行二列上。其中值默认值表示当前组件紧跟在上一个组件的后面。
int ipadx和参数默认值为
ipadx和也被称为内部填充,该参数用以设置组件的最小尺寸,如果参数值为正值则组件的最小尺寸将比原始最小尺寸大,如果为负值,则组件的最小尺寸将会变得比原始的最小尺寸小。该参数也可以理解为直接为组件指定大小,这个设置的大小就是组件的最小尺寸。其设置后组件的大小为组件的原始最小尺寸加上个像素。
int anchor参数默认值为
该参数指定当组件的大小小于网格单元时,组件在网格单元中的位置。一般情况下,在设置了或者的加权值时,如果不使用参数填充空白区域,则组件的大小将小于网格单元的大小,这时使用参数就能看到其中的效果了。参数可取的值有:;;;;;;;;;即居中,北,东北,东,东南,南,西南,西,西北方向。
Insets insets参数默认值为
insets参数也被称为外部填充,该参数指定组件与网格单元之间的最小空白区域大小,要注意的是即使使用了参数填充横向和纵向但只要设置了参数,同样会留出所设置的空白区域,在设置的空白区域不会被填充。在使用该参数时需要设置对象的,,,四个方向的值来调整组件与网格单元之间的空白区域大小,比如其中是GridBagConstraints类型的约束对象,这里要注意后面的其中的第一个字母是大写的。当然也可以为指定负值,以扩大其网格单元。
import java.awt.*;
public class Program
{public static void main(String[] args)
{//将容器ff的布局设为GridBagLayout
Frame ff = new Frame();
GridBagLayout gr = new GridBagLayout();
GridBagConstraints gc = new GridBagConstraints(); //创建一个名为gc的约束对象
ff.setLayout(gr);
//创建一组按钮组件
Button bb1 = new Button(“bb1”);
Button bb2 = new Button(“bb2”);
Button bb3 = new Button(“bb3”);
Button bb4 = new Button(“bb4”);
Button bb5 = new Button(“bb5”);
Button bb6 = new Button(“bb6”);
Button bb7 = new Button(“bb7”);
Button bb8 = new Button(“bb8”);
gc.fill = GridBagConstraints.BOTH;
gc.weightx = 11;
gc.weighty = 11;
gr.setConstraints(bb1, gc);
gc.weightx = 22;
gc.gridx = 1;
gc.gridy = 1;
//将下一个组件放置在坐标为1,1的位置。
gr.setConstraints(bb2, gc);
gc.weightx = 33;
gc.gridx = 2;
gc.gridy = 1; //将下一个组件放置在坐标为2,1的位置。
gc.insets = new Insets(-10, -10, -10, -10); //将下一个组件与网格单元的空白区域向外扩展10个像素,在这里可以看到网格包布局允许组件之间重叠。
gc.gridwidth = GridBagConstraints.REMAINDER;
gr.setConstraints(bb3, gc);
GridBagConstraints gc1 = new GridBagConstraints();
gc1.weighty = 22;
gc1.ipadx = 50;
gc1.ipady = 50; //将组件的最小尺寸加大ipadx*2个像素。
gr.setConstraints(bb4, gc1);
gc1.ipadx = 0;
gc1.ipady = 0;
//将以后的组件的最小尺寸设置为默认值,如果省掉该行,则以后组件的最小尺寸都会加大ipadx*2个像素。
gc1.anchor = GridBagConstraints.NORTHWEST; //将下一个组件bb5的位置放置在单元网格的西北方向。
gr.setConstraints(bb5, gc1); //因为bb5未设置fill,同时bb5设置了weightx(由gc参数设置)和weighty两个值以确定bb5所在的网格单元的大小,因而组件bb5的原始最小尺寸无法占据整个网格单元。
gc1.fill = GridBagConstraints.BOTH;
gc1.gridwidth = GridBagConstraints.REMAINDER;
gr.setConstraints(bb6, gc1);
gc1.weighty = 33;
gc1.insets = new Insets(5, 15,40,150); //使下一个组件bb7与网格单元之间在上,左,下,右,分别保持5,15,40,150个像素的空白位置。
gr.setConstraints(bb7, gc1);
gc1.weighty = 0;
gc1.insets = new Insets(0, 0, 0, 0); //将insets的参数值设为默认值。
gr.setConstraints(bb8, gc1);
ff.setSize(500, 300);
ff.add(bb1); ff.add(bb2);
ff.add(bb3);
ff.add(bb4);
ff.add(bb5);
ff.add(bb6);
ff.add(bb7);
ff.add(bb8);
ff.setVisible(true);}}
此条目发表在
分类目录,贴了 , , ,
标签。将加入收藏夹。
推荐你看看下面这些相关的文章:
我的微信公众号
- 247,650 views - 104,372 views - 45,869 views - 35,842 views - 30,133 views - 27,256 views - 27,069 views - 25,841 views - 25,811 views - 25,464 views
站长微信:bsdlover
站长微博:java Swing布局中JFrame添加new JScrollPane(JTextArea)控制大小
[问题点数:60分,结帖人rachel_tang]
java Swing布局中JFrame添加new JScrollPane(JTextArea)控制大小
[问题点数:60分,结帖人rachel_tang]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
本帖子已过去太久远了,不再提供回复功能。您所在的位置: &
简述Java图形用户界面设计(Swing)
简述Java图形用户界面设计(Swing)
jamesfancy
jamesfancy的博客
Swing是一个用于开发Java应用程序用户界面的开发工具包。它以抽象窗口工具包(AWT)为基础使跨平台应用程序可以使用任何可插拔的外观风格。Swing开发人员只用很少的代码就可以利用Swing丰富、灵活的功能和模块化组件来创建优雅的用户界面。
作为一个 Java 程序员,从论坛上感受到使用 Java 开发程序的人越来多,心中不免欣慰。但是,同样是从论坛中,看到多数人提到 Java 就以为是网络开发&&不是这样的,Java 也可以开发应用程序,而且可以开发出漂亮的图形用户界面的应用程序,也就是 Windows/XWindow 应用程序。因此,我写下这篇文章,希望能带你进入 Java 图形用户界面设计之门。
下面,让我们开始&&
说明:所有代码均在 Windows XP + Eclipse 环境下编写和测试,示例图片均在 Windows XP 下捕捉。
一. AWT 和 Swing
二. 框架、监听器和事件
三. 按钮、切换按钮、复选按钮和单选按钮
四. 文本输入框、密码输入框
五. 窗格、滚动窗格和布局管理
六. 后记&&什么是 SWT (2006年补充)
一. AWT 和 Swing
AWT 和 Swing 是 Java 设计 GUI 用户界面的基础。与 AWT 的重量级组件不同,Swing 中大部分是轻量级组件。正是这个原因,Swing 几乎无所不能,不但有各式各样先进的组件,而且更为美观易用。所以一开始使用 AWT 的程序员很快就转向使用 Swing 了。
那为什么 AWT 组件没有消亡呢?因为 Swing 是架构在 AWT 之上的,没有 AWT 就没有 Swing。所以程序员可以根据自己的习惯选择使用 AWT 或者是 Swing。但是,最好不要二者混用&&除开显示风格不同不说,还很可能造成层次 (Z-Order) 错乱,比如下例:
&&&&&import&java.awt.BorderL &import&java.awt.B &&import&javax.swing.JB &import&javax.swing.JDesktopP &import&javax.swing.JF &import&javax.swing.JInternalF &import&javax.swing.JP &&public&final&class&AwtSwing&{ &&&&&&public&static&void&main(String[]&args)&{ &&&&&&&&&AwtSwing&as&=&new&AwtSwing(); &&&&&&&&&as.show(); &&&&&} &&&&&&JFrame&frame&=&new&JFrame(&Test&AWT&and&SWING&); &&&&&&JDesktopPane&jdp&=&new&JDesktopPane(); &&&&&&JInternalFrame&jif1&=&new&JInternalFrame(&controls&); &&&&&&JInternalFrame&jif2&=&new&JInternalFrame(&cover&); &&&&&&public&AwtSwing()&{ &&&&&&&&&frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); &&&&&&&&&frame.getContentPane().add(jdp); &&&&&&&&&&jif1.setContentPane(new&JPanel()); &&&&&&&&&jif2.setContentPane(new&JPanel()); &&&&&&&&&&jif1.getContentPane().setLayout(new&BorderLayout()); &&&&&&&&&jif1.getContentPane().add(new&Button(&AWT&Button&),&BorderLayout.WEST); &&&&&&&&&jif1.getContentPane().add(new&JButton(&Swing&Button&), &&&&&&&&&&&&&&&&&BorderLayout.EAST); &&&&&&&&&&jif1.setSize(200,&100); &&&&&&&&&jif2.setSize(200,&100); &&&&&&&&&&jdp.add(jif1); &&&&&&&&&jdp.add(jif2); &&&&&&&&&&frame.setSize(240,&140); &&&&&} &&&&&&public&void&show()&{ &&&&&&&&&frame.setVisible(true); &&&&&&&&&jif1.setVisible(true); &&&&&&&&&jif2.setVisible(true); &&&&&} &&}&
运行这个程序,并用鼠标拖动那个名为&cover&的子窗口,我们会发现一个非常有趣的现象,如图:
显然 cover 子窗口是在 controls 子窗口之上的,但是它只罩盖住了 Swing Button,没有罩盖住 AWT Button。再看一会儿,你是不是有这样一种感觉:Swing Button 是&画&上去的,而 AWT Button 则是&贴&上去的。这就是二者混用造成层次错乱的一个例子。
Swing 组件有美观、易用、组件量大等特点,也有缺点&&使用 Swing 组件的程序通常会比使用 AWT 组件的程序运行更慢。但是大家都还是更喜欢用 Swing 组件,原因何在?因为随着计算机硬件的升级,一点点速度已经不是问题。相反的,用户更需要美观的用户界面,开发人员则更需要易用的开发组件。
二. 框架、监听器和事件
框架 (Frame, JFrame) 是 Java 图形用户界面的基础,它就是我们通常所说的窗口,是 Windows/XWindow 应用程序的典型特征。说到 Windows/XWindow,大家很容易联想到&事件 (Event) 驱动&。Java 的图形用户界面正是事件驱动的,并且由各种各样的监听器 (Listener) 负责捕捉各种事件。
如果我们需要对某一个组件的某种事件进行捕捉和处理时,就需要为其添加监听器。比如,我们要在一个窗口 (JFrame) 激活时改变它的标题,我们就需要为这个窗口 (JFrame 对象) 添加一个可以监听到&激活窗口&这一事件的监听器&&WindowListener。
怎么添加监听器呢?这通常由组件类提供的一个 addXxxxxListener 的方法来完成。比如 JFrame 就提供有 addWindowListener 方法添加窗口监听器 (WindowListener)。
一个监听器常常不只监听一个事件,而是可以监听相关的多个事件。比如 WindowListener 除了监听窗口激活事件 (windowActivate) 之外,还可以监听窗口关闭事件 (windowClosing) 等。那么这些事件怎么区分呢?就靠重载监听器类 (Class) 的多个方法 (Method) 了。监听器监听到某个事件后,会自动调用相关的方法。因此我们只要重载这个方法,就可以处理相应的事件了。
不妨先看一个例子:
&&&&&import&javax.swing.*; &import&java.awt.event.*; &&public&class&TestFrame&extends&JFrame&{ &&&&&&private&int&counter&=&0; &&&&&&public&TestFrame()&{ &&&&&&&&&&&&&&&&&&addWindowListener(new&WindowAdapter()&{ &&&&&&&&&&&&&public&void&windowClosing(WindowEvent&e)&{ &&&&&&&&&&&&&&&&&System.out.println( &&&&&&&&&&&&&&&&&&&&&&Exit&when&Closed&event&); &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&System.exit(0); &&&&&&&&&&&&&} &&&&&&&&&&&&&&public&void&windowActivated(WindowEvent&e)&{ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&setTitle(&Test&Frame&&&+&counter++); &&&&&&&&&&&&&} &&&&&&&&&}); &&&&&&&&&&&&&&&&&&&setResizable(false); &&&&&&&&&setSize(200,&150); &&&&&} &&&&&&public&static&void&main(String[]&args)&{ &&&&&&&&&TestFrame&tf&=&new&TestFrame(); &&&&&&&&&tf.show(); &&&&&} &&}&
这个例子中,我们设计了一个窗口类(public class TestFrame extends JFrame { ... }),并且为这个窗口添加了一个窗口监听器 (addWindowListener(new WindowAdapter() ...)。而我们添加的这个窗口监听器主要监听了两个事件:窗口关闭 (public void windowClosing(WindowEvent e) ...) 和窗口激活 (public void windowActivated(WindowEvent e) ...)。在窗口关闭事件中我们退出了整个应用程序(System.exit(0);),而在窗口激活事件中,我们改变了窗口的标题 (setTitle(&Test Frame & + counter++);)。最后,我们在 main 方法中显示了这窗口类的一个实例,运行得到下图所示的结果:
这个程序的运行结果就是一个什么东西都没有加的框架,也就是一个空窗口。那么,你知道显示一个窗口最主要的几句代码吗?不知道没关系,我来告诉你,显示一个窗口只需要做三件事:生成实例(对象)&设置大小&显示,相应的,就是下面的三句代码:
JFrame&frame&=&new&JFrame(&Frame's&Title&); &frame.setSize(400,&300); &frame.setVisible(true);&
也许你会说:第一句的意思我清楚,第三句的意思我也明白,为什么一定要第二句呢?其实想想也就明白了,叫你画一个没法有大小的矩形你能画出来吗?不能。同样,没有大小的窗口,怎么显示?所以我们需要用 setSize(int width, int height) 方法为其设置大小。我们还有另一种方法:用 JFrame 的 pack() 方法让它自己适配一个大小。pack() 在多数时候是令人满意的,但有时,它也会让你哭笑不得&&多试试就知道了。
在 JFrame 中,我们使用 addWindowListener 方法加入一个监听器 WindowListener (addWindowListener(new WindowAdapter() ...) 去监听发生在 JFrame 上的窗口事件。WindowListener 是一个接口,在 java.awt.event 这个包中,但是上例中好象并没有使用 WindowListener,而是使用的 WindowsAdapter 吧,这是怎么回事?
WindowAdapter 是 WindowsListener 接口的一个最简单的实现,也在 java.awt.event 包中。如果我们直接使用 WindowListener 产生一个类,需要实现它的每一个方法 (一共 7 个)。但 WindowAdapter 作为 WindowListener 最简单的实现,已经实现了它的每一个方法为空方法 (即只包含空语句,或者说没有语句的方法)。用 WindowAdapter 就只需要重载可能用到的方法 (上例中只有 2 个) 就行了,而不需要再去实现每一个方法。优点显而易见&&减少编码量。
在 JFrame 上发生的窗口事件 (WindowEvent) 包括:
windowActivated(WindowEvent e)
窗口得到焦点时触发
windowClosed(WindowEvent e)
窗口关闭之后触发
windowClosing(WindowEvent e)
窗口关闭时触发
windowDeactivated(WindowEvent e)
窗口失去焦点时触发
windowDeiconified(WindowEvent e)
windowIconified(WindowEvent e)
windowOpened(WindowEvent e)
窗口打开之后触发
上例重载了其中两个方法。如果在上例运行产生的窗口和另外一个应用程序窗口之间来回切换 (在 Windows 操作系统中你可以使用 Alt+Tab 进行切换)&&试试看,你发现了什么?有没有现我们的示例窗口标题上的数字一直在增加,这便是在 windowActivated 事件中 setTitle(&Test Frame & + counter++) 的功劳。
而另一个事件处理函数 windowClosing 中的 System.exit(0) 则保证了当窗口被关闭时退出当前的 Java 应用程序。如果不作这样的处理会怎样呢?试验之后你会发现,窗口虽然关闭了,但程序并没有结束,但此时,除了使用 Ctrl+C 强行结束之外,恐怕也没有其它办法了。所以,这一点非常重要:你想在关闭窗口的时候退出应用程序,那就需要处理 windowClosing 事件。&&也不尽然,其实还有另外一个更简单的办法,让 JFrame 自己处理这件事&&你只需要如下调用 JFrame 的 setDefaultCloseOperation 即可:
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);&
在产生 JFrame 对象之后执行上述语句,就可以不用处理 windowsClosing 事件来退出程序了。
我们可以在 JFrame 对象中添加 AWT 或者 Swing 组件。但是,虽然它有 add 方法,却不能直接用于添加组件,否则崤壮鲆斐!恍啪褪允浴T斐烧飧鱿窒蟮脑蛑挥幸桓鼋馐停JFrame 不是一个容器,它只是一个框架。那么,应该怎么添加组件呢?
JFrame 有一个 Content Pane,窗口是显示的所有组件都是添加在这个 Content Pane 中。JFrame 提供了两个方法:getContentPane 和 setContentPane 就是用于获取和设置其 Content Pane 的。通常我们不需要重新设置 JFrame 的 Content Pane,只需要直接获取默认的 Content Pane 来添加组件等。如:
(new&JFrame()).getContentPane().add(new&Button(&test&button&))&
三. 按钮、切换按钮、复选按钮和单选按钮
按钮&&就是按钮,不会连按钮都不知道吧?
切换按钮,有两种状态的按钮,即按下状态和弹起状态,若称为选择状态或未选择状态。
复选按钮,又叫复选框,用一个小方框中是否打勾来表示两种状态。
单选按钮,又叫收音机按钮,以小圆框打点表示被选中。常成组出现,一组单选按钮中只有一个能被选中。
发现什么了吗?&&对了,这一部分是在讲各种各样的按钮,而且后三种按钮都有两种状态。先看看这些按钮都长成什么样:
上图中,从上到下,依次就是按钮、切换按钮、复选按钮和单选按钮。图示的窗口,就是下面这个例子的运行结果:
&&&&&import&java.awt.event.ActionE &import&java.awt.event.ActionL &import&java.awt.event.ItemE &import&java.awt.event.ItemL &&import&javax.swing.ButtonG &import&javax.swing.JB &import&javax.swing.JCheckB &import&javax.swing.JF &import&javax.swing.JL &import&javax.swing.JRadioB &import&javax.swing.JToggleB &&public&final&class&TestButtons&{ &&&&&&public&static&void&main(String[]&args)&{ &&&&&&&&&TestButtons&tb&=&new&TestButtons(); &&&&&&&&&tb.show(); &&&&&} &&&&&&JFrame&frame&=&new&JFrame(&Test&Buttons&); &&&&&&JButton&jButton&=&new&JButton(&JButton&);&&&&&&&JToggleButton&toggle&=&new&JToggleButton(&Toggle&Button&);&&&&&&&JCheckBox&checkBox&=&new&JCheckBox(&Check&Box&);&&&&&&&JRadioButton&radio1&=&new&JRadioButton(&Radio&Button&1&);&&&&&&&JRadioButton&radio2&=&new&JRadioButton(&Radio&Button&2&); &&&&&&JRadioButton&radio3&=&new&JRadioButton(&Radio&Button&3&); &&&&&&JLabel&label&=&new&JLabel(&Here&is&Status,&look&here.&);&&&&&&&public&TestButtons()&{ &&&&&&&&&frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); &&&&&&&&&frame.getContentPane().setLayout(new&java.awt.FlowLayout()); &&&&&&&&&&&&&&&&&&&jButton.addActionListener(new&ActionListener()&{ &&&&&&&&&&&&&public&void&actionPerformed(ActionEvent&ae)&{ &&&&&&&&&&&&&&&&&label.setText(&You&clicked&jButton&); &&&&&&&&&&&&&} &&&&&&&&&}); &&&&&&&&&&&&&&&&&&&toggle.addActionListener(new&ActionListener()&{ &&&&&&&&&&&&&public&void&actionPerformed(ActionEvent&ae)&{ &&&&&&&&&&&&&&&&&JToggleButton&toggle&=&(JToggleButton)&ae.getSource(); &&&&&&&&&&&&&&&&&if&(toggle.isSelected())&{ &&&&&&&&&&&&&&&&&&&&&label.setText(&You&selected&Toggle&Button&); &&&&&&&&&&&&&&&&&}&else&{ &&&&&&&&&&&&&&&&&&&&&label.setText(&You&deselected&Toggle&Button&); &&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&} &&&&&&&&&}); &&&&&&&&&&&&&&&&&&&checkBox.addItemListener(new&ItemListener()&{ &&&&&&&&&&&&&public&void&itemStateChanged(ItemEvent&e)&{ &&&&&&&&&&&&&&&&&JCheckBox&cb&=&(JCheckBox)&e.getSource(); &&&&&&&&&&&&&&&&&label.setText(&Selected&Check&Box&is&&&+&cb.isSelected()); &&&&&&&&&&&&&} &&&&&&&&&}); &&&&&&&&&&&&&&&&&&&ButtonGroup&group&=&new&ButtonGroup(); &&&&&&&&&&&&&&&&&&ActionListener&al&=&new&ActionListener()&{ &&&&&&&&&&&&&public&void&actionPerformed(ActionEvent&ae)&{ &&&&&&&&&&&&&&&&&JRadioButton&radio&=&(JRadioButton)&ae.getSource(); &&&&&&&&&&&&&&&&&if&(radio&==&radio1)&{ &&&&&&&&&&&&&&&&&&&&&label.setText(&You&selected&Radio&Button&1&); &&&&&&&&&&&&&&&&&}&else&if&(radio&==&radio2)&{ &&&&&&&&&&&&&&&&&&&&&label.setText(&You&selected&Radio&Button&2&); &&&&&&&&&&&&&&&&&}&else&{ &&&&&&&&&&&&&&&&&&&&&label.setText(&You&selected&Radio&Button&3&); &&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&} &&&&&&&&&}; &&&&&&&&&&&&&&&&&&radio1.addActionListener(al); &&&&&&&&&radio2.addActionListener(al); &&&&&&&&&radio3.addActionListener(al); &&&&&&&&&&&&&&&&&&group.add(radio1); &&&&&&&&&group.add(radio2); &&&&&&&&&group.add(radio3); &&&&&&&&&&frame.getContentPane().add(jButton); &&&&&&&&&frame.getContentPane().add(toggle); &&&&&&&&&frame.getContentPane().add(checkBox); &&&&&&&&&frame.getContentPane().add(radio1); &&&&&&&&&frame.getContentPane().add(radio2); &&&&&&&&&frame.getContentPane().add(radio3); &&&&&&&&&frame.getContentPane().add(label); &&&&&&&&&&frame.setSize(200,&250); &&&&&} &&&&&&public&void&show()&{ &&&&&&&&&frame.setVisible(true); &&&&&} &&}&
除一般按钮外,其余三种按钮都有两种状态,即选择 (按下) 状态和未选择 (弹起) 状态。那么我们又该如何判断呢?切换按钮 (JToggleButton) 提供了一个 isSelected() 方法用来判断当前所处的状态,返回值为真 (true) 时表示它处于选择状态,返回值为假 (false) 时表示它处于未选择状态。而复选按钮 (JCheckBox) 和单选按钮 (JRadioButton) 都是从 JToggleButton 继承的,所以也具有 isSelected() 方法。如上例中 if (toggle.isSelected()) { ... } 等。
单选按钮由自身的特点决定了它们必须成组出现,而且一组中只能有一个能被选中。因此我们需要用一个专门的类,ButtonGroup 来管理。添加到 ButtonGroup 的多个单选按钮中,如果有一个被选择中,同组中的其它单选按钮都会自动改变其状态为未选择状态。在 ButtonGroup 中添加按钮,是使用它的 add 方法,如上例中的 group.add(radio1);。
既然我们已经将多个单选按钮添加到一个 ButtonGroup 中了,那么我们是不是可以将一个包含多个单选按钮的 ButtonGroup 对象添加到 JFrame 的 Content Pane 中,以达到添加其中所有单选按钮的目的呢?不行!ButtonGroup 不是一个可显示的组件,它仅用于管理。所以,在往 JFrame 中添加一组 JRadioButton 的时候,需要一个一个的添加 JRadioButton,而不是笼统的添加一个 ButtonGroup。
上例中还用到了 JLabel,这不是按钮,而是一个静态文本组件,主要用于显示提示文本。要获得一个 JLabel 对象当前显示的文本内容,可以使用它的 getText() 方法;反之,要改变一个 JLabel 对象显示的文本,要使用它的 setText(String text) 方法,如上例中的 label.setText(&You selected Toggle Button&)。
其实这两个方法同样可以用于 JButton 等类。比如上例中我们使用 new JButton(&JButton&) 构造了一个按钮 jButton,如果使用 jButton.getText() 就可以得到字符串 &JButton&。而 jButton.setText(&A Button&),则可以改变按钮上显示的文字为 &A Button&。这两句代码没有在示例中写出来,你可以自己试试。
上例中大量使用了动作监听器 (ActionListener)。ActionListener 只监听一个事件,这个事件在其相关组件上产生了动作时被触发,因此叫作动作事件 (ActionEvent)。ActionListener 只有一个方法需要实现,就是 actionPerformed(ActionEvent event)。按钮、切换按钮和单选按钮被单击时都会触发动作事件,引起动作监听器调用 actionPerformed 方法。因此,如果你想在单击按钮之后做什么事,当然应该重载 ActionListener 的 actionPerformed 方法了。各种按钮都提供了 addActionListener 方法以添加动作监听器。
复选框就要特殊一些。虽然它也有 addActionListener 方法,意味着可以使用动作监听器,但是使用之后你会发现动作监听器并没有起到预想的作用。为什么?原来,单击一个复选按钮,触发的不是动作事件,而是条目事件 (ItemEvent) 中的状态变化 (itemStateChanged),由条目监听器 (ItemListener) 监听,相应需要重载的方法是 ItemListener 的 itemStateChanged 方法。
上例中我们将一个名为 al 的 ActionListener 添加到了每一个单选按钮中,如何判断是哪个单选按钮触发了事件并被 al 监听到了呢?我们可以从 ActionEvent 的 getSource() 方法得到触发事件单选按钮。由于 getSource() 返回的是一个 Object 引用,虽然这个引用指向的是一个单选按钮的实例,但我们还是需要将这个引用的类型转换为 JRadioButton,如上例中的:JRadioButton radio = (JRadioButton) ae.getSource(),只有这样我们才能调用 JRadioButton 有而 Object 没有的方法。
同时,还需要说明的一点是,每个单选按钮都可以添加一个单独的 ActionListener 实例,而不一定要添加同一个。同样的道理,若干毫不相干的、需要添加 ActionListener 的若干组件,也可以添加同一个 ActionListener 实例。关键在于编程者对 actionPerformed 方法的重载。比如下面这段代码就为一个 JButton 对象和一个 JRadioButton 对象添加了同一个动作监听器实例:
&&&&&import&javax.swing.*; &import&java.awt.event.*; &&public&class&Test&{ &&&&&&JButton&b; &&&&&JRadioButton& &&&&&&public&Test()&{ &&&&&&&&&JFrame&f&=&new&JFrame(&Test&); &&&&&&&&&f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); &&&&&&&&&f.getContentPane().setLayout( &&&&&&&&&&&&&new&java.awt.FlowLayout()); &&&&&&&&&b&=&new&JButton(&JButton&); &&&&&&&&&rb&=&new&JRadioButton(&RadioButton&); &&&&&&&&&ActionListener&a&=&new&ActionListener()&{ &&&&&&&&&&&&&public&void&actionPerformed(ActionEvent&ae)&{ &&&&&&&&&&&&&&&&&if&(ae.getSource()&==&b)&{ &&&&&&&&&&&&&&&&&&&&&System.out.println( &&&&&&&&&&&&&&&&&&&&&&&&&&You&clicked&the&JButton&); &&&&&&&&&&&&&&&&&}&else&{ &&&&&&&&&&&&&&&&&&&&&System.out.println( &&&&&&&&&&&&&&&&&&&&&&&&&&You&clicked&the&RadioButton&); &&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&} &&&&&&&&&}; &&&&&&&&&b.addActionListener(a); &&&&&&&&&rb.addActionListener(a); &&&&&&&&&f.getContentPane().add(b); &&&&&&&&&f.getContentPane().add(rb); &&&&&&&&&f.pack(); &&&&&&&&&f.show(); &&&&&} &&&&&&public&static&void&main(String[]&args)&{ &&&&&&&&&new&Test(); &&&&&} &&}&
运行程序后,分别单击两个按钮,相应的,在控制台能分别得到如下输出:
You clicked the JButton
You clicked the RadioButton
这说明多个不用的组件添加同一个监听器是可行的&&不过前提是这些组件都能添加这个监听器。
四. 文本输入框、密码输入框
文本输入框包括两种,单行文本输入框 (JTextField) 和多行文本输入框 (JTextArea)。密码输入框则只有一种 (JPasswordField)。JPasswordField 是 JTextField 的子类,它们的主要区别是 JPasswordField 不会显示出用户输入的东西,而只会显示出程序员设定的一个固定字符,比如 '*' 或者 '#'。
下面的示例图和代码是 JTextField、JPasswordField 和 JTextArea 的示例:
&&&&&import&javax.swing.JF &import&javax.swing.JL &import&javax.swing.JPasswordF &import&javax.swing.JTextA &import&javax.swing.JTextF &import&javax.swing.event.CaretE &import&javax.swing.event.CaretL &&public&final&class&TestTexts&extends&JFrame&{ &&&&&&public&static&void&main(String[]&args)&{ &&&&&&&&&TestTexts&tt&=&new&TestTexts(); &&&&&&&&&tt.setVisible(true); &&&&&} &&&&&&private&JLabel&label&=&new&JLabel(&Status&); &&&&&&private&JTextField&textF &&&&&&private&JPasswordField&pwdF &&&&&&private&JTextArea&textA &&&&&&public&TestTexts()&{ &&&&&&&&&super(&Test&Texts&); &&&&&&&&&setDefaultCloseOperation(EXIT_ON_CLOSE); &&&&&&&&&getContentPane().setLayout(new&java.awt.FlowLayout()); &&&&&&&&&&textField&=&new&JTextField(15); &&&&&&&&&&&&&&&&&&textField.addCaretListener(new&CaretListener()&{ &&&&&&&&&&&&&public&void&caretUpdate(CaretEvent&e)&{ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&label.setText(textField.getText()); &&&&&&&&&&&&&} &&&&&&&&&}); &&&&&&&&&&pwdField&=&new&JPasswordField(15); &&&&&&&&&pwdField.setEchoChar('#'); &&&&&&&&&&textArea&=&new&JTextArea(5,&15); &&&&&&&&&textArea.setLineWrap(true); &&&&&&&&&&getContentPane().add(textField); &&&&&&&&&getContentPane().add(pwdField); &&&&&&&&&getContentPane().add(textArea); &&&&&&&&&getContentPane().add(label); &&&&&&&&&&setSize(200,&200); &&&&&} &&}&
上例中,我们构造了一个宽度为 15 个字符的单行文本框 (textField = new JTextField(15);),并使用 addCaretListener 方法添加了一个 CaretListener (textField.addCaretListener ...)。CaretListener 监听文本光标的移动事件。当用户使用键盘、鼠标等移动了文本光标在 JTextField 中的位置时触发这个事件。我们需要重载 caretUpdate(CaretEvent e) 对事件进行处理 (public void caretUpdate(CaretEvent e) ...)。这样,我们可以在这里做类似 VB 中 TextBox 的 OnChange 事件中做的事情。
JTextField 有 5 个构造方法,常用其中的四个:
JTextField()
JTextField(int columns),如上例 textField = new JTextField(15);
JTextField(String text)
JTextField(String text, int columns)
其中,参数 text 是单行文本框的初始内容,而 columns 指定了单行文本框的宽度,以字符为单位。JTextField 中的文本内容可以用 getText() 方法获得。也可以用 setText 方法指定 JTextField 中的文本内容。
JPasswordField 是 JTextField 的子类,其构造方法也是类似的。JPasswordField 提供了 setEchoChar(char ch) 方法设置为了隐藏密码而显示的字符,默认为 '*' 字符,上例中则设置为了 '#' 字符 (pwdField.setEchoChar('#');)。与 JTextField 一样,JPasswordField 也用 getText 方法和 setText 获得或者设置文本内容 (当然在用户界面上是隐藏的)。
JTextField 是单行文本框,不能显示多行文本,如果想要显示多行文本,就只好使用多行文本框 JTextArea 了。JTextArea 有六个构造方法,常用的也是四个:
JTextArea()
JTextArea(int rows, int columns)
JTextArea(String text)
JTextArea(String text, int rows, int columns) 
text 为 JTextArea 的初始化文本内容;rows 为 JTextArea 的高度,以行为单位;columns 为 JTextArea 的宽度,以字符为单位。如上例中就构造了一个高 5 行,宽 15 个字符的多行文本框 (textArea = new JTextArea(5, 15);)。
多行文本框默认是不会自动折行的 (不过可以输入回车符换行),我们可以使用 JTextArea 的 setLineWrap 方法设置是否允许自动折行。setLineWrap(true) 是允许自动折行,setLineWrap(false) 则是不允许自动折行。多行文本框会根据用户输入的内容自动扩展大小,不信,自己做个实验&&如果不自动折行,那么多行文本框的宽度由最长的一行文字确定的;如果行数据超过了预设的行数,则多行文本框会扩展自身的高度去适应。换句话说,多行文本框不会自动产生滚动条。怎么办?后面讲到滚动窗格 (JScrollPane) 的时候,你就知道了。
多行文本框里文本内容的获得和设置,同样可以使用 getText 和 setText 两个方法来完成。
五. 窗格、滚动窗格和布局管理
窗格 (JPanel) 和滚动窗格 (JScrollPane) 在图形用户界面设计中大量用于各种组件在窗口上的布置和安排。这里所谓的布置和安排,就是布局 (Layout),因此不得不先说说布局。
将加入到容器(通常为窗口等) 的组件按照一定的顺序和规则放置,使之看起来更美观,这就是布局。布局由布局管理器 (Layout Manager) 来管理。那么,我们在什么时候应该使用布局管理器?应用选择哪种布局管理器?又该怎样使用布局管理器呢?
往往,我们设计一个窗口,其中是要添加若干组件的。为了管理好这些管理的布局,我们就要使用布局管理器。比如说,设计一个简单的编辑器,这个编辑器中只需要放置两个按钮和一个多行文本框。这些组件是让 Java 自己任意安排呢?还是按照一定的位置关系较规范的安排呢?当然应该选择后者。那么,为了按照一定的位置关系安排这些组件,我们就需要用到布局管理器了。
然后我们遇到了一个选择题&&使用哪种布局管理器。为此,我们首先要知道有些什么布局管理器,它们的布局特点是什么。常用的布局管理器有: FlowLayout、BorderLayout、GridLayout、BoxLayout 等,其中 FlowLayout 和 BorderLayout 最常用,本文主要也就只谈谈这两种布局管理器。下面列表说明它们的布局特点:
布局管理器 布局特点
FlowLayout
将组件按从左到右从上到下的顺序依次排列,一行不能放完则折到下一行继续放置
BorderLayout
将组件按东(右)、南(下)、西(左)、北(上)、中五个区域放置,每个方向最多只能放置一个组件(或容器)。
GridLayout
形似一个无框线的表格,每个单元格中放一个组件
就像整齐放置的一行或者一列盒子,每个盒子中一个组件
就上述的编辑器为例,如果选用 FlowLayout,那么两个按钮和一个多行文本框就会排列在一行&&当然这是窗口足够宽的情况;如果窗口稍窄一些,则可能分两行排列,第一行有两个按钮,而第二行是多行文本框&&这是最理想的情况;如果窗口再窄一些,就可能分三行排列,第一行和第二行分别放置一个按钮,第三行放置多行文本框。因此,如果窗口大小可以改变,那么三个组件的位置关系也可能随着窗口大小的变化而变化。其实上面所举的例程中,大部分都是用的 FlowLayout,那是因为我们没有要求组件的布局。
如果选用 BorderLayout 的情况又如何呢?我们可以试着加入一个窗格 (JPanel,稍后讲解),并将两个按钮放置在其中,然后将这个窗格加入到 BorderLayout 的北部 (即上部);再将多行文本框加入到 BorderLayout 中部。结果类似使用 FlowLayout 的第二种可能,是最理想的情况。而且,如果改变窗口大小,它们的位置关系仍然是北-中的关系,不会随之改变。
剩下的两种布局管理器,加以窗格 (JPanel) 的配合,也能够很好的安排上述编辑器所需的三个组件。但是由于它们的使用稍为复杂一些,所以就不讲了。下面就讲讲如何使用 FlowLayout 和 BorderLayout。
任何布局管理器,都需要用在容器上,比如 JFrame 的 Content Pane 和下面要说的 JPanel 都是容器(JFrame 默认的 Content Pane 实际就是一个 JPanel)。容器组件提供了一个 setLayout 方法,就是用来改变其布局管理器的。默认情况下,JFrame 的 Content Pane 使用的是 BorderLayout,而一个新产生的 JPanel 对象使用的是 FlowLayout。但不管怎样,我们都可以调用它们的 setLayout 方法来改变其布局管理器。比如上述的编辑器中,我们要让窗口 (JFrame 对象,假设为 frame) 使用 BorderLayout,就可以使用 frame.getContentPane().setLayout(new BorderLayout()); 来改变其布局管理器为一个新的 BorderLayout 对象。
然后,我们对布局管理器的直接操作就结束了,剩下的只需要往容器里添加组件。如果使用 FlowLayout,我们只需要使用容器的 add(Component c) 方法添加组件就行了。但是,如果使用 BorderLayout 就不一样了,因为要指定是把组件添加到哪个区域啊。那我们就使用容器的 add(Component c, Object o) 方法添加组件,该方法的第二个参数就是指明添加到的区域用的。例如,上述编辑器中要添加一个多行文本框到 BorderLayout 的中部,就可以用 frame.getContentPane().add(new JTextArea(5, 15), BorderLayout.CENTER) 来实现。
BorderLayout 的五个区域分别是用下列五个常量来描述的:
BorderLayout.EAST
BorderLayout.SOUTH
BorderLayout.WEST
BorderLayout.NORTH
BorderLayout.CENTER
刚才已经提到了使用 JPanel。JPanel 作为一个容器,可以包容一些组件,然后将这个 JPanel 对象作为一个组件添加到另一个容器 (称作父容器) 中。这个功能有什么好处呢?
上面不是提到 BorderLayout 的一个区域中只能添加一个组件吗?但是我们的编辑器需要添加两个按钮到它的北部,怎么办?下面的例子中,我们就会用的一个 JPanel 包容了这两个按钮,然后再将这个 JPanel 对象作为一个组件添加到设置布局管理器为 BorderLayout 的 Content Pane 中。
上面说到各布局管理器的布局特点的时候,几乎每一种都是一个区域只能添加一个组件,那我们想添加多个组件到一个区域的时候,就要用到 JPanel 了。如果还没有明白,稍后看一段程序可能更易于理解。
而滚动窗格 (JScrollPane) 呢?它是一个能够自己产生滚动条的容器,通常只包容一个组件,并且根据这个组件的大小自动产生滚动条。比如上面讲 JTextArea 的时候提到:JTextAera 会随用户输入的内容自动扩展大小,很容易打破各组件的布局。但是,如果我们将它包容在一个滚动窗格中,它的扩展就不会直接反映在大小的变化上,而会反映在滚动窗格的滚动条上,也就不会打破各组件的布局了。稍后的例子会让你清清楚楚。
是不是等着看例子了?好,例子来了:
&&&&&import&java.awt.BorderL &&import&javax.swing.JB &import&javax.swing.JF &import&javax.swing.JP &import&javax.swing.JScrollP &import&javax.swing.JTextA &&public&final&class&TestPanels&extends&JFrame&{ &&&&&&public&static&void&main(String[]&args)&{ &&&&&&&&&TestPanels&tp&=&new&TestPanels(); &&&&&&&&&tp.setVisible(true); &&&&&} &&&&&&public&TestPanels()&{ &&&&&&&&&setDefaultCloseOperation(EXIT_ON_CLOSE); &&&&&&&&&&JPanel&panel&=&new&JPanel(); &&&&&&&&&for&(int&i&=&0;&i&&&2;&i++)&{ &&&&&&&&&&&&&panel.add(new&JButton(&Button&00&&+&i)); &&&&&&&&&} &&&&&&&&&&JTextArea&textArea&=&new&JTextArea(5,&15); &&&&&&&&&textArea.setLineWrap(true); &&&&&&&&&JScrollPane&scrollPane&=&new&JScrollPane(textArea); &&&&&&&&&getContentPane().add(panel,&BorderLayout.NORTH); &&&&&&&&&getContentPane().add(scrollPane,&BorderLayout.CENTER); &&&&&&&&&&pack(); &&&&&} &&}&
这个例子的运行结果如下图,正是我们想要的结果&&上面两个按钮,下面是一个可以滚动的多行文本框:
上例中首先产生了一个 JPanel 对象 (JPanel panel = new JPanel();),然后将两个按钮置于其中 (panel.add ...);然后产生了一个多行文本框 (JTextArea textArea = new JTextArea(5, 15);),并使用一个滚动窗格将它包裹起来 (JScrollPane scrollPane = new JScrollPane(textArea);),使之成为可以滚动的多行文本框。最后将两个容器 (JPanel 对象和 JScrollPane 对象) 分别添加到了窗口的北部 (getContentPane().add(panel, BorderLayout.NORTH);) 和中部 (也就是剩余部分,getContentPane().add(scrollPane, BorderLayout.CENTER);)。
好像有点不对劲,是什么呢?对了,我们没有设置 Content Pane 的布局管理器为 BorderLayout 啊,为什么&&刚才不是说了吗,JFrame 的 Content Pane 的默认布局管理器就是 BorderLayout,所以不用再设置了。
好了,《简述 Java 图形用户界面设计》就告一段落了。由于篇幅有限,这里说的都是初级知识,有此基础,设计复杂一点的图形用户界面也就不是难事了!
原文链接:
【编辑推荐】
【责任编辑: TEL:(010)】
关于&&的更多文章
Java既是一种高级的面向对象的编程语言,也是一个平台。Java平台
所以姑娘,让我们做一枚花见花开的程序媛。
今天是被国际上众多科技公司和软件企业承认的业内人士
互联网一大真理便是,有痛点的地方就有机会。现在最想
Eclipse 是一个开源的、可扩展的集成开发环境。平台本
本书是为北大燕工教育研究院编写的计算机网络技术的学习教材。它以实际教学大纲为依据,全面系统的介绍了计算机网络技术知识
51CTO旗下网站

我要回帖

更多关于 qt 布局管理器 的文章

 

随机推荐