2.2 多线程的Swing事件处理
为了提高其效率并降低其复杂性,所有的Swing组件都被设计为非线程安全的。尽管这听起比较恐怖,他只是简单的意味着对Swing组件的所有访问需要由一个单一线程完成--事件分发线程。如果我们并不确定我们位于一个特定的线程中,我们可以使用public static boolean isDispatchThread()方法请求EventQueue类或是通过public static boolean isEventDispatchThread()方法请求SwingUtilities类。后者只是作为前者的代理。
通过EventQueue类的帮助,我们可以创建Runnable对象在事件分发线程上执行来正确的访问组件。如果我们需要在事件分发线程上执行一个任务,但是我们并不需要结果也不会关心任务何时完成时,我们可以使用EventQueue的public static void invokeLater(Runnable runnable)方法。如果是相反的情况,直到任务结束并返回值时我们才能继承我们的工作,我们可以使用EventQueue的public static void invokeAndWait(Runnable runnable)方法。获取值的代码要由我们来完成,而并不是invokeAndWait()方法的返回值。
为了演示创建一个基于Swing程序的正确方法,列表2-1演示了一个用于可选中按钮的源代码。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ButtonSample {
public static void main(String args[]) {
Runnable runner = new Runnable() {
public void run() {
JFrame frame = new JFrame("Button Sample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Select Me");
// Define ActionListener
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
System.out.println("I was selected.");
}
};
// Attach listeners
button.addActionListener(actionListener);
frame.add(button, BorderLayout.SOUTH);
frame.setSize(300, 100);
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
代码所生成的按钮如图2-3所示:
首先,我们来看一下invokeLater()方法。他需要一个Runnable对象作为参数。我们创建一个Runnable对象并传递给invokeLater()方法。在当前事件分发完成之后,Runnable对象就会执行。
Runnable runnable = new Runnable() {
public void run() {
// Do work to be done
}
}
EventQueue.invokeLater(runnable);
如果我们希望我们的Swing GUI创建是线程安全的,那么我们所有的Swing代码就应该遵循这种模式。如果我们需要访问命令行参数,只需要在参数声明前添加final关键字就可以了:public static void main(final String args[])。这看起已经超出了一个简单的示例,但是这可以保证我们程序的线程安全性,确保所有的Swing组件的访问都是通过事件分发线程完成的。(然而调用repaint(),revalidate()以及invalidate()并不需要通过事件分发线程完成。)
列表2-1中另外一个需要解释的代码行就是
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
在默认情况下,如果我们图2-3中所示的容器中标题栏上的小X,程序并不会关闭;相反,框架会不可见。将默认的关闭操作设置为JFrame.EXIT_ON_CLOSE可以使得程序在会用户点击X时关闭。在第8章中我们探讨JFrame类时我们会了解到更多的信息。
2.2.1 使用SwingUtilities用于鼠标按钮标识
Swing组件集合包含了一个名为SwingUtilities的工具类,这个类提供了一个通用帮助方法集合。在本书中,当这个类的特定方法集合起来有用时,我们会间断的遇到这个类。对于列表2-1中的按钮示例,我们所感兴趣的方法是与确定选中哪个鼠标按钮相关的方法。
MouseInputListener接口由七个方法组成:mouseClick(MouseEvent), mouseEntered(MouseEvent), mouseExited(MouseEvent), mousePressed(MouseEvent)以及MouseListener中的mouseRelease(MouseEvent),MouseMotionListener中的mouseDragged(MouseEvent)与mouseMove(MouseEvent)。如果我们需要确定当事件发生时哪一个鼠标按钮被选中(或是释放),我们可以检测MouseEvent的modifiers属性,并将其与InputEvent类中的各种掩码设置常量进行对比。
例如,要检测鼠标按下事件中是否是鼠标中键被按下,我们可以在我们的鼠标监听器mousePressed()方法中使用下面的代码:
public void mousePressed(MouseEvent mouseEvent) {
int modifiers = mouseEvent.getModifiers();
if ((modifiers & InputEvent.BUTTON2_MASK) == InputEvent.BUTTON2_MASK) {
System.out.println("Middle button pressed.");
}
}
尽管这种方法可以工作得很好,然而SwingUtilities类提供三个方法可以使得这个过程更为简单:
SwingUtilities.isLeftMouseButton(MouseEvent mouseEvent)
SwingUtilities.isMiddleMouseButton(MouseEvent mouseEvent)
SwingUtilities.isRightMouseButton(MouseEvent mouseEvent)
现在我们不需要手动获取标识并与掩码进行对比,我们可以请求SwingUtilities来完这些工作,如下所示:
if (SwingUtilities.isMiddleMouseButton(mouseEvent)) {
System.out.println("Middle button released.");
}
这可以使得我们的代码变得更容易阅读与维护。
列表2-2包含了一个更新的ButtonSample,在其中添加了另一个监听器来检测哪一个鼠标按钮被按下。
/**
*
*/
package swingstudy.ch02;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
/**
* @author lenovo
*
*/
public class ButtonSample2 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Runnable runner = new Runnable() {
public void run() {
JFrame frame = new JFrame("Button Sample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Select Me");
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.out.println("I was selected");
}
};
MouseListener mouseListener = new MouseAdapter() {
public void mousePressed(MouseEvent event) {
int modifiers = event.getModifiers();
if((modifiers & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) {
System.out.println("Left button is pressed");
}
if((modifiers & InputEvent.BUTTON2_MASK) == InputEvent.BUTTON2_MASK) {
System.out.println("Middle button is pressed");
}
if((modifiers & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK) {
System.out.println("Right button is pressed");
}
}
public void mouseReleased(MouseEvent event) {
if(SwingUtilities.isLeftMouseButton(event)) {
System.out.println("Left button is released");
}
if(SwingUtilities.isMiddleMouseButton(event)) {
System.out.println("Middle button is released");
}
if(SwingUtilities.isRightMouseButton(event)) {
System.out.println("Right button is released");
}
}
};
button.addActionListener(actionListener);
button.addMouseListener(mouseListener);
frame.add(button, BorderLayout.SOUTH);
frame.setSize(300,100);
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
分享到:
相关推荐
本篇文章将深入探讨Java Swing组件集合,帮助初学者更好地理解和使用这些组件。 首先,Swing 提供了丰富的组件集,包括按钮(JButton)、文本框(JTextField)、标签(JLabel)、复选框(JCheckBox)、单选按钮...
Swing是Java Foundation Classes (JFC)的一部分,提供了丰富的组件集合,用于创建美观且功能强大的图形用户界面。其中,一些常见的Swing控件包括: 1. **JFrame**:作为窗口的基础,它是所有Swing应用的起点。在...
它提供了丰富的组件集合,使得开发者可以创建复杂的、交互式的用户界面。在Java Swing组件全演示中,我们将深入探讨Swing的核心概念、组件和设计原则。 首先,Swing是基于AWT(Abstract Window Toolkit)的,但提供...
1. **元件多样性**:Swing提供了比AWT更丰富的组件集合,包括树状视图(Treeviews)、图片按钮等,让开发者能创建更为复杂的用户界面。 2. **跨平台一致性**:Swing组件是轻量级的,它们不依赖于底层操作系统,从而...
Java Swing 是Java GUI(图形用户界面...总的来说,通过研究这些源代码,开发者不仅可以学习到Swing组件的基本使用,还能了解到组件的定制、交互处理和界面设计的技巧,这对于提升Java桌面应用开发技能是非常有帮助的。
综上所述,"Swing组件大全"不仅涵盖了Swing库中的所有核心组件,还涵盖了数据库操作、Excel文件处理和自定义布局管理,是学习和开发Swing应用的宝贵资源。通过深入理解和实践这些知识点,开发者可以构建出功能强大且...
通过深入学习和实践这个"java swing组件例子",你将能够熟练掌握如何使用Java Swing创建功能丰富的GUI应用程序,理解组件间的交互、事件处理机制以及布局管理的重要性和用法。同时,还能了解到如何通过自定义外观和...
它可能涵盖了Swing组件的定制,如创建自定义外观和行为,以及如何利用模型-视图-控制器(MVC)模式来构建可维护的应用程序。源代码实例可能涉及到Swing的高级组件,如JTable、JTree和JList,以及如何与数据库进行...
总的来说,JIDE是Java Swing开发者的强大武器,它通过丰富的组件集合和高级特性,降低了开发复杂桌面应用的难度,提升了开发效率。对于那些需要构建专业级桌面应用的Java开发者而言,JIDE是一个不可多得的资源。通过...
Swing组件的一个重要特点是它们支持模型-视图-控制器(MVC)设计模式,使得代码结构更清晰,维护更容易。 1. **JFrame**: JFrame是顶级容器,常用于创建窗口应用程序。你可以添加各种组件到JFrame上,如菜单栏、...
Java Swing 是Java GUI(图形用户界面)开发的重要库,它提供了丰富的组件集合,用于构建桌面应用程序。本资源“Java Swing 组件全演示源代码”包含了Java Swing中的各种组件的完整示例代码,可以帮助开发者深入理解...
通过分析这些实例,开发者可以深入理解Swing组件的使用、事件处理机制、自定义绘制方法以及如何将它们结合到实际项目中。这些源码实例为初学者提供了宝贵的实践资料,同时也为经验丰富的开发者提供了灵感和参考。
它是Java Foundation Classes (JFC) 的一部分,提供了一套丰富的组件集合,用于构建功能完善的用户界面。Swing在早期是为了弥补Java AWT(Abstract Window Toolkit)的不足而设计的,提供了更丰富的功能、更好的可...
在学习和使用Swing组件时,了解每个组件的属性、方法和事件处理机制非常重要。通过实例代码和案例分析,你可以更好地掌握如何创建功能丰富的桌面应用程序。提供的"Swing常用组件"资源很可能是包含各种示例代码的集合...
总的来说,这个"java使用swing组件编写的简易计算器"项目涵盖了Java GUI编程的基础,包括Swing组件的使用、事件处理、基本计算逻辑实现以及IDE的使用。通过这个项目,开发者可以深入理解Java Swing的原理和实践,...
它们提供了一套丰富的组件集合,使得开发者能够创建功能强大的桌面应用程序。Swing 是 JFC 的一部分,它扩展了 Java AWT(Abstract Window Toolkit)库,提供了更多的功能和更好的性能。 一、JFC 概述: Java ...
- **Java Desktop.org**:这个网站提供了大量的Swing组件集合和示例代码,对于开发者来说是一个不错的资源库。 - **ChinaJavaWorld论坛**:这个中文论坛也有关于Swing的讨论和技术交流,适合中文读者。 ### 性能...
在本项目中,“基于Swing组件编写华容道...它不仅展示了Swing组件的使用,还涵盖了图形用户界面设计、事件处理、数据结构以及算法应用等多个IT领域的知识。这样的项目对于学习和提升Java GUI编程能力是非常有价值的。
首先,Swing是Java的标准GUI库,它提供了丰富的组件集合,如按钮、文本框、表格、菜单等,用于构建美观且功能强大的桌面应用。在销售管理系统中,Swing组件可以用来创建用户友好的界面,让用户能够方便地输入、查看...
标题和描述中提到的知识点是关于Java...总结来说,Swing是一个全面的用户界面工具包,它通过Java语言的纯粹性,提供了一套跨平台、模块化的用户界面组件集合。开发者利用Swing可以创建功能强大、界面美观的应用程序。