- 浏览: 732435 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
lingsuch:
Android网络连接判断与处理 -
月光照着我:
写的不错,作为笔记了
Android中LayoutInflater的使用 -
智博王锋:
好文章是要顶的!
Android中LayoutInflater的使用 -
云南白药:
...
Android中LayoutInflater的使用 -
万新one:
理解了许多。解释的不错。3Q.
Android中LayoutInflater的使用
AWT 和 SWING AWT 和 SWING 是 Java 设计 GUI 用户界面的基础。与 AWT 的重量级组件不同,Swing 中大部分是轻量级组件。正是这个原因,Swing 几乎无所不能,不但有各式各样先进的组件,而且更为美观易用。所以一开始使用 AWT 的程序员很快就转向使用 Swing 了。 那为什么 AWT 组件没有消亡呢?因为 Swing 是架构在 AWT 之上的,没有 AWT 就没有 Swing。所以程序员可以根据自己的习惯选择使用 AWT 或者是 Swing。但是,最好不要二者混用——除开显示风格不同不说,还很可能造成层次 (Z-Order) 错乱,比如下例: /** * TestPanels.java * @author Fancy */ import javax.swing.*; import java.awt.*; public class TestPanels extends JFrame { 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(); } public static void main(String[] args) { TestPanels tp = new TestPanels(); tp.show(); } } 运行这个程序,并用鼠标拖动那个名为“cover”的子窗口,我们会发现一个非常有趣的现象,如图: 显然 cover 子窗口是在 controls 子窗口之上的,但是它只罩盖住了 Swing Button,没有罩盖住 AWT Button。再看一会儿,你是不是有这样一种感觉:Swing Button 是“画”上去的,而 AWT Button 则是“贴”上去的。这就是二者混用造成层次错乱的一个例子。 Swing 组件有美观、易用、组件量大等特点,也有缺点——使用 Swing 组件的程序通常会比使用 AWT 组件的程序运行更慢。但是大家都还是更喜欢用 Swing 组件,原因何在?因为随着计算机硬件的升级,一点点速度已经不是问题。相反的,用户更需要美观的用户界面,开发人员则更需要易用的开发组件。 ——好,我这就来教你使用 Swing 组件开发图形用户界面的 Java 应用程序。 二. 框架、监听器和事件 框架 (Frame) 是 Java 图形用户界面的基础,它就是我们通常所说的窗口,是 Windows/XWindow 应用程序的典型特征。说到 Windows/XWindow,大家很容易联想到“事件 (Event) 驱动”。Java 的图形用户界面正是事件驱动的,并且由各种各样的监听器 (Listener) 负责捕捉各种事件。 如果我们需要对某一个组件的某种事件进行捕捉和处理时,就需要为其添加监听器。比如,我们要在一个窗口 (JFrame) 激活时改变它的标题,我们就需要为这个窗口 (JFrame 对象) 添加一个可以监听到“激活窗口”这一事件的监听器——WindowListener。 怎么添加监听器呢?这通常由组件类提供的一个 addXXXXXListener 的方法来完成。比如 JFrame 就提供有 addWindowListener 方法添加窗口监听器 (WindowListener)。 一个监听器常常不只监听一个事件,而是可以监听相关的多个事件。比如 WindowListener 除了监听窗口激活事件 (windowActivate) 之外,还可以监听窗口关闭事件 (windowClosing) 等。那么这些事件怎么区分呢?就靠重载监听器类 (Class) 的多个方法 (Method) 了,监听器监听到某个事件后,会自动调用相关的方法。我们只要重载这个方法,就可以处理相应的事件了。 不妨先看一个例子: /** * TestFrame.java * @author Fancy */ 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.show(); 也许你会说:第一句的意思我清楚,第三句的意思我也明白,为什么一定要第二句呢?其实想想也就明白了,叫你画一个没法有大小的矩形你能画出来吗?不能。同样,没有大小的窗口,怎么显示?所以我们需要用 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 应用程序。如果不作这样的处理会怎样呢?试验之后你会发现,窗口虽然关闭了,但程序并没有结束,但此时,除了使用 ^C 强行结束之外,恐怕也没有其它办法了。所以,这一点非常重要:如果你想在关闭窗口的时候退出应用程序,需要你自己写代码处理 windowClosing 事件。……也不尽然,其实还有另外一个更简单的办法,让 JFrame 自己处理这件事——你只需要如下调用 JFrame 的 setDefaultCloseOperation 即可: frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 我们可以在 JFrame 对象中添加 AWT 或者 Swing 组件。但是,虽然它有 add 方法,却不能直接用于添加组件,否则会抛出异常——不信就试试。造成这个现象的原因只有一个解释:JFrame 不是一个容器,它只是一个框架。那么,应该怎么添加组件呢? JFrame 有一个 Content Pane,窗口是显示的所有组件都是添加在这个 Content Pane 中。JFrame 提供了两个方法:getContentPane 和 setContentPane 就是用于获取和设置其 Content Pane 的。通常我们不需要重新设置 JFrame 的 Content Pane,只需要直接获取这个 Content Pane 来添加组件等。如:(new JFrame()).getContentPane().add(new Button("test button")); 三. 按钮、切换按钮、复选按钮和单选按钮 按钮,就是按钮,不会连按钮都不知道吧? 切换按钮,有两种状态的按钮,即按下状态和弹起状态,若称为选择状态或未选择状态。 复选按钮,又叫复选框,用一个小方框中是否打勾来表示两种状态。 单选按钮,又叫收音机按钮,以小圆框打点表示被选中。常成组出现,一组单选按钮中只有一个能被选中。 发现什么了吗?——对了,这一部分是在讲各种各样的按钮,而且后三种按钮都有两种状态。先看看这些按钮都长成什么样: 上图中,从上到下,依次就是按钮、切换按钮、复选按钮和单选按钮。图示的窗口,就是下面这个例子的运行结果: /** * TestButtons.java * @author Fancy */ import javax.swing.*; import java.awt.event.*; public class TestButtons { 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.show(); } public static void main(String[] args) { TestButtons tb = new TestButtons(); tb.show(); } } 除一般按钮外,其余三种按钮都有两种状态,即选择 (按下) 状态和未选择 (弹起) 状态。那么我们又该如何判断呢?切换按钮 (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 ae)。按钮、切换按钮和单选按钮被单击时都会触发动作事件,引起动作监听器调用 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 对象添加了同一个动作监听器实例: /** * Test.java * @author Fancy */ import javax.swing.*; import java.awt.event.*; public class Test { JButton b; JRadioButton rb; 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 的示例:
发表评论
-
Swing中引入Android的NinePatch技术,让Swing拥有Android的外观定制能力
2012-09-21 09:22 1627【摘要】 本文诣在 ... -
JavaSwing实现支持合并拆分的JTable
2010-12-16 15:39 1977GridBagModel:抽象模型接口。该接口用于描述表格中单 ... -
JTable小例子,表格中使用JComboBox下拉按钮
2010-12-16 15:21 5426import java.awt.BorderLayout; ... -
配合滚动面板实现JTable上下翻页的效果
2010-12-16 14:26 3424import java.awt.BorderLayout; ... -
JScrollBar简单演示例子
2010-12-06 19:28 6623import java.awt.*; import java ... -
点击jtable的表头,数据会根据根据表头来排序
2010-12-06 11:47 5137import javax.swing.JFrame; imp ... -
重写JSplitPane的BasicSplitPaneUI
2010-09-18 13:39 1578import java.awt.Color; import ... -
Swing窗口初始最大化的方法
2010-08-20 11:09 79061.设置窗口最大(伪最大化) JFrame frame =n ... -
Tree目录实现拖拽功能演示实例(DragAndDrop)
2010-08-10 16:49 1802import java.awt.BorderLayout; ... -
设置JTextPane指定内容的颜色
2010-05-21 14:29 1367package Assis; import java.a ... -
ScaleImageDemo图像缩小与放大演示
2010-05-12 14:59 2123package Assis; import java.a ... -
TreesDemo
2010-05-04 11:19 1093import java.awt.*; import java ... -
TableDemo
2010-05-04 11:17 1206import javax.swing.JTable; imp ... -
分割面板演示JSplitPaneDemo
2010-05-04 11:12 1398//Java Swing 带分隔条的面板代码 impor ... -
StylesExample8
2010-04-08 12:55 1206import javax.swing.*; import j ... -
StylesExample7
2010-04-08 12:54 1004import javax.swing.*; import j ... -
StylesExample6
2010-04-08 12:52 1071import javax.swing.*; import j ... -
StylesExample5
2010-04-08 12:51 999import javax.swing.*; import j ... -
StylesExample4
2010-04-08 12:50 1116import javax.swing.*; import j ... -
StylesExample3
2010-04-08 12:50 1011import javax.swing.*; import j ...
相关推荐
1. **Claude Duguay**(JavaZone):这本书中的例子都非常实用且非泛泛之谈,对于专业开发人员来说非常有价值。 2. **Peter Pilgrim**(CVu Journal):本书将复杂主题分解成易于管理的部分,适合那些已经掌握了基础...
"浅谈Java图形界面事件处理的方法.pdf" Java 语言在图形界面设计中,事件处理是非常重要的一部分。事件处理是指用户与图形用户界面(GUI)之间的交互操作,即当用户触发某一事件时,系统做出的响应,对事件进行...
不必深入研究Swing或Applet等图形界面组件,因为这些在JSP中并不常用。 - **建议**:通过实际项目练习,加深对Java的理解。 ##### 4. 学习JavaScript - **时间**:1~2周 - **目标**:掌握如何使用JavaScript进行...
### 浅谈Java语言评价胜出的8大技术优势 #### 1. 强大的API支持 Java提供了非常丰富的API支持,包括网络编程中的Socket API、数据库操作中的SQL API、图形用户界面的Swing和AWT API等。这些API不仅功能强大而且...
浅谈 Java 的发展及特点[J]. 硅谷, 2010(6):50-50. 2. Burns B. Darkstar: the java game server[J]. 2007. 3. 吴越胜、李新磊.Eclipse 3.0 程序开发技术详解[M]:清华大学出版社,2010.1~3 4. 岷江. Java 的运行...
今天,我们将深入浅谈该问题,并提供两种解决方法:通过使用外部资源文件的方式和通过使用内部资源文件的方式。 问题描述 当我们将 Java 项目打包成 Jar 文件后,发现图片无法加载。这是因为 Jar 文件中的路径问题...
Java的标准库并未内置事件驱动的功能,但在GUI组件如Swing中,有一些基础的事件处理支持。然而,这些并不适用于非GUI应用,因此我们需要自定义一套通用的事件驱动框架。 观察者模式是实现事件驱动的一种常见设计...
"linear"是一种线性过渡,动画速度在整个过程中保持恒定,而"swing"则是非线性的,它模拟了传统的物理摆动,速度在开始和结束时较慢,中间较快,这是jQuery默认的效果。 然而,如果你想要更多的缓动效果,比如...
Java Swing中的布局管理器(Layout Manager)负责自动调整和排列容器中的组件。不同类型的布局管理器有其特定的布局规则。当你尝试使用`setBounds()`方法时,必须考虑到当前使用的布局管理器类型。 - **绝对布局...
在Java的Swing图形用户界面(GUI)开发中,布局管理是至关重要的,它负责自动安排组件在容器内的位置和大小。然而,有时开发者可能希望对组件的位置有精确的控制,这时就可以使用“绝对布局”(Absolute Layout)。...
它是由javax.swing.JTextField类提供的,可以用来创建一个允许用户输入单行文本的控件。文本框的大小通常由其列数来决定,用户可以通过构造函数来设置列数,例如: 1. JTextField() 创建一个默认字符长度为1的...
1. public int getRowCount():获取表格中的行数。 2. public int getColumnCount():获取表格中的列数。 3. public Object getValueAt(int rowIndex, int columnIndex):获取指定行和列的单元格值。 通过继承 ...
1. `public JLabel()`:这是最基础的构造方法,创建了一个没有图标和文本的标签。当你只是想在界面上添加一个空白区域时,可以使用这个方法。 2. `public JLabel(Icon image)`:此构造方法用于创建一个带有指定图标...
6.18.1 不可变性给元组带来了什么影响 6.18.2 元组也不是那么“不可变” 6.18.3 默认集合类型 6.18.4 单元素元组 6.18.5 字典的关键字 6.19 相关模块 6.20 *拷贝Python对象、浅...
纸上得来终觉浅,所以:别问那么多,别想那么多,动手写吧。 JAVA自学之路 四:要事为先 对待人生的任何事情都要:抓大放小,要事为先 对于一个以前从来没有接触过java的人,java无疑是庞大的,似乎每个...