【Java学习笔记】java图形界面编程

在前面的章节中,我们开发运行的应用程序都没有图形界面,但是很多应用软件,如Windows下的Office办公软件、扑克牌接龙游戏软件、企业进销存ERP系统等,都有很漂亮的图形界面。素以需要我们开发具有图形界面的软件。
Java图形界面编程内容主要包括AWT(Abstract Window Kit)和Swing两个部分。AWT是用来创建图形界面的基本工具,Swing是JFC(Java Foundation Classes)的一部分,是对AWT的有益补充。

1.AWT简介

AWT是抽象窗口工具类(Abstrat Window ToolKit)的缩写,AWT库中有60多个类和接口,几乎涵盖了创建Java图形界面程序的所有工具。利用AWT类库,可以在Applet的显示区域创建标签、按钮、复选框第二部分,还可以针对用户行为进行响应。
AWT是jdk的一部分,AWT为图形界面程序提供了所需的丰富的组件,同时还提供了对事件类、监听器类、图形处理工具,2D图形的支持
Java AWT类提供了四个主要的类,包括组件类(Component)、容器类(Container)、图形类(Graphics)和布局管理器。
AWT虽然提供了很多对图形界面的支持,但是缺少剪贴板支持、打印支持、没有弹出式菜单和滚动窗口等问题,所以产生了新的组件Swing来解决这些问题。

2.SWING基础

Swing元素比AWT元素存在更好的图形处理性能。Swing具有java的跨平台性,可以在任何平台上使用Swing图形界面组件。Swing的大部分组件是轻量级组件
Swing组件在不同平台上具有一致性的表现。Swing组件比AWT组件的实用性更强。Swing采用了MVC(Model-View-Controller,模型——视图——控制器)模式。

2.1 Swing的类层次结构

在javax.swing包中包含两种类型的组件:顶层容器(JFrame、JApplet、JDialog和JWindow)和轻量级组件。Swing轻量级组件是从AWT的Container类直接或间接派生过来的、
Swing包是JFC(Java Foundation Classes)的一部分,,javax.swing是其中最大的包,并且绝大部分Swing组件都包含在swing包中。
例:javax.swing.event包中定义了事件和事件处理类,这与java.awt.event包类似,主要包括事件类和监听器接口、事件适配等。

2.2 Swing的特点

  • MVC模式:MVC模式包括模型、视图和控制器等部分。Model(模型)用于保存所用到的数据模型,视图(View)用于显示数据内容,控制器(Controller)用于处理用户和模块交互事件。分层后,各层各司其职,协同工作,当模型的数据改变时,会通知与之相关的视图,视图通过控制器指定相应机制。为了更方便,Swing组件将视图和控制器 合二为一。

  • 组件的多样化:Swing组件的类名都是以字母J开头的。
    在这里插入图片描述

  • 可存取性支持 : 所有的Swing组件都实现了Accessible接口,这样一些辅助功能(如:屏幕阅读器)也可以得到支持

  • 设置边框:Swing组件不仅可以设置一个或多个边框,也可以让用户组合边框或自定义属于自己的边框

  • 支持键盘操作:JComponent类的RegisterKeyboardAction()方法可以实现用键盘操作替代用户鼠标操作。

  • 使用图标:Swing组件中的许多组件可以通过图标修饰自己。

2.3 swing程序结构简介

Java Swing的程序设计流程:
(1)使用import关键字导入swing包
(2)设置GUI的“外观界面风格”
(3)创建顶层容器
(4)创建按钮和标签等各种所需的组件
(5)将组件添加到顶层容器
(6)在组件周围添加边界
(7)进行事件处理
(8)结束
在这里插入图片描述

package swing;import javax.swing.*;		//导入swing包
import java.awt.*;			//导入awt包
import java.awt.event.*;	//导入awt事件处理包public class FirseSwingApp {public static void main(String[] args) {try {				//try语句块,监视该段程序UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());} catch (Exception e) {		//捕获异常e.printStackTrace();	//输出异常信息}JFrame frame = new JFrame("我的第一个Swing程序");Container c = frame.getContentPane();JPanel pane = new JPanel();c.add(pane);pane.setLayout(new FlowLayout());JLabel label = new JLabel();JButton button = new JButton("Press me");pane.add(label);pane.add(button);// 为增加按钮添加监听button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {label.setText("监听事件成功");}});frame.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});frame.setSize(400,280);frame.setVisible(true);}}

