最近在写一个界面,想能如下图这样显示,不知道要用到什么proe组件界面的设置

一个图形界面就算基本完成了_解决方案网当前位置:& &&&java图形界面之 寨子QQ登陆界面java图形界面之 寨子QQ登陆界面本文收集于网络,只用于方便查找方案,感谢源作者,如果侵权请联系删除java图形界面之 山寨QQ登陆界面
要山寨出QQ登陆界面,首先要对java的图形界面有一定的了解。在jdk1.4之前,图形界面所用到的所有类和接口都在javax.awt之下,在其之后就都在javax.swing里了。
关于图形界面的开发其实就类似于搭积木的过程,我们把所需要的控件一个一个的摆放到窗口里面我们所需要的位置,一个图形界面就算基本完成了。下面我们就拿QQ的登陆界面做一个示范。
首先我们先了解一下图形界面中所用到的一些基本的控件,这些都在Javax.swing内:
JFrame(JApplet)
图形中的顶级容器
最灵活的容器
JTextField
文本输入框
JPasswordField
密码输入框
复选框,多选框
其次就是布局方式,这关系到我们怎么样把积木摆放到我们想要的位置:
BorderLayout
将容器分为上北下南左西右东中间
FlowLayout
类似word文档
空布局,绝对布局 控件必须要指定起始坐标和宽度高度
下面我们就来看下实现QQ界面开发的步骤
1.定义一个QQFrame,让该类继承自JFrame。 2.在QQFrame类中定义主函数和初始化界面的方法。 3.在主函数中实例化QQFrame类的对象,调用初始化界面的方法。 4.在初始化界面的方法中,设置窗体的属性值(标题,大小,位置,大小调整,布局,关闭,可见,...) 5.设置窗体的背景图(单独定义方法进行设置),这里我们会用到添加图片的方法 6.创建容器或者元素控件添加到JFrame上。
1.创建北边区域的方法,设置标签
2.创建西边区域的方法,创建容器,添加标签显示图片
3.创建中间区域的方法,创建容器,添加账号,密码,标签,复选框控件
4.创建南边区域的方法,创建容器,添加按钮,标签控件。
7. 5.在主函数中实例化QQFrame类的对象,调用初始化界面的方法。
下面就在代码中说说我所遇到的问题,也请大家留意这些问题不要再犯
//初始化界面方法
public void initUI(){
大小显示位置布局方式。。。
this.setTitle("QQFrame");
this.setSize(371,290);
this.setLocationRelativeTo(null);//让窗口显示位置居屏幕中间
this.setResizable(false);//不可随意调整大小
this.setLayout(new BorderLayout());//设置布局方式尤其要注意默认的布局方式就是框架布局
所以这行代码写不写无所谓
this.setDefaultCloseOperation(3);//关闭窗体时退出程序
this.setUndecorated(true);//去掉窗口外面的边框但这时没有了关闭按钮,所以我们还得在界面上添加按钮,点击后可以关闭界面,关闭界面的代码很简单System.exit(0);就是这一行。
//调用添加窗体背景图的方法
addBackGround();
//由于我们采用框架布局,将界面分为东西南北中五块这里是调用添加窗口各个区域的方法
creatNorth();
creatWest();
creatCenter();
creatSouth();
//设置窗口可见
这里要注意的是添加组件时一定要先添加最后再可视,如果先可视再添加,那么很有可能我们看不到添加的组件了。
this.setVisible(true);
// 有时候我们会想用自己的图片来充当界面的北京下面就介绍添加背景的方法
private void addBackGround(){
我们可能会想将自己的照片设置为窗口背景,那这要怎么样做呢我们需要用到ImageIcon类帮助我们实现
//使用imageicon加载图片
但是这样无法直接显示在窗口上
ImageIcon image=new ImageIcon(this.getClass().getResource("haha.JPG"));//得到类得到路径,图片的格式没有要求,
//创建jlabel对象显示图片
JLabel j=new JLabel(image);
//设置标签的显示起始位置和标签限时的宽度高度
j.setBounds(0,0,image.getIconWidth(),image.getIconHeight());
//将j添加到jlayeredpane的Default层上,Default层是最底下的一层,我们在后面给的值是MIN_VALUE最小的值,就是将标签加到了面板的最底层,这里我们必须要加在最底层上,否则显示不出来。
this.getLayeredPane().add(j,new Integer(Integer.MIN_VALUE));
//获取窗体的内容面板对象强制转换成JPanel对象这样我们就取到了LayeredPane面板上一层的ContentPane面板
JPanel contentPane=(JPanel)this.getContentPane();
//将内容面板设置为透明我们才可以看到我们想要的图片
contentPane.setOpaque(false);
下面我们以西边区域为例,讲一下每个区域的添加控件的方法
//创建西边区域
private void creatWest(){
//创建一个容器,我们要添加的所有组件都应是放在这个容器里的
JPanel jp=new JPanel();
//设置容器大小,只有窗口的大小要用setSize方法,其余的一律要用这种,因为西边区域的高度是窗口高度减去北边还有南边的高度之和,所以西边区域的高度是被动确定的,在这里些什么数字都无所谓,我们在这里写0。延伸一下,中间区域就是东西南北四个区域设置完剩下的部分,所以中间区域就不用设置大小了。
jp.setPreferredSize(new Dimension(110,0));
//设置容器布局为流式靠右布局
jp.setLayout(new FlowLayout(FlowLayout.RIGHT));
//加载图片
ImageIcon im=new ImageIcon(this.getClass().getResource("real.jpg"));
//创建标签对象
JLabel j=new JLabel(im);
//将标签加入面板中并设置面板为透明
jp.add(j);
jp.setOpaque(false);
//将面板加到西边
this.add(jp,BorderLayout.WEST);
其余的区域都和西边和中间区域的添加方法一致,qq界面的所有代码我都放在了附件中,如果有兴趣大家可以看看,当然界面做的还是比较粗糙,不过里面所有的功能都已经实现,比如说链接网页,拖动窗口。后期我还要对界面进行美化。
上一篇:下一篇:
File: 12:09:13编写一个具有界面的应用程序,题目自拟。(至少框架里面有两个组件,其中一个要有相应的事件处理)_百度知道
编写一个具有界面的应用程序,题目自拟。(至少框架里面有两个组件,其中一个要有相应的事件处理)
速度会带下 明天考试用啊
提问者采纳
编辑框文字显示到标签上,点击按钮,放一个标签在编辑框中输入文字一个窗口上放一个按钮和一个编辑框就是了再大不了
其他类似问题
为您推荐:
应用程序的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁人气:662809
访问用户量:1986
笔记经验:1294
总积分:1201
级别:普通会员
搜索本笔记
ta的交流分类
ta的全部笔记
浏览(23856)|(0)
&&交流分类:|笔记分类:
作为一个 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斐烧飧鱿窒蟮脑?蛑挥幸桓鼋馐停篔Frame 不是一个容器,它只是一个框架。那么,应该怎么添加组件呢?
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 图形用户界面设计》就告一段落了。由于篇幅有限,这里说的都是初级知识,有此基础,设计复杂一点的图形用户界面也就不是难事了
相关笔记推荐
精品视频课程推荐
创建规范的XML文档,DTD的作用,并且可以根据要求创建私用的DTD,通过JavaScript解析XML DOM
本视频课程是北京Java私塾原创精品书籍《研磨设计模式》一书的配套学习视频,由《研磨设计模式》的第一作者CC录制
课程目标:全面、系统的掌握GoF设计模式的知识,达到可以在实际项目开发中运用的能力
技术要点:如何实现可配置、如何实现缓存以及缓存的管理、如何实现用缓存来控制多实例的创建、如何实现参数化工厂、 如何实现可扩展工厂、如何实现原型管理器、如何实现Java的静态代理和动态代理、如何实现多线程处理队列请求、 如何实现命令的参数化配置、可撤销的操作、宏命令、队列请求和日志请求、如何实现翻页迭代、如何检测环状结构、 如何实现通用的增删改查、如何模拟工作流来处理流程、如何实现简单又通用的XML读取、如何实现模拟AOP的功能......
内容概述:Shiro是目前最热门、最易用、功能超强大的Java权限管理框架,强烈推荐,每个项目都必备的权限管理技术!通过本课程,你将从零开始直到彻底掌握Shiro的相关开发知识,达到可以进行实际项目开发的能力。包括:权限管理基础、Shiro入门、配置、身份认证、授权、Realms、Session管理、和Spring的集成、Web、Cache等众多开发细节技术
技术要点:源码级分析Shiro的授权过程、自定义开发Realm、多个Realms的开发配置、自定义开发AuthenticationStrategy、自定义开发自定义SessionDAO、和Struts2+Spring3的集成(包括修正struts2的bug)、Shiro和SpringMVC+Spring3的集成、包装使用其他的Cache框架、缓存数据同步更新的解决方案等等实际开发中常用的内容
系统、完整的学习Spring Web MVC开发的知识。包括:Spring Web MVC入门;理解DispatcherServlet;注解式控制器开发详解;数据类型转换;数据格式化;数据验证; 拦截器;对Ajax的支持;文件上传下载;表单标签等内容;最后以一个综合的CRUD带翻页的应用示例来综合所学的知识
从零到精通Spring3的开发知识;IoC/DI的思想、IoC/DI的运行流程、IoC/DI的开发指导、AOP的思想、AOP的运行流程、AOP应用的设计、Spring对JDBC和Hibernate的支持、Spring的事务、SSH的集成应用
浏览(23856)|(0)
&&交流分类:|笔记分类:
版权所有 Copyright(C) 私塾在线学习网

我要回帖

更多关于 java图形用户界面组件 的文章

 

随机推荐