第5章 常用API
作者:张子默
一、章节结构
二、API概述
**API(Application Programming Interface):**应用程序编程接口。
**Java API:**Java API指的就是JDK中提供的各种功能的Java类。这些类将底层进行了封装,使用者不需要关心这些类是如何实现的,只需要知道如何使用这些类即可。为了帮助使用者使用这些类,Java提供了专门的帮助文档。
Java帮助文档使用
-
在左侧栏索引位置输入想要使用的Java类检索,在检索结果中单击即可在右侧展示相关类信息
-
Java类所在的包
小贴士:
- Java类在java.lang报下,不需要导包
- Java类的简单案例
- Java构造方法
- Java成员方法
三、包和导包
包的概念
包其实就是文件夹,其作用是对类进行分类管理。
包的定义格式
package 包名;
小贴士:
- 包名一般是公司域名反写,并且多级包用
.
分隔,如:www.zzm.com
包名为com.zzm
案例
-
学生类
package com.packages.student; /** * 用途:学生类 * 时间:2024/6/23 1:01 * 创建人:张子默 */ public class Student { public void study() { System.out.println("好好学习天天向上"); } }
-
学生测试类-同包
package com.packages.student; /** * 用途:学生测试类-同包 * 时间:2024/6/23 1:03 * 创建人:张子默 */ public class StudentTest { public static void main(String[] args) { Student s = new Student(); s.study(); } }
-
学生测试类-不同包
package com.packages.test; /** * 用途:学生测试类-不同包 * 时间:2024/6/23 1:03 * 创建人:张子默 */ public class StudentTest { public static void main(String[] args) { com.packages.student.Student s = new com.packages.student.Student(); s.study(); } }
小贴士:
- 在同一个包下,类可以直接被使用
- 在不同的包下,使用类必须定义它的全类名、
- 使用不同包下的类时,使用的时候要写类的全路径,这样类的使用就比较繁琐,为了简化导包的操作,Java提供了导包的功能
导包
导包格式
import 包名;
import com.zzm.packages.Student;
案例
-
学生测试类-不同包优化
package com.packages.test; import com.packages.student.Student; /** * 用途:学生测试类-不同包 * 时间:2024/6/23 1:03 * 创建人:张子默 */ public class StudentTest { public static void main(String[] args) { // com.packages.student.Student s = new com.packages.student.Student(); // s.study(); Student s = new Student(); s.study(); } }
小贴士:导包的 三种方式
- 手动导包
- 快捷键导包
- 写一个类,写一部分的时候,如果给出了对应的提示,回车后自动导包
四、Scanner类
Scanner
是一个简单的文本扫描程序,可以获取基本数据类型数据和字符串数据。
构造方法
Scanner(InputStream source):创建Scanner对象
Scanner sc = new Scanner(System.in);
小贴士:
- System.in:对应的是InputStream类型,可以表示键盘输入
成员方法
int nextInt():获取一个int类型的数据
int i = sc.nextInt();
案例:数据求和
package com.packages.scanner;
import java.util.Scanner;
/**
* 用途:数据求和
* 时间:2024/6/23 1:37
* 创建人:张子默
*/
/*
需求:键盘录入两个整数,求两个数据和,并在控制台输出求和结果
分析:
1.创建键盘录入数据对象
2.通过键盘录入数据对象调用nextInt()方法获取数据
3.对获取的两个整数求和
4.在控制台输出求和结果
*/
public class ScannerSum {
public static void main(String[] args) {
// 创建键盘录入数据对象
Scanner sc = new Scanner(System.in);
// 通过键盘录入数据对象调用nextInt()方法获取数据
System.out.println("请输入第一个整数:");
int firstNumber = sc.nextInt();
System.out.println("请输入第二个整数:");
int secondNumber = sc.nextInt();
// 对获取的两个整数求和
int sum = firstNumber + secondNumber;
// 在控制台输出求和结果
System.out.println("求和结果是:" + sum);
}
}
五、Random类
Random
类的实例用于生成随机数。
Random基本使用
构造方法
Random():创建一个新的随机数生成器
成员方法
int nextInt(int bound):获取一个int类型的随机数,参数bound表示获取到的随机数在[0, bound)之间。
案例
-
Random的基本使用
package com.packages.random; import java.util.Random; /** * 用途:Random的基本使用 * 时间:2024/6/23 1:49 * 创建人:张子默 */ public class RandomDemo { public static void main(String[] args) { // Random():创建一个新的随机数生成器 Random r = new Random(); // int nextInt(int bound):获取一个int类型的随机数,参数bound表示获取到的随机数在[0, bound)之间 // int i = r.nextInt(10); // System.out.println(i); // for (int i = 1; i <= 10; i++) { // int j = r.nextInt(10); // System.out.println(j); // } // 需求:如何获取1-100之间的随机数 // int number = r.nextInt(100); // 0-99 // int number = r.nextInt(101); // 0-100 int number = r.nextInt(100) + 1; System.out.println(number); } }
-
猜数字游戏
package com.packages.random; import java.util.Random; import java.util.Scanner; /** * 用途:猜数字小游戏 * 时间:2024/6/23 11:13 * 创建人:张子默 */ /* 需求:系统自动产生一个1-100之间的整数,使用程序实现猜这个数字是多少 猜的时候根据不同情况给出相应的提示 如果猜的数字比真实数字大,提示你猜的数字大了 如果猜的数字比真实数字小,提示你猜的数据小了 如果猜的数字与真实数字相等,提示恭喜你猜中了 分析: 1.使用Random获取一个1-100之间的整数 2.使用Scanner实现键盘录入猜的数据值 3.使用if...else if ... else的格式实现猜数字,并给出对应的提示 */ public class RandomTest { public static void main(String[] args) { // 使用Random获取一个1-100之间的整数 Random r = new Random(); int number = r.nextInt(100) + 1; System.out.println("系统已经产生了一个1-100之间的整数"); while (true) { // 使用Scanner实现键盘录入猜的数据值 Scanner sc = new Scanner(System.in); System.out.println("请输入你要猜的数字:"); int guessNumber = sc.nextInt(); // 使用if...else if...else的格式实现猜数字,并给出相应的提示 if (guessNumber > number) { System.out.println("你猜的数字" + guessNumber + "大了"); } else if (guessNumber < number) { System.out.println("你猜的数字" + guessNumber + "小了"); } else { System.out.println("恭喜你猜中了"); break; } } } }
六、GUI
GUI概述
GUI(Graphical User Interface),图形用户接口,以图形的方式来显示计算机操作的界面。
GUI相关API
Java为GUI提供的API都存在java.awt和java.Swing两个包中。
-
java.awt包:抽象窗口工具包,这个包的API需要调用本地系统方法实现功能,和本地系统有关联,不利于代码移植,属重量级控件。
-
java.Swing包:该包是在awt包的基础上建立的一套图形界面系统,提供了更多的组件,而且完全由Java实现,增强了移植性,属轻量级控件。
因此,我们做图形界面开发使用的是swing包下的类。
组件的概念
组件是具有图形表示的对象,该图形表示可以显示在屏幕上并且可以与用户交互。比如说,在用户登录中,文本框和按钮等,都是能够表示图形的对象,所以他们都称为组件。
常用组件
基本组件:具有图形表示的对象。
容器组件:可以添加组件的组件,也就是在容器中可以通过add方法添加组件,既可以添加基本组件,也可以添加容器组件。
基本组件
- JButton:按钮组件。
- JLabel:用来显示文本内容,或者展示图片。
- JTextFile:文本框,用来输入内容。
- JTextArea:文本域,用于输入多行多列的数据。
容器组件
- 面板也是一个容器,我们常用JPanel。
- 窗体Frame,在awt包下,而开发过程中使用的是JFrame,在Swing包下。
小贴士:
由于我们使用的都是Swing包下的组件,所以将来使用的组件,都是以J开头的。
常用组件
JFrame概述
JFrame是一个顶层窗口。
-
构造方法
JFrame():构造一个最初不可见的的窗体
-
成员方法
void setVisible(boolean b):显示或隐藏窗体取决于参数b的值。 void setSize(int width, int height):调整此组件的大小,使其宽度为width,高度为height,单位是像素。
JFrame常用设置
void setTitle(String title):设置窗体标题
void setLocationRelativeTo(Component c):设置位置,值为null,则窗体位于屏幕中央
void setDefaultCloseOperation(int operation):设置窗体关闭时默认操作(整数3表示窗口关闭时退出应用程序)
void setAlwaysOnTop(boolean alwaysOnTop):设置此窗口是否应始终位于其它窗口之上
案例
package com.gui;
import javax.swing.*;
/**
* 用途:JFrame常用设置
* 时间:2024/6/23 18:31
* 创建人:张子默
*/
/*
void setTitle(String title):设置窗体标题
void setLocationRelativeTo(Component c):设置位置,值为null,则窗体位于屏幕中央
void setDefaultCloseOperation(int operation):设置窗体关闭时默认操作(整数3表示窗口关闭时退出应用程序)
void setAlwaysOnTop(boolean alwaysOnTop):设置此窗口是否应始终位于其他窗口之上
*/
public class JFrameDemo02 {
public static void main(String[] args) {
// 创建窗口对象
JFrame jf = new JFrame();
// void setTitle(String title):设置窗口标题
jf.setTitle("百度一下,你就知道");
// 设置窗体大小
jf.setSize(400, 300);
// void setDefaultCloseOperation(int operation):设置窗体关闭时的默认操作(整数3表示窗口关闭时退出应用程序)
jf.setDefaultCloseOperation(3);
// void setLocationRelativeTo(Component c):设置位置,值为null,则窗体位于屏幕中央
jf.setLocationRelativeTo(null);
// void setAlwaysOnTop(boolean alwaysOnTop):设置此窗口是否应始终位于其它窗口之上
jf.setAlwaysOnTop(true);
// 设置窗体可见
jf.setVisible(true);
}
}
JButton
JButton是按钮的实现。
-
构造方法
JButton(String text):创建一个带文本的按钮
-
成员方法
void setSize(int width, int height):设置大小 void setLocation(int x, int y):设置位置(x坐标, y坐标) void setBounds( int x, int y, int width, int height)
小贴士:
窗体操作相关方法
- 取消窗体默认布局:窗体对象.setLayout(null);
- 把按钮添加到窗体:窗体对象.add(按钮对象);
JLabel
JLabel是短文本字符串或图像的显示区域。
-
构造方法
JLabel(String text):使用指定的文本创建JLabel实例 JLabel(Icon image):使用指定的图像创建JLabel实例
ImageIcon(String filename):从指定的文件创建ImageIcon
文件路径:绝对路径和相对路径
- 绝对路径:完整的路径名,不需要任何其他信息就可以定位它所表示的文件;例如:C:\mn.png
- 相对路径:必须使用取自其他路径名的信息进行解释;例如:images\mn.png
-
成员方法
void setBounds(int x, int y, int width, int height):设置位置和大小
小贴士:
在实际开发中,因为每个组件的大小和位置都是前端人员设计好的,所以不用担心布局的问题。
JPasswordField
JPasswordField用来表示密码框。
案例
- 用户登录
package com.gui;
import javax.swing.*;
/**
* 用途:用户登录
* 时间:2024/6/23 19:54
* 创建人:张子默
*/
public class UserLogin {
public static void main(String[] args) {
// 创建窗体对象
JFrame jf = new JFrame();
jf.setTitle("用户登录");
jf.setSize(400, 300);
jf.setDefaultCloseOperation(3);
jf.setLocationRelativeTo(null);
jf.setAlwaysOnTop(true);
jf.setLayout(null);
// 显示用户名文本
JLabel usernameLabel = new JLabel("用户名");
usernameLabel.setBounds(50, 50, 50, 20);
jf.add(usernameLabel);
// 用户名输入框
JTextField usernameField = new JTextField();
usernameField.setBounds(150, 50, 180, 20);
jf.add(usernameField);
// 显示密码文本
JLabel passwordLabel = new JLabel("密码");
passwordLabel.setBounds(50, 100, 50, 20);
jf.add(passwordLabel);
// 密码输入框
// JTextField passwordField = new JTextField();
// passwordField.setBounds(150, 100, 180, 20);
// jf.add(passwordField);
JPasswordField passwordField = new JPasswordField();
passwordField.setBounds(150, 100, 180, 20);
jf.add(passwordField);
// 登录按钮
JButton loginButton = new JButton("登录");
loginButton.setBounds(50, 200, 280, 20);
jf.add(loginButton);
jf.setVisible(true);
}
}
- 聊天室
package com.gui;
import javax.swing.*;
/**
* 用途:聊天室
* 时间:2024/6/23 20:12
* 创建人:张子默
*/
public class ChatRoom {
public static void main(String[] args) {
// 创建窗体对象
JFrame jf = new JFrame();
jf.setTitle("聊天室");
jf.setSize(400, 300);
jf.setDefaultCloseOperation(3);
jf.setLocationRelativeTo(null);
jf.setAlwaysOnTop(true);
jf.setLayout(null);
// 显示聊天信息文本域
JTextArea messageArea = new JTextArea();
messageArea.setBounds(10, 10, 360, 200);
jf.add(messageArea);
// 输入聊天信息的文本框
JTextField messageField = new JTextField();
messageField.setBounds(10, 230, 180, 20);
jf.add(messageField);
// 发送按钮
JButton sendButton = new JButton("发送");
sendButton.setBounds(200, 230, 70, 20);
jf.add(sendButton);
// 清空聊天按钮
JButton clearButton = new JButton("清空聊天");
clearButton.setBounds(280, 230, 100, 20);
jf.add(clearButton);
jf.setVisible(true);
}
}
- 猜数字
package com.gui;
import javax.swing.*;
/**
* 用途:猜数字
* 时间:2024/6/23 20:40
* 创建人:张子默
*/
public class GuessNumber {
public static void main(String[] args) {
// 创建窗体对象
JFrame jf = new JFrame();
jf.setTitle("猜数字");
jf.setSize(400, 300);
jf.setDefaultCloseOperation(3);
jf.setLocationRelativeTo(null);
jf.setAlwaysOnTop(true);
jf.setLayout(null);
// 提示信息
JLabel messageLabel = new JLabel("系统产生了一个1-100之间的数据,清猜一猜");
messageLabel.setBounds(70, 50, 350, 20);
jf.add(messageLabel);
// 请输入要猜的数字
JTextField numberField = new JTextField();
numberField.setBounds(120, 100, 150, 20);
jf.add(numberField);
// 猜数字的按钮
JButton guessButton = new JButton("我猜");
guessButton.setBounds(150, 150, 100, 20);
jf.add(guessButton);
jf.setVisible(true);
}
}
-
手机日期和时间显示
package com.gui; import javax.swing.*; /** * 用途:手机日期和时间显示 * 时间:2024/6/23 20:49 * 创建人:张子默 */ public class ShowDateTime { public static void main(String[] args) { // 创建窗体对象 JFrame jf = new JFrame(); jf.setTitle("手机日期和时间显示"); jf.setSize(400, 300); jf.setDefaultCloseOperation(3); jf.setLocationRelativeTo(null); jf.setAlwaysOnTop(true); jf.setLayout(null); // 提示日期 JLabel dateLabel = new JLabel("日期"); dateLabel.setBounds(50, 50, 100, 20); jf.add(dateLabel); // 按照格式显示日期的字符串 JLabel showDateLabel = new JLabel("xxxx年xx月xx日"); showDateLabel.setBounds(50, 80, 200, 20); jf.add(showDateLabel); // 提示时间 JLabel timeLabel = new JLabel(); timeLabel.setBounds(50, 150, 100, 20); jf.add(timeLabel); // 按照格式显示时间的字符串 JLabel showTimeLabel = new JLabel("xx:xx"); showTimeLabel.setBounds(50, 180, 200, 20); jf.add(showTimeLabel); jf.setVisible(true); } }
-
日历控件
package com.gui;
import javax.swing.*;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import java.awt.*;
import java.awt.event.*;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.*;
/*
日期选择器,可以指定日期的显示格式
*/
public class DateChooser extends JPanel {
private static final long serialVersionUID = 4529266044762990227L;
private Date initDate;
private Calendar now = Calendar.getInstance();
private Calendar select;
private JPanel monthPanel;// 月历
private JP1 jp1;// 四块面板,组成
private JP2 jp2;
private JP3 jp3;
private JP4 jp4;
private Font font = new Font("宋体", Font.PLAIN, 12);
private final LabelManager lm = new LabelManager();
private SimpleDateFormat sdf;
private boolean isShow = false;
private Popup pop;
private JComponent showDate;
public static DateChooser getInstance() {
return new DateChooser();
}
public static DateChooser getInstance(Date date) {
return new DateChooser(date);
}
public static DateChooser getInstance(String format) {
return new DateChooser(format);
}
public static DateChooser getInstance(Date date, String format) {
return new DateChooser(date, format);
}
/**
* Creates a new instance of DateChooser
*/
private DateChooser() {
this(new Date());
}
private DateChooser(Date date) {
this(date, "yyyy年MM月dd日");
}
private DateChooser(String format) {
this(new Date(), format);
}
private DateChooser(Date date, String format) {
initDate = date;
sdf = new SimpleDateFormat(format);
select = Calendar.getInstance();
select.setTime(initDate);
initPanel();
}
/**
* 是否允许用户选择
*/
public void setEnabled(boolean b) {
super.setEnabled(b);
showDate.setEnabled(b);
}
/**
* 得到当前选择框的日期
*/
public Date getDate() {
return select.getTime();
}
public String getStrDate() {
return sdf.format(select.getTime());
}
public String getStrDate(String format) {
sdf = new SimpleDateFormat(format);
return sdf.format(select.getTime());
}
// 根据初始化的日期,初始化面板
private void initPanel() {
monthPanel = new JPanel(new BorderLayout());
monthPanel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
JPanel up = new JPanel(new BorderLayout());
up.add(jp1 = new JP1(), BorderLayout.NORTH);
up.add(jp2 = new JP2(), BorderLayout.CENTER);
monthPanel.add(jp3 = new JP3(), BorderLayout.CENTER);
monthPanel.add(up, BorderLayout.NORTH);
monthPanel.add(jp4 = new JP4(), BorderLayout.SOUTH);
this.addAncestorListener(new AncestorListener() {
public void ancestorAdded(AncestorEvent event) {
}
public void ancestorRemoved(AncestorEvent event) {
}
// 只要祖先组件一移动,马上就让popup消失
public void ancestorMoved(AncestorEvent event) {
hidePanel();
}
});
}
public void register(final JComponent showDate) {
this.showDate = showDate;
showDate.setRequestFocusEnabled(true);
showDate.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
showDate.requestFocusInWindow();
}
});
this.setBackground(Color.WHITE);
this.add(showDate, BorderLayout.CENTER);
this.setPreferredSize(new Dimension(90, 25));
this.setBorder(BorderFactory.createLineBorder(Color.GRAY));
showDate.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
if (showDate.isEnabled()) {
showDate.setCursor(new Cursor(Cursor.HAND_CURSOR));
showDate.setForeground(Color.RED);
}
}
public void mouseExited(MouseEvent me) {
if (showDate.isEnabled()) {
showDate.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
showDate.setForeground(Color.BLACK);
}
}
public void mousePressed(MouseEvent me) {
if (showDate.isEnabled()) {
showDate.setForeground(Color.CYAN);
if (isShow) {
hidePanel();
} else {
showPanel(showDate);
}
}
}
public void mouseReleased(MouseEvent me) {
if (showDate.isEnabled()) {
showDate.setForeground(Color.BLACK);
}
}
});
showDate.addFocusListener(new FocusListener() {
public void focusLost(FocusEvent e) {
hidePanel();
}
public void focusGained(FocusEvent e) {
}
});
}
// 根据新的日期刷新
private void refresh() {
jp1.updateDate();
jp2.updateDate();
jp3.updateDate();
jp4.updateDate();
SwingUtilities.updateComponentTreeUI(this);
}
// 提交日期
private void commit() {
// TODO add other components here
if (showDate instanceof JTextField) {
((JTextField) showDate).setText(sdf.format(select.getTime()));
} else if (showDate instanceof JLabel) {
((JLabel) showDate).setText(sdf.format(select.getTime()));
}
hidePanel();
}
// 隐藏日期选择面板
private void hidePanel() {
if (pop != null) {
isShow = false;
pop.hide();
pop = null;
}
}
// 显示日期选择面板
private void showPanel(Component owner) {
if (pop != null) {
pop.hide();
}
Point show = new Point(0, showDate.getHeight());
SwingUtilities.convertPointToScreen(show, showDate);
Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
int x = show.x;
int y = show.y;
if (x < 0) {
x = 0;
}
if (x > size.width - 295) {
x = size.width - 295;
}
if (y < size.height - 170) {
} else {
y -= 188;
}
pop = PopupFactory.getSharedInstance()
.getPopup(owner, monthPanel, x, y);
pop.show();
isShow = true;
}
/**
* 最上面的面板用来显示月份的增减
*/
private class JP1 extends JPanel {
private static final long serialVersionUID = -5638853772805561174L;
JLabel yearleft, yearright, monthleft, monthright, center,
centercontainer;
public JP1() {
super(new BorderLayout());
this.setBackground(new Color(160, 185, 215));
initJP1();
}
private void initJP1() {
yearleft = new JLabel(" <<", JLabel.CENTER);
yearleft.setToolTipText("上一年");
yearright = new JLabel(">> ", JLabel.CENTER);
yearright.setToolTipText("下一年");
yearleft.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
yearright.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
monthleft = new JLabel(" <", JLabel.RIGHT);
monthleft.setToolTipText("上一月");
monthright = new JLabel("> ", JLabel.LEFT);
monthright.setToolTipText("下一月");
monthleft.setBorder(BorderFactory.createEmptyBorder(2, 30, 0, 0));
monthright.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 30));
centercontainer = new JLabel("", JLabel.CENTER);
centercontainer.setLayout(new BorderLayout());
center = new JLabel("", JLabel.CENTER);
centercontainer.add(monthleft, BorderLayout.WEST);
centercontainer.add(center, BorderLayout.CENTER);
centercontainer.add(monthright, BorderLayout.EAST);
this.add(yearleft, BorderLayout.WEST);
this.add(centercontainer, BorderLayout.CENTER);
this.add(yearright, BorderLayout.EAST);
this.setPreferredSize(new Dimension(295, 25));
updateDate();
yearleft.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
yearleft.setCursor(new Cursor(Cursor.HAND_CURSOR));
yearleft.setForeground(Color.RED);
}
public void mouseExited(MouseEvent me) {
yearleft.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
yearleft.setForeground(Color.BLACK);
}
public void mousePressed(MouseEvent me) {
select.add(Calendar.YEAR, -1);
yearleft.setForeground(Color.WHITE);
refresh();
}
public void mouseReleased(MouseEvent me) {
yearleft.setForeground(Color.BLACK);
}
});
yearright.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
yearright.setCursor(new Cursor(Cursor.HAND_CURSOR));
yearright.setForeground(Color.RED);
}
public void mouseExited(MouseEvent me) {
yearright.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
yearright.setForeground(Color.BLACK);
}
public void mousePressed(MouseEvent me) {
select.add(Calendar.YEAR, 1);
yearright.setForeground(Color.WHITE);
refresh();
}
public void mouseReleased(MouseEvent me) {
yearright.setForeground(Color.BLACK);
}
});
monthleft.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
monthleft.setCursor(new Cursor(Cursor.HAND_CURSOR));
monthleft.setForeground(Color.RED);
}
public void mouseExited(MouseEvent me) {
monthleft.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
monthleft.setForeground(Color.BLACK);
}
public void mousePressed(MouseEvent me) {
select.add(Calendar.MONTH, -1);
monthleft.setForeground(Color.WHITE);
refresh();
}
public void mouseReleased(MouseEvent me) {
monthleft.setForeground(Color.BLACK);
}
});
monthright.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
monthright.setCursor(new Cursor(Cursor.HAND_CURSOR));
monthright.setForeground(Color.RED);
}
public void mouseExited(MouseEvent me) {
monthright.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
monthright.setForeground(Color.BLACK);
}
public void mousePressed(MouseEvent me) {
select.add(Calendar.MONTH, 1);
monthright.setForeground(Color.WHITE);
refresh();
}
public void mouseReleased(MouseEvent me) {
monthright.setForeground(Color.BLACK);
}
});
}
private void updateDate() {
center.setText(select.get(Calendar.YEAR) + "年"
+ (select.get(Calendar.MONTH) + 1) + "月");
}
}
private class JP2 extends JPanel {
private static final long serialVersionUID = -8176264838786175724L;
public JP2() {
this.setPreferredSize(new Dimension(295, 20));
}
protected void paintComponent(Graphics g) {
g.setFont(font);
g.drawString("星期日 星期一 星期二 星期三 星期四 星期五 星期六", 5, 10);
g.drawLine(0, 15, getWidth(), 15);
}
private void updateDate() {
}
}
private class JP3 extends JPanel {
private static final long serialVersionUID = 43157272447522985L;
public JP3() {
super(new GridLayout(6, 7));
this.setPreferredSize(new Dimension(295, 100));
initJP3();
}
private void initJP3() {
updateDate();
}
public void updateDate() {
this.removeAll();
lm.clear();
Date temp = select.getTime();
Calendar select = Calendar.getInstance();
select.setTime(temp);
select.set(Calendar.DAY_OF_MONTH, 1);
int index = select.get(Calendar.DAY_OF_WEEK);
int sum = (index == 1 ? 8 : index);
select.add(Calendar.DAY_OF_MONTH, 0 - sum);
for (int i = 0; i < 42; i++) {
select.add(Calendar.DAY_OF_MONTH, 1);
lm.addLabel(new MyLabel(select.get(Calendar.YEAR), select
.get(Calendar.MONTH), select.get(Calendar.DAY_OF_MONTH)));
}
for (MyLabel my : lm.getLabels()) {
this.add(my);
}
select.setTime(temp);
}
}
private class MyLabel extends JLabel implements Comparator<MyLabel>,
MouseListener, MouseMotionListener {
private static final long serialVersionUID = 3668734399227577214L;
private int year, month, day;
private boolean isSelected;
public MyLabel(int year, int month, int day) {
super("" + day, JLabel.CENTER);
this.year = year;
this.day = day;
this.month = month;
this.addMouseListener(this);
this.addMouseMotionListener(this);
this.setFont(font);
if (month == select.get(Calendar.MONTH)) {
this.setForeground(Color.BLACK);
} else {
this.setForeground(Color.LIGHT_GRAY);
}
if (day == select.get(Calendar.DAY_OF_MONTH)) {
this.setBackground(new Color(160, 185, 215));
} else {
this.setBackground(Color.WHITE);
}
}
public boolean getIsSelected() {
return isSelected;
}
public void setSelected(boolean b, boolean isDrag) {
isSelected = b;
if (b && !isDrag) {
int temp = select.get(Calendar.MONTH);
select.set(year, month, day);
if (temp == month) {
SwingUtilities.updateComponentTreeUI(jp3);
} else {
refresh();
}
}
this.repaint();
}
protected void paintComponent(Graphics g) {
if (day == select.get(Calendar.DAY_OF_MONTH)
&& month == select.get(Calendar.MONTH)) {
// 如果当前日期是选择日期,则高亮显示
g.setColor(new Color(160, 185, 215));
g.fillRect(0, 0, getWidth(), getHeight());
}
if (year == now.get(Calendar.YEAR)
&& month == now.get(Calendar.MONTH)
&& day == now.get(Calendar.DAY_OF_MONTH)) {
// 如果日期和当前日期一样,则用红框
Graphics2D gd = (Graphics2D) g;
gd.setColor(Color.RED);
Polygon p = new Polygon();
p.addPoint(0, 0);
p.addPoint(getWidth() - 1, 0);
p.addPoint(getWidth() - 1, getHeight() - 1);
p.addPoint(0, getHeight() - 1);
gd.drawPolygon(p);
}
if (isSelected) {// 如果被选中了就画出一个虚线框出来
Stroke s = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE,
BasicStroke.JOIN_BEVEL, 1.0f,
new float[]{2.0f, 2.0f}, 1.0f);
Graphics2D gd = (Graphics2D) g;
gd.setStroke(s);
gd.setColor(Color.BLACK);
Polygon p = new Polygon();
p.addPoint(0, 0);
p.addPoint(getWidth() - 1, 0);
p.addPoint(getWidth() - 1, getHeight() - 1);
p.addPoint(0, getHeight() - 1);
gd.drawPolygon(p);
}
super.paintComponent(g);
}
public boolean contains(Point p) {
return this.getBounds().contains(p);
}
private void update() {
repaint();
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
isSelected = true;
update();
}
public void mouseReleased(MouseEvent e) {
Point p = SwingUtilities.convertPoint(this, e.getPoint(), jp3);
lm.setSelect(p, false);
commit();
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
Point p = SwingUtilities.convertPoint(this, e.getPoint(), jp3);
lm.setSelect(p, true);
}
public void mouseMoved(MouseEvent e) {
}
public int compare(MyLabel o1, MyLabel o2) {
Calendar c1 = Calendar.getInstance();
c1.set(o1.year, o2.month, o1.day);
Calendar c2 = Calendar.getInstance();
c2.set(o2.year, o2.month, o2.day);
return c1.compareTo(c2);
}
}
private class LabelManager {
private List<MyLabel> list;
public LabelManager() {
list = new ArrayList<MyLabel>();
}
public List<MyLabel> getLabels() {
return list;
}
public void addLabel(MyLabel my) {
list.add(my);
}
public void clear() {
list.clear();
}
@SuppressWarnings("unused")
public void setSelect(MyLabel my, boolean b) {
for (MyLabel m : list) {
if (m.equals(my)) {
m.setSelected(true, b);
} else {
m.setSelected(false, b);
}
}
}
public void setSelect(Point p, boolean b) {
// 如果是拖动,则要优化一下,以提高效率
if (b) {
// 表示是否能返回,不用比较完所有的标签,能返回的标志就是把上一个标签和
// 将要显示的标签找到了就可以了
boolean findPrevious = false, findNext = false;
for (MyLabel m : list) {
if (m.contains(p)) {
findNext = true;
if (m.getIsSelected()) {
findPrevious = true;
} else {
m.setSelected(true, b);
}
} else if (m.getIsSelected()) {
findPrevious = true;
m.setSelected(false, b);
}
if (findPrevious && findNext) {
return;
}
}
} else {
MyLabel temp = null;
for (MyLabel m : list) {
if (m.contains(p)) {
temp = m;
} else if (m.getIsSelected()) {
m.setSelected(false, b);
}
}
if (temp != null) {
temp.setSelected(true, b);
}
}
}
}
private class JP4 extends JPanel {
private static final long serialVersionUID = -6391305687575714469L;
public JP4() {
super(new BorderLayout());
this.setPreferredSize(new Dimension(295, 20));
this.setBackground(new Color(160, 185, 215));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
final JLabel jl = new JLabel("今天: " + sdf.format(new Date()));
jl.setToolTipText("点击选择今天日期");
this.add(jl, BorderLayout.CENTER);
jl.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
jl.setCursor(new Cursor(Cursor.HAND_CURSOR));
jl.setForeground(Color.RED);
}
public void mouseExited(MouseEvent me) {
jl.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
jl.setForeground(Color.BLACK);
}
public void mousePressed(MouseEvent me) {
jl.setForeground(Color.WHITE);
select.setTime(new Date());
refresh();
commit();
}
public void mouseReleased(MouseEvent me) {
jl.setForeground(Color.BLACK);
}
});
}
private void updateDate() {
}
}
public static void main(String[] args) {
//创建窗体
JFrame jf = new JFrame();
//设置窗体大小
jf.setSize(400, 300);
//设置窗体标题
jf.setTitle("日历控件");
//设置位置,值为null,则窗体位于屏幕中央
jf.setLocationRelativeTo(null);
//设置窗体关闭时默认操作,窗口关闭时退出应用程序
jf.setDefaultCloseOperation(3);
//设置此窗口是否应始终位于其他窗口之上
jf.setAlwaysOnTop(true);
//取消窗体默认布局:窗体对象.setLayout(null);
jf.setLayout(null);
//创建日期选择器对象,指定日期字符串格式
DateChooser dateChooser = DateChooser.getInstance("yyyy-MM-dd");
JTextField showDateField = new JTextField("单击选择日期");
showDateField.setBounds(50, 50, 100, 20);
//把日历控件和文本框进行绑定
dateChooser.register(showDateField);
jf.add(showDateField);
jf.setVisible(true);
}
}
package com.gui;
import javax.swing.*;
/**
* 用途:考勤查询
* 时间:2024/6/23 21:16
* 创建人:张子默
*/
public class AttendanceQuery02 {
public static void main(String[] args) {
// 创建窗体对象
JFrame jf = new JFrame();
jf.setTitle("考勤查询");
jf.setSize(400, 300);
jf.setDefaultCloseOperation(3);
jf.setLocationRelativeTo(null);
jf.setAlwaysOnTop(true);
jf.setLayout(null);
// 显示考勤日期的文本
JLabel dateLabel = new JLabel("考勤日期");
dateLabel.setBounds(50, 20, 100, 20);
jf.add(dateLabel);
// 显示开始时间文本
JLabel startDateLabel = new JLabel("开始时间");
startDateLabel.setBounds(50, 70, 100, 20);
jf.add(startDateLabel);
DateChooser dateChooser1 = DateChooser.getInstance("yyyy/MM/dd");
DateChooser dateChooser2 = DateChooser.getInstance("yyyy/MM/dd");
// 开始时间输入框
JTextField startDateField = new JTextField();
startDateField.setBounds(50, 100, 100, 20);
dateChooser1.register(startDateField);
jf.add(startDateField);
// 显示结束时间文本
JLabel endDateLabel = new JLabel("结束时间");
endDateLabel.setBounds(250, 70, 100, 20);
jf.add(endDateLabel);
// 结束时间输入框
JTextField endDateField = new JTextField();
endDateField.setBounds(250, 100, 100, 20);
dateChooser2.register(endDateField);
jf.add(endDateField);
// 确定按钮
JButton confirmButton = new JButton("确定");
confirmButton.setBounds(250, 180, 60, 20);
jf.add(confirmButton);
jf.setVisible(true);
}
}
事件监听机制
在GUI界面中要实现具体的功能,就必须使用时间监听机制,事件监听机制由事件源、事件、事件绑定组成。
事件源
事件发生的地方,可以是按钮、窗体、图片等。
事件
发生了什么事情,例如:鼠标点击事件,键盘按下事件等。
事件绑定
把事件绑定在事件源上,当发生了某个事件,则触发对应的处理逻辑。
- 事件源对象.addXXXListener(事件)
package com.gui;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* 用途:事件监听机制
* 时间:2024/6/23 21:39
* 创建人:张子默
*/
public class ActionListenerDemo {
public static void main(String[] args) {
// 创建窗体对象
JFrame jf = new JFrame();
jf.setTitle("事件监听机制");
jf.setSize(400, 300);
jf.setDefaultCloseOperation(3);
jf.setLocationRelativeTo(null);
jf.setAlwaysOnTop(true);
jf.setLayout(null);
// 创建按钮
JButton jButton = new JButton("你点我啊");
jButton.setBounds(0, 0, 100, 100);
jf.add(jButton);
jButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("你点我啊");
}
});
jf.setVisible(true);
}
}
七、String
String概述
String
类表示字符串,Java程序中的所有字符串文字(例如"abc")都实现为此类的实例。
构造方法
- String():初始化新创建的String对象,使其表示空字符序列。
- String(String original):初始化新创建的String对象,使其表示与参数相同相同的字符序列。
实例
package com.zzm;
/**
* 用途:StringDemo01
* 时间:2024/7/1 22:44
* 创建人:张子默
*/
/*
String类在java.lang包下
java.lang包下的特点是使用不需要导包
String类的构造方法
1.String();空参构造
2.String(String str);带参构造
3.直接双引号赋值
*/
public class StringDemo01 {
public static void main(String[] args) {
// 空参构造
String s1 = new String();
System.out.println(s1); // 空的字符串对象
System.out.println(s1.length()); // 0 length();返回字符串的长度(也就还包含字符的个数)
// 带参构造
String s2 = new String("abcd");
System.out.println(s2); // abcd
System.out.println(s2.length()); // 4
// 双引号直接赋值(常用)
String s3 = "琪默工作室";
System.out.println(s3); // 琪默工作室
System.out.println(s3.length()); // 5
}
}
成员方法
- int length():返回此字符串的长度。
- boolean equals(Object anObject):将此字符串与指定的对象进行比较。
- boolean equalsIgnoreCase(String anotherString):将此String与另一个String比较,忽略了大小写。
- String trim():返回一个字符串,其值为此字符串删除了所有前导和尾随空格。
实例
package com.zzm;
/**
* 用途:StringDemo02
* 时间:2024/7/1 23:13
* 创建人:张子默
*/
/*
String类成员方法
1.int length();返回字符串长度(包含字符的个数)
2.boolean equals(字符串);比较字符串内容
3.boolean equalsIgnoreCase(字符串);比较字符串内容忽略大小写
4.String trim();去除字符串首、尾的空格
*/
public class StringDemo02 {
public static void main(String[] args) {
// 定义字符串
String s1 = "abc";
String s2 = "abc";
String s3 = "ABC";
// 1.int length();返回字符串长度
System.out.println(s1.length()); // 3
// 2.boolean equals(字符串);比较引用类型数据的内容(比较引用类型数据的地址,使用==)
System.out.println(s1.equals(s2)); // 比较内容,true
System.out.println(s1.equals(s3)); // 比较内容,false
// 3.boolean equalsIgnoreCase(字符串);比较引用类型数据的内容忽略大小写(验证码)
System.out.println(s1.equalsIgnoreCase(s3)); // 比较内容忽略大小写,true
// 4.String trim();去除2字符串首、尾的空格(不能去除中间的空格)
// String str = " username";
String str = "username ";
System.out.println(str);
System.out.println(str.trim());
}
}
用户登录
package com.zzm;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* 用途:用户登录
* 时间:2024/6/23 19:54
* 创建人:张子默
*/
/*
案例:GUI案例1(用户登录)
1.已知用户名和密码
admin
123456
2.用户名和密码的长度都是6-12位
3.点击登录
先判断输入的数据长度是否合法
再判断是否登陆成功
*/
public class UserLogin {
public static void main(String[] args) {
// 创建窗体对象
JFrame jf = new JFrame();
jf.setTitle("用户登录");
jf.setSize(400, 300);
jf.setDefaultCloseOperation(3);
jf.setLocationRelativeTo(null);
jf.setAlwaysOnTop(true);
jf.setLayout(null);
// 显示用户名文本
JLabel usernameLabel = new JLabel("用户名");
usernameLabel.setBounds(50, 50, 50, 20);
jf.add(usernameLabel);
// 用户名输入框
JTextField usernameField = new JTextField();
usernameField.setBounds(150, 50, 180, 20);
jf.add(usernameField);
// 显示密码文本
JLabel passwordLabel = new JLabel("密码");
passwordLabel.setBounds(50, 100, 50, 20);
jf.add(passwordLabel);
// 密码输入框
// JTextField passwordField = new JTextField();
// passwordField.setBounds(150, 100, 180, 20);
// jf.add(passwordField);
JPasswordField passwordField = new JPasswordField();
passwordField.setBounds(150, 100, 180, 20);
jf.add(passwordField);
// 登录按钮
JButton loginButton = new JButton("登录");
loginButton.setBounds(50, 200, 280, 20);
jf.add(loginButton);
String username = "admin";
String password = "123456";
loginButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 通过输入框对象,获取用户输入的数据
String uname = usernameField.getText().trim();
String psw = passwordField.getText().trim();
// 判断用户名长度
if (uname.length() < 5 || uname.length() > 12) {
JOptionPane.showMessageDialog(jf, "用户名的长度是5-12位,请重新输入!"); // 弹框提示
usernameField.setText(""); // 清空文本框 -> 将文本框内容设置为空的字符串
return ; // 结束方法
}
// 判断密码长度
if (psw.length() < 6 || psw.length() > 12) {
JOptionPane.showMessageDialog(jf, "密码的长度是6-12位请重新输入");
passwordField.setText("");
return ;
}
// 如果长度都合法,再判断内容,注意比较字符串内容,使用equals方法
if (uname.equals(username) && psw.equals(password)) {
JOptionPane.showMessageDialog(jf, "登陆成功");
usernameField.setText("");
passwordField.setText("");
} else {
JOptionPane.showMessageDialog(jf, "用户名或密码错误,登陆失败");
}
}
});
jf.setVisible(true);
}
}
聊天室
package com.zzm;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* 用途:聊天室
* 时间:2024/7/6 20:17
* 创建人:张子默
*/
/*
1.将文本框的内容发送到文本域中
2.每次发送的文本,不带前后空格
3.多次发送的内容在文本域,追加呈现
4.清空聊天就是将文本域内容设置为空
*/
public class ChatRoom {
public static void main(String[] args) {
JFrame jf = new JFrame();
jf.setSize(400, 300);
jf.setTitle("聊天室"); // 设置窗体标题
jf.setLocationRelativeTo(null); // 设置窗体位置在中央弹出
jf.setDefaultCloseOperation(3); // 设置窗体关闭停止程序
jf.setAlwaysOnTop(true); // 设置窗体置顶
jf.setLayout(null); // 取消默认布局
// 文本域对象
JTextArea textArea = new JTextArea();
textArea.setBounds(10, 10, 360, 200);
jf.add(textArea);
// 文本框
JTextField text = new JTextField();
text.setBounds(10, 230, 180, 20);
jf.add(text);
// 发送按钮
JButton send = new JButton("发送");
send.setBounds(200, 230, 70, 20);
jf.add(send);
// 清空聊天按钮
JButton clear = new JButton("清空聊天");
clear.setBounds(280, 230, 100, 20);
jf.add(clear);
// 发送按钮绑定点击事件
send.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 获取文本框内容,去除首尾空格
String message = text.getText().trim();
// 如果字符串长度为0,代表为空
/*if (message.length() == 0) {
JOptionPane.showMessageDialog(jf, "你输入的内容不能为空!");
return ;
}
// 调用字符串类的isEmpty来判断,如果返回为true,代表为空
if (message.isEmpty()) {
JOptionPane.showMessageDialog(jf, "你输入的内容不能为空!");
return ;
}*/
// 如果字符串内容和""一样,代表为空
if ("".equals(message)) {
JOptionPane.showMessageDialog(jf, "你输入的内容不能为空!");
return ;
}
// 拼接到文本域,加一个换行
textArea.append(message + "\n");
// 清空文本框
text.setText("");
}
});
// 清空聊天按钮绑定点击事件
clear.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
// 清空文本域
textArea.setText("");
}
});
// 设置窗体可见
jf.setVisible(true);
}
}
八、基本类型包装类
基本类型包装类概述
String和基本数据类型之间不能直接进行相互转换,为了方便进行各种基本数据类型和字符串的相互转换,Java就提供了基本类型包装类。
小贴士:将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据。
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
Integer
Integer类在对象中包装基本类型int的值。
构造方法
- Integer(int value):根据int值创建Integer对象(过时)。
- Integer(String s):根据String值创建Integer对象(过时)。
成员方法
- static Interger valueOf(int i):返回表示指定的int值的Integer实例。
- static Integer valueOf(String s):返回一个保存指定值的Integer对象。
实例
package com.zzm;
/**
* 用途:IntegerDemo01
* 时间:2024/7/4 22:26
* 创建人:张子默
*/
/*
基本类型包装类
将基本类型封装成对象,好处是提供了方法操作数据
除了int是Integer,char是Character
其余都是首字母大写
byte -> Byte
short -> Short
* int -> Integer
long -> Long
float -> Float
double -> Double
* char -> Character
boolean -> Boolean
包装类常见操作
用于基本数据类型与字符串(引用数据类型)之间的转换
Integer狗仔方法(过时)
Integer(int value);
Integer(String str);
Integer静态方法(推荐)
static Integer valueOf(int value);返回指定int值的Integer对象
static Integer valueOf(String str);返回指定String值的Integer对象
*/
public class IntegerDemo01 {
public static void main(String[] args) {
/*
Integer构造方法(过时)
*/
// Integer(int value);
/*Integer i1 = new Integer(100);
System.out.println(i1);
// Integer(String str);
Integer i2 = new Integer("200");
System.out.println(i2);*/
/*
Integer静态方法(推荐)
valueOf(基本类型/字符串);
*/
// static Integer valueOf(int value);返回指定int值的Integer对象
Integer i1 = Integer.valueOf(100);
System.out.println(i1); // i1是对象,可以调动方法
// static Integer valueOf(String str);返回指定String值的Integer对象
Integer i2 = Integer.valueOf("200");
System.out.println(i2); // i2是对象,可以调用方法
// Integer i3 = Integer.valueOf("100a"); // 要传递纯数值,否则不能完成转换的!!!报错
// System.out.println(i3);
}
}
Int和String的相互转换
- static String valueOf(int i):返回int参数的字符串表示形式,该方法是String类中的方法。
- static int parseInt(String s):将字符串解析为int类型,该方法是Integer类中的方法。
实例
package com.zzm;
/**
* 用途:IntegerDemo02
* 时间:2024/7/4 23:21
* 创建人:张子默
*/
/*
Integer是完成String和int之间的转换
int -> String
方式1:空串+号拼接
方式2:static String valueOf(int i);
String -> int
static int parseInt(String s);
*/
public class IntegerDemo02 {
public static void main(String[] args) {
/*
int -> String
*/
// 方式1:空串+号拼接
int i = 100;
String s = i + "";
System.out.println(s);
// 方式2:static String valueOf(int i);
String ss = String.valueOf(100);
System.out.println(ss);
/*
String -> int
*/
// static int parseInt(String s);
int num = Integer.parseInt("888");
System.out.println(num); // 888
}
}
猜数字
package com.zzm;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
/**
* 用途:猜数字
* 时间:2024/7/6 21:02
* 创建人:张子默
*/
/*
1.系统产生一个1-100之间的随机数
2.猜的内容不能为空
3.每次根据猜的数给出相应的提示
*/
public class GuessNumber {
public static void main(String[] args) {
JFrame jf = new JFrame();
jf.setSize(400, 300);
jf.setTitle("猜数字"); // 设置窗体标题
jf.setLocationRelativeTo(null); // 设置窗体位置在中央弹出
jf.setDefaultCloseOperation(3); // 设置窗体关闭停止程序
jf.setAlwaysOnTop(true); // 设置窗体置顶
jf.setLayout(null); // 取消默认布局
// 文本对象
JLabel jLabel = new JLabel("系统产生了一个1-100的随机数,请猜一猜");
jLabel.setBounds(70, 50, 350, 20);
jf.add(jLabel);
// 文本框对象
JTextField jTextField = new JTextField();
jTextField.setBounds(120, 100, 150, 20);
jf.add(jTextField);
// 我猜按钮
JButton btn = new JButton("我猜");
btn.setBounds(150, 150, 100, 20);
jf.add(btn);
// 产生随机数,范围是1-100的整数
int randomNumber = new Random().nextInt(100) + 1;
// 给按钮添加点击事件
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 获取输入框中的数据
String guessNumber = jTextField.getText().trim();
// 非空判断
if ("".equals(guessNumber)) {
// 弹出错误提示框
JOptionPane.showMessageDialog(jf, "猜的数字不能为空!");
return ; // 结束方法
}
// 将获取到的String转为int
int number = Integer.parseInt(guessNumber);
// 判断数据关系
if (number < 1 || number > 100) {
JOptionPane.showMessageDialog(jf, "请输入1-100的整数!");
jTextField.setText(""); // 清空文本框
return ;
} else if (number > randomNumber) {
JOptionPane.showMessageDialog(jf, "猜大了!");
jTextField.setText("");
return ;
} else if (number < randomNumber) {
JOptionPane.showMessageDialog(jf, "猜小了!");
jTextField.setText("");
return ;
} else {
JOptionPane.showMessageDialog(jf, "恭喜你,猜中了!");
}
}
});
jf.setVisible(true); // 设置显示窗体(一般写在最后)
}
}
自动拆装箱
- 装箱把基本数据类型转换为对应的包装类类型。
- 拆箱:把包装类类型转换为对应的基本数据类型。
package com.zzm;
/**
* 用途:IntegerDemo03
* 时间:2024/7/6 20:56
* 创建人:张子默
*/
/*
自动拆装箱:
自动装箱:基本类型 -> 包装类
自动拆箱:包装类 -> 基本类型
*/
public class IntegerDemo03 {
public static void main(String[] args) {
// 自动装箱:基本类型 -> 包装类
Integer i = 100;
// 自动拆箱:包装类 -> 基本类型
int ii = i; // 底层自动调用intValue()
/*
分析案例
*/
Integer in= 200;
in += 100;
// in = in + 100;
// in = in.intValue() + 100; // 自动拆箱
// in = 300; // 自动装箱
}
}
十、日期与日期格式化
Date
Date类表示特定的时刻,精度为毫秒。
构造方法
- Date():分配Date对象并对其进行格式化,使其表示分配时间,测量Date到毫秒。
- Date(long date):分配Date对象并初始化它以表示自标准基准时间以来的毫秒数,即1970年1月1日00:00:00。
实例
package com.zzm;
import java.util.Date;
/**
* 用途:DateDemo01
* 时间:2024/7/6 22:49
* 创建人:张子默
*/
/*
Date类表示特定的时刻,单位为毫秒
时间换算公式
1秒 = 1000毫秒(常用)
1毫秒 = 1000微秒
1微秒 = 1000纳秒
时间原点的由来:1970年01月01日
1960年8月,贝尔实验室的程序员使用B语言在老旧的PDP-7机器上开发出了Unix的一个版本
随后改进了B语言,开发了C语言,重写了UNIX
所以认为1970年1月1日是C语言的生日,Java延续了这一传统
Date构造方法
Date():空参构造创建对象,代表当前系统时间
Date(long 毫秒值):带参构造创建对象,参数表示从时间原点开始,经过的毫秒值
注意:导包使用util包下的Date
*/
public class DateDemo01 {
public static void main(String[] args) {
// 空参创建Date对象 -> 系统时间 -> 常用
Date d1 = new Date();
System.out.println(d1); // Sat Jul 06 22:58:01 CST 2024
// 带参数创建Date对象 -> 设置时间 -> 不常用
Date d2 = new Date(0L); // 从时间原点,经历了0毫秒的时间节点 -> 就是时间原点
System.out.println(d2); // Thu Jan 01 08:00:00 CST 1970
// 带参创建Date对象 -> 设置时间 -> 不常用
Date d3 = new Date(60 * 60 * 1000L); // 从时间原点,经历了1个小时的时间节点 -> 60 * 60 * 1000
System.out.println(d3); // Thu Jan 01 09:00:00 CST 1970
}
}
获取当前事件毫秒值
package com.zzm;
import java.util.Date;
/**
* 用途:DateDemo02
* 时间:2024/7/6 23:02
* 创建人:张子默
*/
/*
Date类的getTime方法:获取Date对象封装的毫秒值
System类的currentTimeMillis方法:获取当前系统时间记录的毫秒值
*/
public class DateDemo02 {
public static void main(String[] args) {
// 创建日期对象,封装当前系统时间
Date d = new Date();
// getTime()获取Date对象封装的毫秒值(代表从时间原点到现在所经历的毫秒值)
long time = d.getTime();
System.out.println(time); // 1720278340016
// System类有一个方法currentTimeMillis(),也可以获取当前系统时间记录的毫秒值
long time2 = System.currentTimeMillis();
System.out.println(time2); // 1720278456990
// 毫秒值 / (24 * 60 * 60 * 1000) = 经历的天数
// 获取开始的时间节点
long start = System.currentTimeMillis(); // 小
String s = "";
for (int i = 1; i <= 50000; i++) {
// 完成5亿次字符串拼接 -> 4秒左右
s += i;
}
// 获取结束的时间节点
long end = System.currentTimeMillis(); // 大
// 计算某一段代码运行的时间
System.out.println(end - start); // 4071
}
}
SImpleDateFormat
- SimpleDateFormat是一个用于以区域设置敏感的方式格式化和解析日期的具体类。
- 日期和时间格式由日期和时间模式字符串指定,在日期和时间模式字符串中,从’A’到’Z’以及从’a’到’z’字母被解释为表示日期或时间字符串的组成部分模式字母。
常用模式字母 | 模式说明 |
---|---|
y | 年 |
M | 月 |
d | 日 |
H | 时 |
m | 分 |
s | 秒 |
构造方法
- SimpleDateFormat():构造一个SimpleDateFormat,使用默认模式和日期格式。
- SimpleDateFormat(String pattern):构造一个SimpleDateFormat使用给定的模式和默认的日期格式。
成员方法
- String format(Date date):将日期格式化成日期/时间字符串。
- Date parse(String source):从给定字符串解析文本以生成日期。
实例
package com.zzm;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 用途:DateDemo03
* 时间:2024/7/6 23:19
* 创建人:张子默
*/
/*
SimpleDateFormat可以对Date对象,进行格式化和解析
日期模式字符串中,字字母的对应关系
y 年
M 月
d 日
H 时
m 分
s 秒
SimpleDateFormat构造方法
public SimpleDateFormat();构造一个SimpleDateFormat对象,使用默认格式
public SimpleDateFormate(String 格式);构造一个SimpleDateFormat对象,使用指定格式
SimpleDateFormat成员方法
格式化:public String format(Date date);格式化为指定格式
解析:public Date parse(String source);从指定格式解析为日期对象
*/
public class DateDemo03 {
public static void main(String[] args) throws ParseException {
// Date -> String
// 创建日期对象
Date date = new Date();
// 创建日期格式化对象
// SimpleDateFormat sdf = new SimpleDateFormat(); // 空参,默认格式
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); // 带参,指定格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 带参,指定格式
// 格式化
String s = sdf.format(date);
System.out.println(s);
/*
空参,默认格式 2024/07/06 下午23:32
带参,指定格式1 2024年07月06日 23:32:40
带参,指定格式2 2024-07-06 23:32:40
*/
System.out.println("---------------------------");
// String -> Date
// 被解析的字符串(包含年月日时分秒的,一般是别人给我们的)
String str = "2024年07月06日 23:35:29";
// 创建日期格式化对象,给出的格式必须和字符串中保持一致,否则报错!
// SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 报一个解析异常
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
// 解析
Date d = sdf2.parse(str); // 报错: Alt+回车,选择Add..敲回车
System.out.println(d); // Sat Jul 06 23:35:29 CST 2024
}
}
手机日期和时间显示实现
package com.zzm;
import javax.swing.*;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 用途:手机日期和时间显示
* 时间:2024/6/23 20:49
* 创建人:张子默
*/
/*
将xxxx年xx月xx日和xx:xx改为动态获取
*/
public class ShowDateTime {
public static void main(String[] args) {
// 创建窗体对象
JFrame jf = new JFrame();
jf.setTitle("手机日期和时间显示");
jf.setSize(400, 300);
jf.setDefaultCloseOperation(3);
jf.setLocationRelativeTo(null);
jf.setAlwaysOnTop(true);
jf.setLayout(null);
// 提示日期
JLabel dateLabel = new JLabel("日期");
dateLabel.setBounds(50, 50, 100, 20);
jf.add(dateLabel);
// 获取日期的字符串
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
// 格式化当前系统时间 -> 只取了日期
String dateStr = dateFormat.format(new Date());
// 按照格式显示日期的字符串
JLabel showDateLabel = new JLabel(dateStr);
showDateLabel.setBounds(50, 80, 200, 20);
jf.add(showDateLabel);
// 提示时间
JLabel timeLabel = new JLabel();
timeLabel.setBounds(50, 150, 100, 20);
jf.add(timeLabel);
// 获取时间字符串
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
// 格式化当前系统时间 -> 只取时间
String timeStr = timeFormat.format(new Date());
// 按照格式显示时间的字符串
JLabel showTimeLabel = new JLabel(timeStr);
showTimeLabel.setBounds(50, 180, 200, 20);
jf.add(showTimeLabel);
jf.setVisible(true);
}
}
考勤查询
package com.zzm;
import javax.swing.*;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import java.awt.*;
import java.awt.event.*;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.*;
/*
日期选择器,可以指定日期的显示格式
*/
public class DateChooser extends JPanel {
private static final long serialVersionUID = 4529266044762990227L;
private Date initDate;
private Calendar now = Calendar.getInstance();
private Calendar select;
private JPanel monthPanel;// 月历
private JP1 jp1;// 四块面板,组成
private JP2 jp2;
private JP3 jp3;
private JP4 jp4;
private Font font = new Font("宋体", Font.PLAIN, 12);
private final LabelManager lm = new LabelManager();
private SimpleDateFormat sdf;
private boolean isShow = false;
private Popup pop;
private JComponent showDate;
public static DateChooser getInstance() {
return new DateChooser();
}
public static DateChooser getInstance(Date date) {
return new DateChooser(date);
}
public static DateChooser getInstance(String format) {
return new DateChooser(format);
}
public static DateChooser getInstance(Date date, String format) {
return new DateChooser(date, format);
}
/**
* Creates a new instance of DateChooser
*/
private DateChooser() {
this(new Date());
}
private DateChooser(Date date) {
this(date, "yyyy年MM月dd日");
}
private DateChooser(String format) {
this(new Date(), format);
}
private DateChooser(Date date, String format) {
initDate = date;
sdf = new SimpleDateFormat(format);
select = Calendar.getInstance();
select.setTime(initDate);
initPanel();
}
/**
* 是否允许用户选择
*/
public void setEnabled(boolean b) {
super.setEnabled(b);
showDate.setEnabled(b);
}
/**
* 得到当前选择框的日期
*/
public Date getDate() {
return select.getTime();
}
public String getStrDate() {
return sdf.format(select.getTime());
}
public String getStrDate(String format) {
sdf = new SimpleDateFormat(format);
return sdf.format(select.getTime());
}
// 根据初始化的日期,初始化面板
private void initPanel() {
monthPanel = new JPanel(new BorderLayout());
monthPanel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
JPanel up = new JPanel(new BorderLayout());
up.add(jp1 = new JP1(), BorderLayout.NORTH);
up.add(jp2 = new JP2(), BorderLayout.CENTER);
monthPanel.add(jp3 = new JP3(), BorderLayout.CENTER);
monthPanel.add(up, BorderLayout.NORTH);
monthPanel.add(jp4 = new JP4(), BorderLayout.SOUTH);
this.addAncestorListener(new AncestorListener() {
public void ancestorAdded(AncestorEvent event) {
}
public void ancestorRemoved(AncestorEvent event) {
}
// 只要祖先组件一移动,马上就让popup消失
public void ancestorMoved(AncestorEvent event) {
hidePanel();
}
});
}
public void register(final JComponent showDate) {
this.showDate = showDate;
showDate.setRequestFocusEnabled(true);
showDate.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
showDate.requestFocusInWindow();
}
});
this.setBackground(Color.WHITE);
this.add(showDate, BorderLayout.CENTER);
this.setPreferredSize(new Dimension(90, 25));
this.setBorder(BorderFactory.createLineBorder(Color.GRAY));
showDate.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
if (showDate.isEnabled()) {
showDate.setCursor(new Cursor(Cursor.HAND_CURSOR));
showDate.setForeground(Color.RED);
}
}
public void mouseExited(MouseEvent me) {
if (showDate.isEnabled()) {
showDate.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
showDate.setForeground(Color.BLACK);
}
}
public void mousePressed(MouseEvent me) {
if (showDate.isEnabled()) {
showDate.setForeground(Color.CYAN);
if (isShow) {
hidePanel();
} else {
showPanel(showDate);
}
}
}
public void mouseReleased(MouseEvent me) {
if (showDate.isEnabled()) {
showDate.setForeground(Color.BLACK);
}
}
});
showDate.addFocusListener(new FocusListener() {
public void focusLost(FocusEvent e) {
hidePanel();
}
public void focusGained(FocusEvent e) {
}
});
}
// 根据新的日期刷新
private void refresh() {
jp1.updateDate();
jp2.updateDate();
jp3.updateDate();
jp4.updateDate();
SwingUtilities.updateComponentTreeUI(this);
}
// 提交日期
private void commit() {
// TODO add other components here
if (showDate instanceof JTextField) {
((JTextField) showDate).setText(sdf.format(select.getTime()));
} else if (showDate instanceof JLabel) {
((JLabel) showDate).setText(sdf.format(select.getTime()));
}
hidePanel();
}
// 隐藏日期选择面板
private void hidePanel() {
if (pop != null) {
isShow = false;
pop.hide();
pop = null;
}
}
// 显示日期选择面板
private void showPanel(Component owner) {
if (pop != null) {
pop.hide();
}
Point show = new Point(0, showDate.getHeight());
SwingUtilities.convertPointToScreen(show, showDate);
Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
int x = show.x;
int y = show.y;
if (x < 0) {
x = 0;
}
if (x > size.width - 295) {
x = size.width - 295;
}
if (y < size.height - 170) {
} else {
y -= 188;
}
pop = PopupFactory.getSharedInstance()
.getPopup(owner, monthPanel, x, y);
pop.show();
isShow = true;
}
/**
* 最上面的面板用来显示月份的增减
*/
private class JP1 extends JPanel {
private static final long serialVersionUID = -5638853772805561174L;
JLabel yearleft, yearright, monthleft, monthright, center,
centercontainer;
public JP1() {
super(new BorderLayout());
this.setBackground(new Color(160, 185, 215));
initJP1();
}
private void initJP1() {
yearleft = new JLabel(" <<", JLabel.CENTER);
yearleft.setToolTipText("上一年");
yearright = new JLabel(">> ", JLabel.CENTER);
yearright.setToolTipText("下一年");
yearleft.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
yearright.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
monthleft = new JLabel(" <", JLabel.RIGHT);
monthleft.setToolTipText("上一月");
monthright = new JLabel("> ", JLabel.LEFT);
monthright.setToolTipText("下一月");
monthleft.setBorder(BorderFactory.createEmptyBorder(2, 30, 0, 0));
monthright.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 30));
centercontainer = new JLabel("", JLabel.CENTER);
centercontainer.setLayout(new BorderLayout());
center = new JLabel("", JLabel.CENTER);
centercontainer.add(monthleft, BorderLayout.WEST);
centercontainer.add(center, BorderLayout.CENTER);
centercontainer.add(monthright, BorderLayout.EAST);
this.add(yearleft, BorderLayout.WEST);
this.add(centercontainer, BorderLayout.CENTER);
this.add(yearright, BorderLayout.EAST);
this.setPreferredSize(new Dimension(295, 25));
updateDate();
yearleft.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
yearleft.setCursor(new Cursor(Cursor.HAND_CURSOR));
yearleft.setForeground(Color.RED);
}
public void mouseExited(MouseEvent me) {
yearleft.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
yearleft.setForeground(Color.BLACK);
}
public void mousePressed(MouseEvent me) {
select.add(Calendar.YEAR, -1);
yearleft.setForeground(Color.WHITE);
refresh();
}
public void mouseReleased(MouseEvent me) {
yearleft.setForeground(Color.BLACK);
}
});
yearright.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
yearright.setCursor(new Cursor(Cursor.HAND_CURSOR));
yearright.setForeground(Color.RED);
}
public void mouseExited(MouseEvent me) {
yearright.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
yearright.setForeground(Color.BLACK);
}
public void mousePressed(MouseEvent me) {
select.add(Calendar.YEAR, 1);
yearright.setForeground(Color.WHITE);
refresh();
}
public void mouseReleased(MouseEvent me) {
yearright.setForeground(Color.BLACK);
}
});
monthleft.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
monthleft.setCursor(new Cursor(Cursor.HAND_CURSOR));
monthleft.setForeground(Color.RED);
}
public void mouseExited(MouseEvent me) {
monthleft.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
monthleft.setForeground(Color.BLACK);
}
public void mousePressed(MouseEvent me) {
select.add(Calendar.MONTH, -1);
monthleft.setForeground(Color.WHITE);
refresh();
}
public void mouseReleased(MouseEvent me) {
monthleft.setForeground(Color.BLACK);
}
});
monthright.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
monthright.setCursor(new Cursor(Cursor.HAND_CURSOR));
monthright.setForeground(Color.RED);
}
public void mouseExited(MouseEvent me) {
monthright.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
monthright.setForeground(Color.BLACK);
}
public void mousePressed(MouseEvent me) {
select.add(Calendar.MONTH, 1);
monthright.setForeground(Color.WHITE);
refresh();
}
public void mouseReleased(MouseEvent me) {
monthright.setForeground(Color.BLACK);
}
});
}
private void updateDate() {
center.setText(select.get(Calendar.YEAR) + "年"
+ (select.get(Calendar.MONTH) + 1) + "月");
}
}
private class JP2 extends JPanel {
private static final long serialVersionUID = -8176264838786175724L;
public JP2() {
this.setPreferredSize(new Dimension(295, 20));
}
protected void paintComponent(Graphics g) {
g.setFont(font);
g.drawString("星期日 星期一 星期二 星期三 星期四 星期五 星期六", 5, 10);
g.drawLine(0, 15, getWidth(), 15);
}
private void updateDate() {
}
}
private class JP3 extends JPanel {
private static final long serialVersionUID = 43157272447522985L;
public JP3() {
super(new GridLayout(6, 7));
this.setPreferredSize(new Dimension(295, 100));
initJP3();
}
private void initJP3() {
updateDate();
}
public void updateDate() {
this.removeAll();
lm.clear();
Date temp = select.getTime();
Calendar select = Calendar.getInstance();
select.setTime(temp);
select.set(Calendar.DAY_OF_MONTH, 1);
int index = select.get(Calendar.DAY_OF_WEEK);
int sum = (index == 1 ? 8 : index);
select.add(Calendar.DAY_OF_MONTH, 0 - sum);
for (int i = 0; i < 42; i++) {
select.add(Calendar.DAY_OF_MONTH, 1);
lm.addLabel(new MyLabel(select.get(Calendar.YEAR), select
.get(Calendar.MONTH), select.get(Calendar.DAY_OF_MONTH)));
}
for (MyLabel my : lm.getLabels()) {
this.add(my);
}
select.setTime(temp);
}
}
private class MyLabel extends JLabel implements Comparator<MyLabel>,
MouseListener, MouseMotionListener {
private static final long serialVersionUID = 3668734399227577214L;
private int year, month, day;
private boolean isSelected;
public MyLabel(int year, int month, int day) {
super("" + day, JLabel.CENTER);
this.year = year;
this.day = day;
this.month = month;
this.addMouseListener(this);
this.addMouseMotionListener(this);
this.setFont(font);
if (month == select.get(Calendar.MONTH)) {
this.setForeground(Color.BLACK);
} else {
this.setForeground(Color.LIGHT_GRAY);
}
if (day == select.get(Calendar.DAY_OF_MONTH)) {
this.setBackground(new Color(160, 185, 215));
} else {
this.setBackground(Color.WHITE);
}
}
public boolean getIsSelected() {
return isSelected;
}
public void setSelected(boolean b, boolean isDrag) {
isSelected = b;
if (b && !isDrag) {
int temp = select.get(Calendar.MONTH);
select.set(year, month, day);
if (temp == month) {
SwingUtilities.updateComponentTreeUI(jp3);
} else {
refresh();
}
}
this.repaint();
}
protected void paintComponent(Graphics g) {
if (day == select.get(Calendar.DAY_OF_MONTH)
&& month == select.get(Calendar.MONTH)) {
// 如果当前日期是选择日期,则高亮显示
g.setColor(new Color(160, 185, 215));
g.fillRect(0, 0, getWidth(), getHeight());
}
if (year == now.get(Calendar.YEAR)
&& month == now.get(Calendar.MONTH)
&& day == now.get(Calendar.DAY_OF_MONTH)) {
// 如果日期和当前日期一样,则用红框
Graphics2D gd = (Graphics2D) g;
gd.setColor(Color.RED);
Polygon p = new Polygon();
p.addPoint(0, 0);
p.addPoint(getWidth() - 1, 0);
p.addPoint(getWidth() - 1, getHeight() - 1);
p.addPoint(0, getHeight() - 1);
gd.drawPolygon(p);
}
if (isSelected) {// 如果被选中了就画出一个虚线框出来
Stroke s = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE,
BasicStroke.JOIN_BEVEL, 1.0f,
new float[]{2.0f, 2.0f}, 1.0f);
Graphics2D gd = (Graphics2D) g;
gd.setStroke(s);
gd.setColor(Color.BLACK);
Polygon p = new Polygon();
p.addPoint(0, 0);
p.addPoint(getWidth() - 1, 0);
p.addPoint(getWidth() - 1, getHeight() - 1);
p.addPoint(0, getHeight() - 1);
gd.drawPolygon(p);
}
super.paintComponent(g);
}
public boolean contains(Point p) {
return this.getBounds().contains(p);
}
private void update() {
repaint();
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
isSelected = true;
update();
}
public void mouseReleased(MouseEvent e) {
Point p = SwingUtilities.convertPoint(this, e.getPoint(), jp3);
lm.setSelect(p, false);
commit();
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
Point p = SwingUtilities.convertPoint(this, e.getPoint(), jp3);
lm.setSelect(p, true);
}
public void mouseMoved(MouseEvent e) {
}
public int compare(MyLabel o1, MyLabel o2) {
Calendar c1 = Calendar.getInstance();
c1.set(o1.year, o2.month, o1.day);
Calendar c2 = Calendar.getInstance();
c2.set(o2.year, o2.month, o2.day);
return c1.compareTo(c2);
}
}
private class LabelManager {
private List<MyLabel> list;
public LabelManager() {
list = new ArrayList<MyLabel>();
}
public List<MyLabel> getLabels() {
return list;
}
public void addLabel(MyLabel my) {
list.add(my);
}
public void clear() {
list.clear();
}
@SuppressWarnings("unused")
public void setSelect(MyLabel my, boolean b) {
for (MyLabel m : list) {
if (m.equals(my)) {
m.setSelected(true, b);
} else {
m.setSelected(false, b);
}
}
}
public void setSelect(Point p, boolean b) {
// 如果是拖动,则要优化一下,以提高效率
if (b) {
// 表示是否能返回,不用比较完所有的标签,能返回的标志就是把上一个标签和
// 将要显示的标签找到了就可以了
boolean findPrevious = false, findNext = false;
for (MyLabel m : list) {
if (m.contains(p)) {
findNext = true;
if (m.getIsSelected()) {
findPrevious = true;
} else {
m.setSelected(true, b);
}
} else if (m.getIsSelected()) {
findPrevious = true;
m.setSelected(false, b);
}
if (findPrevious && findNext) {
return;
}
}
} else {
MyLabel temp = null;
for (MyLabel m : list) {
if (m.contains(p)) {
temp = m;
} else if (m.getIsSelected()) {
m.setSelected(false, b);
}
}
if (temp != null) {
temp.setSelected(true, b);
}
}
}
}
private class JP4 extends JPanel {
private static final long serialVersionUID = -6391305687575714469L;
public JP4() {
super(new BorderLayout());
this.setPreferredSize(new Dimension(295, 20));
this.setBackground(new Color(160, 185, 215));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
final JLabel jl = new JLabel("今天: " + sdf.format(new Date()));
jl.setToolTipText("点击选择今天日期");
this.add(jl, BorderLayout.CENTER);
jl.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
jl.setCursor(new Cursor(Cursor.HAND_CURSOR));
jl.setForeground(Color.RED);
}
public void mouseExited(MouseEvent me) {
jl.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
jl.setForeground(Color.BLACK);
}
public void mousePressed(MouseEvent me) {
jl.setForeground(Color.WHITE);
select.setTime(new Date());
refresh();
commit();
}
public void mouseReleased(MouseEvent me) {
jl.setForeground(Color.BLACK);
}
});
}
private void updateDate() {
}
}
public static void main(String[] args) {
//创建窗体
JFrame jf = new JFrame();
//设置窗体大小
jf.setSize(400, 300);
//设置窗体标题
jf.setTitle("日历控件");
//设置位置,值为null,则窗体位于屏幕中央
jf.setLocationRelativeTo(null);
//设置窗体关闭时默认操作,窗口关闭时退出应用程序
jf.setDefaultCloseOperation(3);
//设置此窗口是否应始终位于其他窗口之上
jf.setAlwaysOnTop(true);
//取消窗体默认布局:窗体对象.setLayout(null);
jf.setLayout(null);
//创建日期选择器对象,指定日期字符串格式
DateChooser dateChooser = DateChooser.getInstance("yyyy-MM-dd");
JTextField showDateField = new JTextField("单击选择日期");
showDateField.setBounds(50, 50, 100, 20);
//把日历控件和文本框进行绑定
dateChooser.register(showDateField);
jf.add(showDateField);
jf.setVisible(true);
}
}
package com.zzm;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 用途:考勤查询
* 时间:2024/6/23 21:16
* 创建人:张子默
*/
/*
用日历控件,改进考勤查询的日期字符串格式
日期控件使用步骤:
1.创建日期选择器对象,指定日期字符串格式
DateChooser dateChooser = DateChooser.getInstance("yyyy-MM-dd");
2.文本框对象
JTextField showDateField = new JTextField("单击选择日期");
showDateField.setBounds(50, 50, 100, 20);
3.把日历控件和文本框进行绑定
dateChooser.register(showDateField);
*/
public class AttendanceQuery {
public static void main(String[] args) {
// 创建窗体对象
JFrame jf = new JFrame();
jf.setTitle("考勤查询");
jf.setSize(400, 300);
jf.setDefaultCloseOperation(3);
jf.setLocationRelativeTo(null);
jf.setAlwaysOnTop(true);
jf.setLayout(null);
// 显示考勤日期的文本
JLabel dateLabel = new JLabel("考勤日期");
dateLabel.setBounds(50, 20, 100, 20);
jf.add(dateLabel);
// 显示开始时间文本
JLabel startDateLabel = new JLabel("开始时间");
startDateLabel.setBounds(50, 70, 100, 20);
jf.add(startDateLabel);
DateChooser dateChooser1 = DateChooser.getInstance("yyyy/MM/dd");
DateChooser dateChooser2 = DateChooser.getInstance("yyyy/MM/dd");
// 开始时间输入框
JTextField startDateField = new JTextField();
startDateField.setBounds(50, 100, 100, 20);
dateChooser1.register(startDateField);
jf.add(startDateField);
// 显示结束时间文本
JLabel endDateLabel = new JLabel("结束时间");
endDateLabel.setBounds(250, 70, 100, 20);
jf.add(endDateLabel);
// 结束时间输入框
JTextField endDateField = new JTextField();
endDateField.setBounds(250, 100, 100, 20);
dateChooser2.register(endDateField);
jf.add(endDateField);
// 确定按钮
JButton confirmButton = new JButton("确定");
confirmButton.setBounds(250, 180, 60, 20);
jf.add(confirmButton);
// 给确定按钮加入点击事件
confirmButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 定义日期格式化对象 -> 解析 -> 格式要和字符串一致
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
// 分别获取文本框的开始时间和结束时间
String startTimeStr = startDateField.getText();
String endTimeStr = endDateField.getText();
try {
// 分别解析两个字符串,得到两个Date对象
Date startDate = sdf.parse(startTimeStr);
Date endDate = sdf.parse(endTimeStr);
// 弹框打印Date对象 -> 加了一个换行
JOptionPane.showMessageDialog(jf, startDate + "\n" + endDate);
} catch (ParseException ex) {
throw new RuntimeException(ex);
}
}
});
jf.setVisible(true);
}
}
十一、练习
-
String类中replace方法的作用是?并举例说明
答: replace(旧子串,新子串); 该方法接收两个参数,使用新子串替换所有的旧子串,并返回新的字符串 System.out.println("你TMD真是个人才".replace("TMD", "***")); //你***真是个人才
-
String类中trim方法的作用是?并举例说明
答: 去除该字符串首尾的空格,并返回新的字符串 System.out.println(" 123 ".trim()); //123
-
String类中length方法的作用是?并举例说明
答: 返回字符串长度,也就是包含字符的个数 System.out.println("12345".length()); //5
-
String类中toCharArray方法的作用是?并举例说明
答: 将该字符串转为对应的字符数组,返回字符数组 char[] chars = "abc".toCharArray(); //遍历数组chars查看结果
-
Integer类中parseInt方法的作用是?
答: 将字符串类型,解析为int类型 如果该字符串包含除了数字外的其他字符,则会报NumberFormatException异常 int i1 = Integer.parseInt("100"); //转换成功 int i2 = Integer.parseInt("123adb"); //NumberFormatException
-
Date类中getTime方法的作用是?
答: 获取从时间原点开始,至今经历的毫秒值 Date d = new Date(); System.out.println(d.getTime()); //1651331634385 可以转换为天数 System.out.println(d.getTime() / 24 / 60 / 60 /1000); //从时间原点至今经历的天数为19112天
-
SimpleDateFormat类中format方法的作用是?
答: 将Date对象,通过指定格式,格式化为String类型 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date d = new Date(); //当前时间 String format = sdf.format(d); System.out.println(format); //2022-04-30 23:23:23
-
SimpleDateFormat类中parse方法的作用是?
答: 将包含日期的字符串,通过指定格式,解析为Date对象 parse方法有异常,Alt+回车抛出即可 SimpleDateFormat带参构造的参数为解析格式,如果格式不匹配会报ParseException异常 public static void main(String[] args) throws ParseException { String s = "2022-04-30 23:18:25"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = sdf.parse(s); System.out.println(date); //Sat Apr 30 23:23:23 CST 2022 }
由于本人是在业余时间整理,所以进度比较缓慢,各章节将持续更新,敬请等待…