Java Swing 开发总结汇总贴
文章目录
1. Java GUI 开发思路
a. 程序的编写
IDEA + Swing + JFormDesigner(可视化开发插件)
eclipse + Swing + WindowBuilder(可视化开发插件)
IDEA + JavaFX + SceneBuilder(可视化开发插件)
b. 项目打包封装成exe程序
先在IDE中将项目打包成 jar 包,再通过 exe4j 将 jar 包转换成exe可执行文件
c. 项目发布到GitHub上
其中的一种步骤:
1、在浏览器端登录GitHub账号
2、点击’New Repository’创建一个新的仓库
3、在电脑端打开 git-bash (需要事先在电脑上安装好Git)
4、在终端中通过 cd 命令切换到项目根目录下
5、进行初始化:git init
6、将本目录下的所有文件添加到 git 管理:git add .
7、提交本地仓库:git commit -m “备注”
8、关联到Github上:git remote add origin https://仓库地址
9、将本地代码提交至GitHub:git push -u origin master
2. 监听器Listener的三种写法
通过实际项目来进行说明
Demo类
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Date;
//监听器Listener的三种写法:内部类、匿名内部类、Lambda表达式
/**
* Demo为自定义类,继承父类JFrame
* showTime()为自定义函数
**/
public class Demo extends JFrame
{
//创建了一个标签类的成员变量label,文本内容显示"00:00:00"
JLabel label = new JLabel("00:00:00"); //父类的属性,可被内部类访问
public Demo() {
super();
//创建并设置容器panel
JPanel panel = new JPanel();
this.setContentPane(panel);
//创建按钮并将其添加到容器panel中
JButton button1 = new JButton("按钮1");
panel.add(button1);
JButton button2 = new JButton("按钮2");
panel.add(button2);
JButton button3 = new JButton("按钮3");
panel.add(button3);
//将label添加到容器panel中
panel.add(label);
//文本框的创建,文本框设置为20个英文字母的宽度,将其添加到容器中
JTextField textField = new JTextField(20);
panel.add(textField);
//文本框显示内容的设置
textField.setText("Hello World");
//button1、2、3实现的功能是一样的
//按钮button1事件-内部类:
MyActionListener listener = new MyActionListener();
button1.addActionListener(listener);
//按钮button2事件-匿名内部类:
button2.addActionListener(new ActionListener()
{
@Override //实现方法
public void actionPerformed(ActionEvent e) {
showTime();
}
});
//按钮button3事件-lambda表达式:
button3.addActionListener( (selfDefine) -> { showTime(); } );
}
//MyActionListener是子类,也是内部类,ActionListener是接口,接口类不直接使用,要派生出一个子类
private class MyActionListener implements ActionListener
{
@Override //实现方法
public void actionPerformed(ActionEvent e) {
showTime();
}
}
//自定义函数用于显示系统时间
public void showTime()
{
SimpleDateFormat date = new SimpleDateFormat("HH:mm:ss");
//获取当前系统时间并格式化存储在timeStr中
String timeStr = date.format(new Date());
System.out.println(timeStr);
//标签label文本内容显示字符串timeStr的内容,即显示系统时间
label.setText(timeStr);
}
}
main类
import javax.swing.*;
public class main {
//该程序采用Java Swing进行开发,IDE为IntelliJ IDEA 2021.1
public static void main(String[] args)
{
//JFrame指一个窗口,构造方法的参数为窗口标题
JFrame frame = new Demo(); //多态
Demo demo = new Demo();
//设置窗口标题
frame.setTitle("Demo");
//设置窗口大小
frame.setSize(830,355);
//固定窗口大小
frame.setResizable(false);
//当关闭窗口时,退出整个程序
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//显示窗口
frame.setVisible(true);
}
}
3. Swing开发过程中文件、文件夹的处理问题
通过实际项目来进行说明
Demo类,再加上上述mian类才能作为一个完整的程序运行
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
/**
* Demo为自定义类,继承父类JFrame
* 假设演示所用文件为XXX.txt
* 绝对路径为C:\Users\XXX.txt
**/
public class Demo extends JFrame {
//用于文件、文件夹的信息存储
String fileContent;
String filename;
String path;
String frontPath;
String extension;
//用于文件名的存储
String[] fileNames;
//用于文件绝对路径的存储
String[] dirFilePath;
//用于一层文件夹中文件内容的存储
String[] fileTexts;
public Demo() {
super();
//创建并设置容器panel
JPanel panel = new JPanel();
this.setContentPane(panel);
//创建按钮并将其添加到容器panel中
JButton button1 = new JButton("打开文件");
panel.add(button1);
JButton button2 = new JButton("打开文件夹");
panel.add(button2);
//打开文件事件-lambda表达式
button1.addActionListener(e -> fileOpen());
//打开文件夹事件-lambda表达式
button2.addActionListener(e -> dirOpen());
}
//====================文件处理======================
/**
* 从给定路径path中读取文件(读取字符流)
* @param path String 绝对路径
* @return str String 从文件中读取的内容
**/
public String readFile(String path){
FileReader reader = null;
String str = null;
try {
reader = new FileReader(path);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int len = 0;
//通过buffer一次读取一个数组,数组要设置的大一些
char[] buffer = new char[102400];
while (true){
try {
if (!((len = reader.read(buffer)) != -1)) break;
} catch (IOException e) {
e.printStackTrace();
}
//将字符数组转换成字符串
str = new String(buffer,0,len);
}
System.out.println(str);
try {
reader.close(); //释放资源
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
/**
* 将字符串中的内容写到指定路径的文件中(输出字符流)
* @param str String 字符串str中的内容
* @param path String 绝对路径
**/
public void writeFile(String str,String path){
FileWriter writer;
try {
writer = new FileWriter(path);
writer.write(str);
writer.flush(); //清空缓冲区
writer.close(); //释放资源
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
public void fileOpen(){
//创建一个JFrame组件为parent组件
JFrame file1 = new JFrame("选择文件");
//创建文件选择器
JFileChooser choosers = new JFileChooser();
//设置为只能选文件
choosers.setFileSelectionMode(JFileChooser.FILES_ONLY);
//默认一次只能选择一个文件,参数改为"true"后可选择多个文件
choosers.setMultiSelectionEnabled(true);
//弹出选择文件对话框
int flag = choosers.showOpenDialog(file1);
if(flag == JFileChooser.APPROVE_OPTION) {
//获取文件的名称
filename = choosers.getSelectedFile().getName();
//获取选择文件的路径
path = choosers.getSelectedFile().getPath();
//获取文件的扩展名
extension = path.substring(path.lastIndexOf('.'));
//获取文件名之前的路径
frontPath = path.substring(0, path.lastIndexOf('\\')); //需要对'\'进行转义表示
//XXX.txt
System.out.println("用户选择了文件:" + filename);
//C:\Users\XXX.txt
System.out.println("文件绝对路径:" + path);
//C:\Users
System.out.println("文件路径:" + frontPath);
//.txt
System.out.println("文件扩展名:" + extension);
//从源文件中读取字符流,存为字符串
fileContent = readFile(path);
//将读到的字符流写入文本文档中,在"."之前插入字符串"_Src","_Src"为自定义标识
StringBuilder sb = new StringBuilder(filename);
//C:\Users\XXX_Src.txt
writeFile(fileContent, frontPath+"\\"+sb.insert(sb.indexOf("."),"_Src"));
}
}
//==========================文件夹处理============================
public void dirOpen(){
//创建一个JFrame组件为parent组件
JFrame file2 = new JFrame("选择文件");
//创建文件选择器
JFileChooser choosers = new JFileChooser();
//设置为只能选文件
choosers.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
//默认一次只能选择一个文件夹,参数改为"true"后可选择多个文件夹
choosers.setMultiSelectionEnabled(true);
//弹出选择文件对话框
int flag = choosers.showOpenDialog(file2);
if(flag == JFileChooser.APPROVE_OPTION) {
//获取文件夹的名称
filename = choosers.getSelectedFile().getName();
//获取选择文件夹的路径
path = choosers.getSelectedFile().getPath();
frontPath = path.substring(0, path.lastIndexOf('\\'));
//Users
System.out.println("用户选择了文件夹:" + filename);
//C:\\Users
System.out.println("文件夹绝对路径:" + path);
//获取文件夹下的所有文件
// 只能获取一层文件夹下的所有文件,且该文件夹内没有其它文件夹,否则会报错(描述1)
File fi = choosers.getSelectedFile();
File[] files = fi.listFiles();
//将目录下的所有文件名称及文件地址存储到列表中
List<String> listF = new ArrayList<>();
List<String> listP = new ArrayList<>();
for (File file : files) {
System.out.println(file.getName());
listF.add(file.getName());
listP.add(path + "\\" + file.getName());
}
//将列表中的内容存到字符串数组中
fileNames = listF.toArray(new String[listF.size()]);
dirFilePath = listP.toArray(new String[listP.size()]);
//在所选文件夹的路径下创建目录DES,如果没有目录DES则新建一个
File dir = new File(path+"\\Demo");
if(!dir.exists()){
dir.mkdir();
}
//必须先实例化,否则会触发空指针异常:
//"Cannot invoke "java.util.List.add(Object)" because "this.texts" is null"
List<String> texts = new ArrayList<>();
//循环处理遍历得到的文件
for (int i = 0; i < dirFilePath.length; i++) {
//注意,写代码时fileNames[i]写为fileName会报错
StringBuilder sb = new StringBuilder(fileNames[i]);
//得到文件的绝对路径
System.out.println(dirFilePath[i]);
//"XXX.txt变为XXX_Src.txt"
String temp = String.valueOf(sb.insert(sb.indexOf("."), "_Src"));
//字符串连接得到新文件的绝对路径
String newFileAbsolute =
dirFilePath[i].substring(0, dirFilePath[i].lastIndexOf('\\')) + "\\Demo\\" + temp;
System.out.println("新文件名:"+temp);
System.out.println("新文件的绝对路径:"+newFileAbsolute);
//将读取到的字符流存储到列表中
fileContent = null;
fileContent = readFile(dirFilePath[i]);
texts.add(fileContent);
//将读到的字符流写到新文件中
writeFile(fileContent, newFileAbsolute);
}
//将列表中的内容存到字符串数组中
fileTexts = texts.toArray(new String[texts.size()]);
}
}
}
4. 测试某块代码的运行时间
//在程序可视化界面上显示某部分代码的运行时间
long stime; //开始时间
long etime; //结束时间
stime = etime = 0;
//系统纳秒计时
stime = System.nanoTime();
yourSelfDefine(); //需要测试的函数
etime = System.nanoTime();
//计算代码执行时间,加上单位“毫秒”,并将结果显示在标签label上
label.setText((etime - stime) / 10E6 +" 毫秒");
5. BigInteger 大整数类的使用
注:以下内容的变量之间相互关联
//String 转换为 BigInteger
String str = "12306";
BigInteger e = new BigInteger(str);
//假设里面已存有若干组大整数
BigInteger[] cipher;
//将得到的大整数类数组(cipher)转换为字符串数组(tempStr)形式进行存储
String[] tempStr;
List<String> tempList = new ArrayList<>();
for (int i = 0; i < cipher.length; i++) {
tempList.add(String.valueOf(cipher[i]));
}
//注:如果tempStr之前存有内容,该句会将内容清空然后存入tempList中的内容
tempStr = tempList.toArray(new String[tempList.size()]);
//文件按行写入
FileWriter writer;
try {
//这里的filePath指要写入文件的绝对路径
writer = new FileWriter(filePath);
BufferedWriter bw = new BufferedWriter(writer);
//可以是j < tempStr.length-1
for (int j = 0; j < cipher.length; j++) {
bw.write(tempStr[j]);
bw.newLine(); //换行
bw.flush(); //清空缓冲区
}
writer.flush(); //清空缓冲区
writer.close(); //释放资源
} catch (IOException ioException) {
ioException.printStackTrace();
}
//按行读取读取文件,存入字符串数组中
List<String> readLine = new ArrayList<>();
try {
FileReader reader = new FileReader(filePath);
BufferedReader br = new BufferedReader(reader);
while (true) {
try {
String temp = br.readLine();
readLine.add(temp);
if (temp == null)
break;
} catch (IOException e) {
e.printStackTrace();
}
}
try {
br.close();
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String[] temp1;
temp1 = readLine.toArray(new String[readLine.size()]);
//将String数组中的内容存到BigInteger数组中
for (int k = 0; k < cipher.length; k++) {
//String转BigInteger
cipher[k] = new BigInteger(temp1[k]);
}
//注意!此句指申请一个长度为0的数组,需要进行清空数组的操作时要注意申请数组的空间问题
cipher = new BigInteger[0]; //会报错,解决方案见“描述2”
for (int i = 0; i < temp1.length - 1; i++) {
//String转BigInteger
...
}
6. 问题描述汇总
描述1
解决办法:删掉你要打开文件夹下的文件夹或打开一个内部没有文件夹的文件夹。
描述2
解决办法:将:“cipher = new BigInteger[0]; ” 改为:“cipher = new BigInteger[temp1.length-1]; ”。