3.事件类

每一个事件类都与一个事件类接口相对应,由事件引起的动作都存放在接口需要实现的方法中。Java中,常用的事件类接口包括动作事件类、调整事件类、焦点事件类、项目事件类、按钮事件类、鼠标事件类、窗口事件类。

3.1 事件类的分类

所有与AWT相关的事件类都是java.awt.AWTEvent的派生类,AWTEvent也是java.util.EventObject类的派生类。
AWT事件包括低级事件和高级事件,低级事件时指源于组件或容器的事件,当组件或容器发生事件时,将触发事件。
高级事件是语义事件。这类事件与特定的具体事件不一定相对应,但是会 产生特定的事件对象。

3.2 动作事件类

动作事件类是指发生组件定义的语义事件。使用动作事件时需要给组件添加一个事件监听器ActionListener。ActionListener只有唯一的actionPerformed()方法。

   // 给按钮 增加 监听button.addActionListener(new ActionListener() {// 当按钮被点击时,就会触发 ActionEvent事件public void actionPerformed(ActionEvent e) {//按钮被操作}});

3.3 调整事件类

调整事件是滑动滚动条时发生的事件。为了监听调整事件,需要给ScrollBar添加一个调整事件监听器AdjustListener

scrollbar.addAdjustmentListener(new AdjustListener()){public void adjustmentValueChanged(AdjustmentEvent e){//调整滚动条}
}

3.4 焦点事件类

焦点事件类(FocusEvent)是指界面的组件失去焦点(焦点从一个对象转移到另外一个对象)时就会发生焦点事件。得到焦点事件的组件处于激活状态。

void FocusGained(FocusEvent e){// 当获得焦点时发生
}
void FocusLost(FocusEvent e){// 当失去焦点时发生
}

3.5 项目事件类

项目事件类(ItemEvent)是指某个项目(Item)时被选定、取消的语义事件,使用项目事件必须给组件添加一个实现ItemListener接口的事件处理器。

void itemStateChange(ItemEvent e)

3.6 键盘事件类

键盘事件类(KeyEvent)是指容器内任意组件获得焦点时,组件发生键击时,组件对象将产生该事件。

 f.addKeyListener(new KeyListener() {// 键被弹起public void keyReleased(KeyEvent e) {}//键被按下public void keyPressed(KeyEvent e) {// TODO Auto-generated method stub}// 一个按下弹起的组合动作public void keyTyped(KeyEvent e) {}});

3.7 鼠标事件类

鼠标事件类(MouseEvent)是指组件中发生鼠标动作时间,当鼠标移动到某个区域或单击某个组件时会触发鼠标事件。使用鼠标事件需要给组件添加MouseListener接口的事件处理器

 l.addMouseListener(new MouseListener() {// 释放鼠标public void mouseReleased(MouseEvent e) {// TODO Auto-generated method stub}// 按下鼠标public void mousePressed(MouseEvent e) {// TODO Auto-generated method stub}// 鼠标退出public void mouseExited(MouseEvent e) {// TODO Auto-generated method stub}// 鼠标进入public void mouseEntered(MouseEvent e) {}// 按下释放组合动作为点击鼠标public void mouseClicked(MouseEvent e) {// TODO Auto-generated method stub}}); 

3.8 窗口事件类

窗口事件类(WindowEvent)是指窗口状态改变的事件。使用窗口事件必须为组件添加一个实现WindowListener接口的事件处理器。

windowOpenedvoid windowOpened(WindowEvent e)
窗口首次变为可见时调用。windowClosingvoid windowClosing(WindowEvent e)
用户试图从窗口的系统菜单中关闭窗口时调用。windowClosedvoid windowClosed(WindowEvent e)
因对窗口调用 dispose 而将其关闭时调用。windowIconifiedvoid windowIconified(WindowEvent e)
窗口从正常状态变为最小化状态时调用。对于很多平台而言,已最小化的窗口将显示为窗口 iconImage 属性中所指定的图标。windowDeiconifiedvoid windowDeiconified(WindowEvent e)
窗口从最小化状态变为正常状态时调用。windowActivatedvoid windowActivated(WindowEvent e)
将 Window 设置为活动 Window 时调用。只有框架或对话框可以成为活动 Window。本机的窗口系统可能使用特殊装饰表示活动 Window 或其子窗口,如高亮显示标题栏。活动 Window 要么是聚焦 Window,要么是作为聚焦 Window 所有者的第一个 Frame 或 Dialog。
windowDeactivatedvoid windowDeactivated(WindowEvent e)
当 Window 不再是活动 Window 时调用。只有框架或对话框可以成为活动 Window。本机的窗口操作系统可能使用特殊装饰表示活动 Window 或其子窗口,如高亮显示标题栏。活动 Window 要么是聚焦 Window,要么是作为聚焦 Window 所有者的第一个 Frame 或 Dialog。

4 事件监听器

事件监听器的主要任务是对事件进行监听并进行相应处理。事件处理是图形界面程序设计必须做的工作。
当用户使用鼠标、键盘等外部设备输入发生事件时,可以使用事件监听处理器处理这些事件,从而实现相应的事件响应。事件监听器是为了处理特定时间而编写的方法。

4.1 事件监听器接口

不同的事件类对应不同的的事件监听器,他是事件监听器类的接口。

AWT的组件不仅可以注册监听器,还可以注销监听器

public void add<ListenerType> (<ListenerType>  listener ) //注册监听器
public void remove<ListenerType>(<ListenerType>  listener)//注销监听器

在这里插入图片描述

4.2 事件监听器特点

事件监听器接口是一个特殊的接口,与普通的接口相比,不同之处在于:
(1)一个监听器接口的类可以实现一个或或多个接口,并且接口之间用逗号隔开

implements MouseMotionListener,MouseLinstener,WindowListener;

(2) 同一个组件可以监听一个事件源的多个事件
即在对象ob上接收多个事件,并被同一个监听器接收和处理。

ob.addMouseMotionListener(this) ; 		//添加鼠标动作监听器
ob.addMouseListener(this);		//添加鼠标监听器
ob.addWindowListener(this);		//添加窗口监听器

(3)事件处理这和事件源可以处在同一个类中。
上述程序事件中,事件源是窗口对象ob,事件处理这是类TreeListener,其中ob是类TreeLIstener的成员变量
(4)通过事件对象可以获得一些信息。例如,可以获得组件中鼠标的位置坐标。

public void mouseMoved(MouseEvent e){Strng str = "鼠标移动";ob1.setText(s);ob2.setText("鼠标坐标为:" + e.getX() + e.getY());
}

Java语言只支持单继承,但可以通过接口实现多继承的功能。

在AWT中经常实现多个监听器接口,每一个接口中已定义的方法必须实现。如果针对某事件不做任何处理,就不需要实现这个方法,方法体为空。

5.轻量级容器

Jframe的内部轻量级容器结构图:
在这里插入图片描述
在这里插入图片描述
用户添加的组件都在contentPane上,背景图片只能添加到layeredPane.
GlassPane是完全透明的,默认值为不可见。
覆盖content的目的是为了接收鼠标事件和组件绘图功能提供方便。

5.1 根面板(JRootPanel)

根面板(JRootPanel)由contentPane、menuBar、glassPlane构成

5.2 面板(JPanel)

面板(JPanel)是轻量级容器,用法与Panel基本相同,用于收纳其他的组件。

5.3 分层面板(JLayeredPane)

Swing有JLayeredPane、JDesktopPane两种类型的分层面板,JDesktopPane是JLayeredPane的派生类,用于创建多文档和虚拟桌面程序的容器

5.4 滚动窗口(JScrollPane)

滚动窗口(JScrollPane)是管理窗口(JViewport)、可选水平或垂直滚动的轻量级容器。滚动窗口有JScrollBar、JViewPort之间的链接组成

5.5 分隔板(JSplitPane)

分隔板(JSplitPane)用于提供可以拆分的窗口,但只能分割成两个容器。支持水平和竖直两种拆分类型,可带滚动条

5.6 选项板(JTabbedPane)

选项板(JTabbedPane)提供允许用户通过单击具有标题和图标的选项卡,在组件之间进行来回切换的组件,通过addTab()和insertTab()方式添加选项卡、组件到TabbedPane对象中。

5.7 工具栏(JToolBar)

工具栏(JToolBar)是显示常用工具组件的容器。可以将工具栏单独拖出作为一个独立的工具条。

6. Swing组件

Swing组件与AWT组件类似,但又为每个组件添加了新的方法。

6.1 按钮(Button)

在Swing中,所有类型的按钮都是javax.swing.AbstractButton类的子类。

6.2 复选框(JChekBox)

该类是javax.swing.JToggleButton类的子类。

6.3 单选框(JRadioButton)

单选框(JRadioButton)与AWT中的复选框功能类似,
JRadioButton 和 ButtonGroup配合使用时可以创建一组数组,但一次只能选择其中的一个按钮,通过add()方法将JRadioButton对象添加到该组中。

6.4 组合框(JComboBox)

组合框是将按钮、可编辑字段及下拉菜单组合在一起的操作。用户可以从下拉菜单中选则不同的值。

6.5 进度条(JProgressBar)

进度条是以图形化的方式来描述任务进度的组件。在任务完成的过程中,进度条显示该任务完成的百分比。

6.6 表格(JTable)

在界面上将数据以表格的形式展示,可以采用表格控件(JTable)来实现。
表格控件是Swing新增加的组件。主要是为了将数据以表格的形式显示。

6.7 树(JTree)

很多时候需要使用树状控件展示数据,如Windows的文件浏览器就像现行的树状控件。树(JTree)中特定的节点可以由TreePath标识或由其显示行标识。可查看的父类节点都是可以展开的,但是他们可以显示也可以不显示。显示节点必须是可以查看的,并且位于显示区域。

7 拓展训练

7.1 设置闪烁的标题栏

【Timer控件】
在银行,股票,比赛系统中经常出现同时处理并显示业务数据的情况,每个窗口和窗口中的数据分类和重要性并不相通。当有的信息重要性很高,必须以醒目的方式提醒读者注意的时候,可以采用闪烁的标题栏来动态突出某窗口信息的重要性。
【例】在TimerFlashBar类的主方法中创建Timer控件,并在空间中实现窗口闪烁的效果。该效果一直循环,每隔1秒闪烁一次

package swing;import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;import javax.swing.Timer;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;public class TimerFlashBar  extends JFrame{
//
//	private static final long serialVersionUID private JPanel contentPane;public static void main(String[] args) {EventQueue.invokeLater(new Runnable() { //把事件添加到AWT的事件处理线程中public void run() {try {TimerFlashBar frame = new TimerFlashBar();frame.setVisible(true);}catch(Exception e) {e.printStackTrace();}}});}public TimerFlashBar() {addWindowListener(new WindowAdapter() {@Overridepublic void windowOpened(WindowEvent e) {do_this_windowOpened(e);} });setTitle("设置闪烁的标题栏");setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setBounds(100,100,273,130);contentPane = new JPanel();contentPane.setBorder(new EmptyBorder(5,5,5,5));contentPane.setLayout(new BorderLayout(0,0));setContentPane(contentPane);JLabel label = new JLabel("系统内存紧缺,请立即保存数据");label.setHorizontalAlignment(SwingConstants.CENTER);}protected void do_this_windowOpened(WindowEvent e) {Timer timer = new Timer(500,new ActionListener() {String title = getTitle();public void actionPerformed(ActionEvent e) {if(getTitle().isEmpty()) {setTitle(title);}else {setTitle("");}}});timer.start();}
}

在这里插入图片描述

7.2 建立简单的时钟布局

【布局管理器】
Java提供了流布局、边框布局、网格布局等多种布局方式,其实我们也可以自定义一个布局管理器

package swing;import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;public class UseCloakLayout implements LayoutManager {public void addLayoutComponent(String name,Component comp) {}public void layoutContainer(Container parent) {double centerX = parent.getBounds().getCenterX();double centerY = parent.getBounds().getCenterY();Insets insets = parent.getInsets();double horizon = centerX - insets.left;double vertical = centerY - insets.top;double radius = horizon > vertical ? vertical:horizon;//设置时钟半径int count = parent.getComponentCount();//获得控件个数for(int i = 0;i<count;i++) {Component component = parent.getComponent(i);if(component.isVisible()) {Dimension size = component.getPreferredSize();double angle = 2 * Math.PI*i/count;//获得角度大小double x = centerX + radius*Math.sin(angle);double y = centerY - radius*Math.cos(angle);//重新设置控件的位置和大小component.setBounds((int)x-size.width/2,(int)y-size.height/2, size.width, size.height);}}}//给定指定容器所包含的控件,计算该容器的最小大小维度数@Overridepublic Dimension minimumLayoutSize(Container parent) {// TODO Auto-generated method stubreturn parent.getMinimumSize();}@Overridepublic Dimension preferredLayoutSize(Container parent) {// TODO Auto-generated method stubreturn parent.getPreferredSize();}@Overridepublic void removeLayoutComponent(Component comp) {// TODO Auto-generated method stub}}
package swing;import java.awt.BorderLayout;
import java.awt.EventQueue;import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;public class CloakLayoutTest extends JFrame{private JPanel contentPane;public static void main(String[] args) {try {UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");}catch(Throwable e) {e.printStackTrace();}EventQueue.invokeLater(new Runnable() {@Overridepublic void run() {try {ClockLayoutTest frame = new ClockLayoutTest();frame.setVisible(true);}catch(Exception e) {e.printStackTrace();}}});}public CloakLayoutTest() {setTitle("建立时钟布局");setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setBounds(100,100,450,300);contentPane = new JPanel();contentPane.setBorder(new EmptyBorder(5,5,5,5));contentPane.setLayout(new BorderLayout(0,0));setContentPane(contentPane);setLayout(new ClockLayoutTest());for(int i = 0;i<12;i++) {if(i<10) {add(new JButton(""+i));}else {add(new JButton(""+i));}}}}

7.3简单投票系统

【多个组件的使用】
在日常生活中,我们经常会遇到进行投票的情况。本例实现一个简单的投票计数软件

在这里插入图片描述

package swing;import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;public class VoteCount extends JFrame{private JPanel contentPane;//设置4个复选框private JCheckBox checkBox1;private JCheckBox checkBox2;private JCheckBox checkBox3;private JCheckBox checkBox4;//设置4个标签private JLabel label1;private JLabel label2;private JLabel label3;private JLabel label4;//设置4个进度条private JProgressBar progressBar1;private JProgressBar progressBar2;private JProgressBar progressBar3;private JProgressBar progressBar4;public static void main(String[] args) {	try {UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");}catch(Throwable e){e.printStackTrace();}EventQueue.invokeLater(new Runnable() {public void run() {try {VoteCount frame = new VoteCount();frame.setVisible(true);}catch(Exception e) {e.printStackTrace();}}});}public VoteCount() {setTitle("简单投票系统");setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setBounds(100,100,450,300);contentPane = new JPanel();contentPane.setBorder(new EmptyBorder(5,5,5,5));setContentPane(contentPane);contentPane.setLayout(new BorderLayout(0,0));JPanel buttonPanel = new JPanel();contentPane.add(buttonPanel,BorderLayout.SOUTH);JButton submitButton = new JButton("提交");submitButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {do_submitButton_actionPerformed(e);}});buttonPanel.add(submitButton);JButton refreshButton = new JButton("刷新");refreshButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {do_refreshButton_actionPerformed(e);}});buttonPanel.add(refreshButton);JPanel panel = new JPanel();panel.setBorder(new TitledBorder(new LineBorder(new Color(0,0,0)),"我最喜爱的水果",TitledBorder.LEADING,TitledBorder.TOP,null,new Color(59,59,59)));contentPane.add(panel,BorderLayout.CENTER);panel.setLayout(new GridLayout(4,1,15,15));//第一条记录JPanel panel1 = new JPanel();panel.add(panel1);panel1.setLayout(new BorderLayout(0,0));checkBox1 = new JCheckBox("苹果");panel1.add(checkBox1,BorderLayout.WEST);label1 = new JLabel("0票");panel1.add(label1,BorderLayout.EAST);progressBar1 = new JProgressBar();progressBar1.setStringPainted(true);panel1.add(progressBar1,BorderLayout.CENTER);//第二条记录JPanel panel2 = new JPanel();panel.add(panel2);panel2.setLayout(new BorderLayout(0,0));checkBox2 = new JCheckBox("香蕉");panel2.add(checkBox2,BorderLayout.WEST);label2 = new JLabel("0票");panel2.add(label2,BorderLayout.EAST);progressBar2 = new JProgressBar();progressBar2.setStringPainted(true);panel2.add(progressBar2,BorderLayout.CENTER);//第三条记录JPanel panel3 = new JPanel();panel.add(panel3);panel3.setLayout(new BorderLayout(0,0));checkBox3 = new JCheckBox("梨");panel3.add(checkBox3,BorderLayout.WEST);label3 = new JLabel("0票");panel3.add(label3,BorderLayout.EAST);progressBar3 = new JProgressBar();progressBar3.setStringPainted(true);panel3.add(progressBar3,BorderLayout.CENTER);//第四条记录JPanel panel4 = new JPanel();panel.add(panel4);panel4.setLayout(new BorderLayout(0,0));checkBox4 = new JCheckBox("桃子");panel4.add(checkBox4,BorderLayout.WEST);label4 = new JLabel("0票");panel4.add(label4,BorderLayout.EAST);progressBar4 = new JProgressBar();progressBar4.setStringPainted(true);panel4.add(progressBar4,BorderLayout.CENTER);}protected void do_submitButton_actionPerformed(ActionEvent e) {String text1 = label1.getText(); //获得标签文本int number1 = Integer.parseInt(text1.substring(0,text1.length()-1));//获得票数String text2 = label1.getText(); //获得标签文本int number2 = Integer.parseInt(text1.substring(0,text1.length()-1));//获得票数String text3 = label1.getText(); //获得标签文本int number3 = Integer.parseInt(text1.substring(0,text1.length()-1));//获得票数String text4 = label1.getText(); //获得标签文本int number4 = Integer.parseInt(text1.substring(0,text1.length()-1));//获得票数if(checkBox1.isSelected()) { //如果被选中number1++;				//票数+1label1.setText(number1+"票");//更新标签}if(checkBox2.isSelected()) {number2++;label2.setText(number2+"票");}if(checkBox3.isSelected()) {number3++;label3.setText(number3+"票");}if(checkBox4.isSelected()) {number4++;label4.setText(number4+"票");}//计算总票数double total = number1 + number2 + number3 +number4;progressBar1.setString(number1*100/total+"%"); //在进度条上显示票数progressBar1.setValue(number1);progressBar2.setString(number2*100/total+"%"); //在进度条上显示票数progressBar2.setValue(number2);progressBar3.setString(number3*100/total+"%"); //在进度条上显示票数progressBar3.setValue(number3);progressBar4.setString(number4*100/total+"%"); //在进度条上显示票数progressBar4.setValue(number4);}protected void do_refreshButton_actionPerformed(ActionEvent e) {//建立动作事件的响应checkBox1.setSelected(false);checkBox2.setSelected(false);checkBox3.setSelected(false);checkBox4.setSelected(false);}}

7.4 包含图片的弹出菜单

【JPopMenu的使用】
Windows应用软件单击鼠标右键,会出现一个弹出菜单,菜单可以进行排列桌面图片、创建文件或文件夹等操作。本例演示如何利用Swing创建包含图片的弹出菜单

package swing;import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JProgressBar;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;class PopupMenuImage extends Frame{private JPanel contentPane;public static void main(String[] args) {try {UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");}catch(Throwable e) {e.printStackTrace();}EventQueue.invokeLater(new Runnable() {public void run() {try {PopupMenuImage frame = new PopupMenuImage();frame.setVisible(true);}catch(Exception e){e.printStackTrace();}}});}public PopupMenuImage() {setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setBounds(100,100,300,200);contentPane = new JPanel();contentPane.setBorder(new EmptyBorder(5,5,5,5));JPopupMenu popupMenu = new JPopupMenu();contentPane.setComponentPopupMenu(popupMenu);JMenuItem cut = new JMenuItem("剪切");cut.setIcon(new ImageIcon(PopupMenuImage.class.getResource("./cut.jpg")));cut.addActionListener(listener);popupMenu.add(cut);JMenuItem copy = new JMenuItem("拷贝");copy.setIcon(new ImageIcon(PopupMenuImage.class.getResource("./cpoy.jpg")));copy.addActionListener(listener);popupMenu.add(copy);JMenuItem paste = new JMenuItem("粘贴");paste.setIcon(new ImageIcon(PopupMenuImage.class.getResource("./paste.jpg")));paste.addActionListener(listener);popupMenu.add(paste);contentPane.setLayout(new BorderLayout(0,0));setContentPane(contentPane);label = new JLabel("单击鼠标右键弹出菜单");contentPane.add(label,BorderLayout.NORTH);}private void setDefaultCloseOperation(int exitOnClose) {// TODO Auto-generated method stub}private void setContentPane(JPanel contentPane2) {// TODO Auto-generated method stub}private ActionListener listener = new ActionListener() {public void actionPerformed(ActionEvent e) {label.setText(e.getActionCommand());}};
private JLabel label;}

7.5 震动效果提示信息

在这里插入图片描述

package swing;import javax.swing.Timer;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;import javax.swing.JDialog;
import javax.swing.JOptionPane;public class ShakeEffect {private JDialog dialog;private Point start;private Timer shakeTimer;public ShakeEffect(JDialog dialog) {this.dialog = dialog;}public void startShake() { //开始震动方法final long startTime = System.currentTimeMillis();//获得程序运行起始时间start = dialog.getLocation();shakeTimer = new Timer(10,new ActionListener() {public void actionPerformed(ActionEvent e) {long elapsed = System.currentTimeMillis() - startTime;Random random = new Random(elapsed);int change = random.nextInt(50);dialog.setLocation(start.x +change,start.y+change);//随机改变坐标if(elapsed >=1000) {stopShake();}}});shakeTimer.start();}public void stopShake() {shakeTimer.stop();dialog.setLocation(start);dialog.repaint();}public static void main(String[] args) {JOptionPane pane = new JOptionPane("特别注意",JOptionPane.WARNING_MESSAGE);JDialog d = pane.createDialog(null,"震动效果对话框");//获得对话框对象ShakeEffect sd = new ShakeEffect(d);d.pack();d.setModal(false);d.setVisible(true);sd.startShake();}}

8 答疑解惑

swing是一个用于开发Java应用程序图形界面的开发工具包,以抽象窗口工具包(AWT)为基础使跨平台应用程序可以使用任何可插拔的外观风格。
一般的桌面应用,使用Java Swing是绰绰有余的。但是大型网站、ERP等大型项目不适合使用Swing。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/40032.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Megatron-DeepSpeed与Megatron-LM在reduce grad上的差异

Megatron-DeepSpeed与Megatron-LM在reduce grad上的差异 一.Megatron-DeepSpeed 实现【deepspeed/runtime/engine.py】二.ModelLink 实现【ParamAndGradBuffer】1.ParamAndGradBuffer功能介绍2.实现原理A.分配一大块内存B.获取视图C.all_reduce grad 测试DP1,TP2,PP1,MBS1,zero…

【信即是功夫】人皆有良知在心中

良知就是做人、做事的准则&#xff0c;良知就是天理&#xff1b;实实在在地自信 每个人心中都有一个圣人&#xff0c;只因自己不能真的相信&#xff0c;把这个圣人埋没了 良知在每个人心中&#xff0c;无论你如何做&#xff0c;也无法泯灭它。即使身为盗贼的人&#xff0c;他…

WebStorm配置路径别名(jsconfig.json)

项目是 ViteVueTs 新建一个 jsconfig.json文件 {"compilerOptions": {"baseUrl": ".","paths": {"/*": ["./src/*"]}},"exclude": ["node_modules", "dist"] }然后在 vite.confi…

Sping源码(九)—— Bean的初始化(非懒加载)—mergeBeanDefinitionPostProcessor

序言 前几篇文章详细介绍了Spring中实例化Bean的各种方式&#xff0c;其中包括采用FactoryBean的方式创建对象、使用反射创建对象、自定义BeanFactoryPostProcessor以及构造器方式创建对象。 创建对象 这里再来简单回顾一下对象的创建&#xff0c;不知道大家有没有这样一个疑…

day01-切片和索引

day01-切片和索引 ndarray对象的内容可以通过索引或切片来访问和修改&#xff0c;与 Python 中list 的切片操作一样。 ndarray数组可以基于0-n的下标进行索引 注意&#xff0c;数组切片并不像列表切片会重新开辟一片空间&#xff0c;而是地址引用&#xff0c;需要使用.copy()…

算法day1 两数之和 两数相加 冒泡排序 快速排序

两数之和 最简单的思维方式肯定是去凑两个数&#xff0c;两个数的和是目标值就ok。这里两遍for循环解决。 两数相加 敲了一晚上哈哈&#xff0c;结果超过int范围捏&#xff0c;难受捏。 public class Test2 {public static void main(String[] args) { // ListNode l1 …

IO多路复用学习

Linux中的I/O多路复用 相关基础概念 在学习I/O多路复用之前&#xff0c;先学习一些相关的基础概念&#xff0c;便于理解。 内核缓冲区和用户缓冲区 &#x1f62e; CPU 上会运行两种程序&#xff0c;一种是操作系统的内核程序&#xff08;也称为系统程序&#xff09;&#x…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(二十)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 30 节&#xff09; P30《29.数据持久化-用户首选项》 实现数据持久化在harmonyOS中有很多种方式&#xff0c;比较常见的是以下两…

OpenCV教程02:图像处理系统1.0(翻转+形态学+滤波+缩放+旋转)

-------------OpenCV教程集合------------- Python教程99&#xff1a;一起来初识OpenCV&#xff08;一个跨平台的计算机视觉库&#xff09; OpenCV教程01&#xff1a;图像的操作&#xff08;读取显示保存属性获取和修改像素值&#xff09; OpenCV教程02&#xff1a;图像处理…

WIN32核心编程 - 数据类型 错误处理 字符处理

公开视频 -> 链接点击跳转公开课程博客首页 -> 链接点击跳转博客主页 目录 数据类型 基本数据类型 Win32基本数据类型 错误处理 C语言中的错误处理 C中的错误处理 Win32中的错误处理 字符处理 C/C WIN32 字符处理 数据类型 基本数据类型 C/C语言定义了一系列…

Rocky Linux 9 系统OpenSSH CVE-2024-6387 漏洞修复

Rocky Linux 9系统 OpenSSH CVE-2024-6387 漏洞修复 1、漏洞修复2、修复思路3、修复方案3.1、方案一3.2、方案二 4、总结5、参考 1、漏洞修复 CVE-2024-6387&#xff1a;regreSSHion&#xff1a;OpenSSH 服务器中的远程代码执行&#xff08;RCE&#xff09;&#xff0c;至少在…

【目标检测】DINO

一、引言 论文&#xff1a; DINO: DETR with Improved DeNoising Anchor Boxes for End-to-End Object Detection 作者&#xff1a; IDEA 代码&#xff1a; DINO 注意&#xff1a; 该算法是在Deformable DETR、DAB-DETR、DN-DETR基础上的改进&#xff0c;在学习该算法前&#…

《IT 领域准新生暑期预习指南:开启未来科技之旅》

IT专业入门&#xff0c;高考假期预习指南 高考的落幕&#xff0c;只是人生长途中的一个逗号&#xff0c;对于心怀 IT 梦想的少年们&#xff0c;新的征程已然在脚下铺展。这个七月&#xff0c;当分数尘埃落定&#xff0c;你们即将迈向新的知识殿堂&#xff0c;而这个假期&#…

Git使用[推送大于100M的文件后解救办法]

推送大于100M的文件后解救办法 本文摘录于&#xff1a;https://blog.csdn.net/u012150602/article/details/122687435只是做学习备份之用&#xff0c;绝无抄袭之意&#xff0c;有疑惑请联系本人&#xff01; 当有文件大于100M的时候在提交的时候没有问题,但是在push的似乎就不行…

番外篇 | 手把手教你如何去更换YOLOv5的检测头为ASFF_Detect

前言:Hello大家好,我是小哥谈。自适应空间特征融合(ASFF)的主要原理旨在解决单次检测器中不同尺度特征的不一致性问题。具体来说,ASFF通过动态调整来自不同尺度特征金字塔层的特征贡献,确保每个检测对象的特征表示是一致且最优的。本文所做出的改进是将YOLOv5的检测头更换…

程序算法设计分析

动态规划和分治、贪心相比有什么区别&#xff1f;各自的优缺点&#xff1f; 分治算法特征&#xff1a; 1&#xff09;规模如果很小&#xff0c;则很容易解决。//一般问题都能满足 2&#xff09;大问题可以分为若干规模小的相同问题。//前提 3&#xff09;利用子问题的解&#x…

O2OA(翱途)开发平台 V9.1 即将发布,更安全、更高效、更开放

尊敬的O2OA(翱途)平台合作伙伴、用户以及亲爱的开发小伙伴们&#xff0c;O2OA(翱途)平台 V9.1将于7月3日正式发布&#xff0c;届时欢迎大家到O2OA官网部署下载及体验最新版本。新版本我们在如下方面做了更大的努力&#xff1a; 1.扩展数据库兼容性和功能范围&#xff1a;在O2OA…

基于Web技术的教育辅助系统设计与实现(SpringBoot MySQL)+文档

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

汽车电子工程师入门系列——CAN 规范系列通读

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…

使用ps给gif动图抠图

目录 导入gif图片 打开时间轴 选择图片 魔棒抠图-初步抠图 套索抠图-精准抠图 导入gif图片 打开时间轴 因为gif动图实际上多张图片实现的效果&#xff0c;所以如果要给gif抠图&#xff0c;就得挨个给每个时间线的图片抠图 点击窗口->时间轴 选择图片 在时间轴上选择要…