目录
一、作品要求:
二、主要需求点分析:
1、菜单项目
2、文件结构
3、软件主界面
4、状态切换类菜单项JCheckBoxMenItem:
5、关于本程序对话框:
6、打开文件对话框:
7、另存为文件对话框:
8、字体设置对话框:
三、主要参考代码:
1、记事本入口主程序类文件:
2、主界面类文件:
3、功能主菜单类文件:
4、基础操作类文件--文件操作类文件:
5、基础操作类文件--字符编码判断类文件:
6、基础操作类文件--字体对话框类文件:
四、演示DEMO源代码在github上的仓库地址:
1、仿照Windows操作系统自带的记事本软件,完成Java版记事本程序的设计与制作。
2、每个班级刻录一张光盘,光盘封面写上班级信息、课程信息、指导老师姓名,如:2018计算机1班《Java实训作业》,指导老师:谢祥选。
3、在光盘上建立一个【班级】目录,在班级目录下再以【学号_姓名】方式创建学生目录,班级和学生目录请使用汉字中括符(【】)括起来,学生目录中的学号与姓名之间的连接符为英文的下划线(_),不是减号(-)。
4、把要上交的作品的项目根目录或项目工作空间目录完整的复制到学生自已的文件夹中,上交的作业中的项目目录不能用中括符(【】)括起来,必须保留开发时的原始目录结构与名称。
上交的作品光盘目录结构如下:
光盘F:\
|----【18计算机1班】
|----【20180324_张三丰】
|----LoginFrame
|----MyNotepad
|----20180325_李四光
|----MyCalculator
|----MyNotepad
|----20180368_小宇飞刀
|----LoginFrame
|----MyNotepad
……
import javax.swing.*;
/**
* 文件名:MenuFrameTest.java
* 功能描述:记事本程序入口类文件
*/
class MyNotepad {
public static void main(String[] args) {
try {
//可跨平台风格,忽略时的默认风格
//String lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
String lookAndFeel = UIManager.getSystemLookAndFeelClassName();//当前系统风格
UIManager.setLookAndFeel(lookAndFeel);
}catch (Exception e) {}
MainFrame myFrame = new MainFrame();
myFrame.setVisible(true);
}
}
/**
* 文件名:MainFrame.java
* 功能描述:程序主窗口类
*/
import javafx.geometry.HorizontalDirection;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.lang.reflect.Modifier;
import javax.swing.*;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class MainFrame extends JFrame {
private Container container = this.getContentPane();
private JTextArea textArea = new JTextArea();
private JScrollPane scrollPane = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
private JPanel panelStatusBar = new JPanel(new BorderLayout(10,5));
private JLabel labelContent = new JLabel("1行, 1列");
private JLabel labelEncoding = new JLabel("字符编码:UTF-8 ");
private MainMenu mainMenu;
public void setCurrentFileCharset(String currentFileCharset) {
labelEncoding.setText("字符编码:"+mainMenu.getCurrentFileCharset()+" ");
}
private void updateStatusBar(CaretEvent e) {
try {
int caretPos = textArea.getCaretPosition(); //获取当前光标处出字符在textArea中的索引值
int row = textArea.getLineOfOffset(caretPos); //算出行号
int col = caretPos - textArea.getLineStartOffset(row); //算出列号
labelContent.setText(String.format("%d行, %d列", row + 1, col + 1));
//labelEncoding.setText("字符编码:"+currentFileCharset+" ");
//System.out.println(labelContent.getText()+"|"+caretPos);
labelContent.validate();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public MainFrame() {
container.setLayout(new BorderLayout());
initFrame();
initTextArea();
initStatusBar();
initMenu();
}
private void initFrame() {
setTitle("记事本");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置窗口关闭方式
setSize(800,535);
setLocationRelativeTo(null); //居中显示
}
private void initMenu() {
mainMenu = new MainMenu(this,textArea);
}
private void initTextArea() {
textArea.setFont(new Font("新宋体",Font.ROMAN_BASELINE,14));
textArea.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent documentEvent) {
mainMenu.setModified(true);
}
@Override
public void removeUpdate(DocumentEvent documentEvent) {
mainMenu.setModified(true);
}
@Override
public void changedUpdate(DocumentEvent documentEvent) {
mainMenu.setModified(true);
}
});
textArea.addCaretListener(new CaretListener() {
@Override
public void caretUpdate(CaretEvent e) {
updateStatusBar(e);
}
});
/*
container.add(textArea);
VERTICAL垂直 HORIZONTAL水平
JScrollPane scrollPane = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
*/
container.add(scrollPane,BorderLayout.CENTER);
validate();
}
private void initStatusBar() {
JLabel labelLeft = new JLabel("提示信息:");
labelLeft.setHorizontalAlignment(SwingConstants.LEFT);
labelContent.setHorizontalAlignment(SwingConstants.RIGHT);
labelContent.setHorizontalAlignment(SwingConstants.LEFT);
panelStatusBar.add(labelLeft,BorderLayout.WEST);
panelStatusBar.add(labelContent,BorderLayout.CENTER);
panelStatusBar.add(labelEncoding,BorderLayout.EAST);
container.add(panelStatusBar,BorderLayout.SOUTH);
validate();
}
public void setPanelStatusBarVisible(boolean visible) {
this.panelStatusBar.setVisible(visible);
}
}
/**
* 文件名:MainMenu.java
* 功能描述:菜单及功能类文件
*/
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Modifier;
public class MainMenu {
private JFrame mainFrame = null;
private JTextArea textArea = null;
private String currentFileCharset = "UTF-8";//当前文件字符编码
private String currentFileName = ""; //当前文件名
private boolean isModified = false;//文件是否已修改
public Clipboard clipboard = new Clipboard("系统剪切板");//剪贴板
public boolean isModified() {
return isModified;
}
public void setModified(boolean modified) {
isModified = modified;
}
public void setCurrentFileCharset(String currentFileCharset) {
this.currentFileCharset = currentFileCharset;
}
public String getCurrentFileCharset() {
return currentFileCharset;
}
public MainMenu(JFrame owner, JTextArea textArea) {
this.mainFrame = owner;
this.textArea = textArea;
initMenu();
}
private void initMenu() {
JMenuBar menubar = new JMenuBar();//菜单条栏、菜单条:它是菜单的容器
JMenu menuFile = new JMenu("文件(F)");
JMenu menuEdit = new JMenu("编辑(E)");
JMenu menuFormat = new JMenu("格式(O)");
JMenu menuView = new JMenu("查看(V)");
JMenu menuHelp = new JMenu("帮助(H)");
menuFile.setMnemonic('F'); //设置菜单的热键为字母键F,需按下Alt键和字母键F
menuEdit.setMnemonic('E');
menuFormat.setMnemonic('O');
menuView.setMnemonic('V');
menuView.setMnemonic('H');
menubar.add(menuFile); //把主菜单条加入菜单栏容器中
menubar.add(menuEdit);
menubar.add(menuFormat);
menubar.add(menuView);
menubar.add(menuHelp);
//---------------------------BEGIN 【文件】菜单-----------------------//
JMenuItem miNew = new JMenuItem("新建(N)");
miNew.setMnemonic('O');
miNew.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK)); //设置快捷键Ctrl_N
miNew.addActionListener(this::menuFileActionPerformed);
JMenuItem miOpen = new JMenuItem("打开(O)");
miOpen.setMnemonic('O');
miOpen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK)); //设置快捷键Ctrl_O
miOpen.addActionListener(this::menuFileActionPerformed);
JMenuItem miSave=new JMenuItem("保存(S)");
miSave.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK)); //设置快捷键Ctrl_S
miSave.addActionListener(this::menuFileActionPerformed);
JMenuItem miSaveAs = new JMenuItem("另存为(A)");
miSaveAs.addActionListener(this::menuFileActionPerformed);
JMenuItem miExit=new JMenuItem("退出(X)");
miExit.addActionListener(this::menuFileActionPerformed);
menuFile.add(miNew);
menuFile.add(miOpen);
menuFile.add(miSave);
menuFile.add(miSaveAs);
menuFile.addSeparator(); //分隔线
menuFile.add(miExit);
//---------------------------END 【文件】菜单-----------------------//
//---------------------------BEGIN 【编辑】菜单-----------------------//
JMenuItem miSelectAll = new JMenuItem("全选(A)");
miSelectAll.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A,InputEvent.CTRL_MASK));
miSelectAll.addActionListener(this::menuEditActionPerformed);
JMenuItem miCut=new JMenuItem("剪切(X)");
miCut.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,InputEvent.CTRL_MASK));
miCut.addActionListener(this::menuEditActionPerformed);
JMenuItem miCopy = new JMenuItem("复制(C)");
miCopy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,InputEvent.CTRL_MASK));
miCopy.addActionListener(this::menuEditActionPerformed);
JMenuItem miPaste=new JMenuItem("粘贴(V)");
miPaste.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V,InputEvent.CTRL_MASK));
miPaste.addActionListener(this::menuEditActionPerformed);
menuEdit.add(miSelectAll);
menuEdit.addSeparator();
menuEdit.add(miCut);
menuEdit.add(miCopy);
menuEdit.addSeparator();
menuEdit.add(miPaste);
//---------------------------END 【编辑】菜单-----------------------//
//---------------------------BEGIN 【格式】菜单-----------------------//
JCheckBoxMenuItem miAutoLine=new JCheckBoxMenuItem("自动换行(W)");
textArea.setLineWrap(true); //激活自动换行功能
textArea.setWrapStyleWord(true); //激活断行不断字功能
miAutoLine.setState(textArea.getLineWrap());
miAutoLine.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_MASK));
miAutoLine.addActionListener(this::menuFormatActionPerformed);
JMenuItem miFontSet = new JMenuItem("字体(F)");
miFontSet.setMnemonic('F');
miFontSet.addActionListener(this::menuFormatActionPerformed);
menuFormat.add(miAutoLine);
menuFormat.add(miFontSet);
//---------------------------END 【格式】菜单-----------------------//
//---------------------------BEGIN 【查看】菜单-----------------------//
JCheckBoxMenuItem miStatusBar=new JCheckBoxMenuItem("状态栏(S)");
miStatusBar.setMnemonic('S');
miStatusBar.setState(true);
miStatusBar.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
((MainFrame)mainFrame).setPanelStatusBarVisible(miStatusBar.getState());
//自已加状态栏自已写
}
});
menuView.add(miStatusBar);
//---------------------------END 【查看】菜单-----------------------//
//---------------------------BEGIN 【帮助】菜单-----------------------//
JMenuItem miHelpContent = new JMenuItem("帮助信息……");
miHelpContent.addActionListener(this::menuHelpActionPerformed);
JMenuItem miAbout = new JMenuItem("关于……");
miAbout.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1,Modifier.FINAL));
miAbout.addActionListener(this::menuHelpActionPerformed);
menuHelp.add(miHelpContent);
menuHelp.addSeparator();
menuHelp.add(miAbout);
//---------------------------END 【帮助】菜单-----------------------//
mainFrame.setJMenuBar(menubar);
mainFrame.validate();
}
public void menuFileActionPerformed(ActionEvent e) {
if (((JMenuItem)e.getSource()).getText().equals("新建(N)")) {
if (canCloseFile()) {
initVar();
}
}
else if (((JMenuItem)e.getSource()).getText().equals("打开(O)")) {
if (canCloseFile()) {
openFile();
}
}
else if (((JMenuItem)e.getSource()).getText().equals("保存(S)")) {
//System.out.println(currentFileCharset);
saveFile(currentFileName);
}
else if (((JMenuItem)e.getSource()).getText().equals("另存为(A)")) {
saveFile("");
}
else if (((JMenuItem)e.getSource()).getText().equals("退出(X)")) {
if (canCloseFile()) {
System.exit(0);
}
}
}
public void menuEditActionPerformed(ActionEvent e) {
if (((JMenuItem)e.getSource()).getText().equals("全选(A)")) {
textArea.selectAll();
}
else if (((JMenuItem)e.getSource()).getText().equals("复制(C)")) {
copy();
}
else if (((JMenuItem)e.getSource()).getText().equals("剪切(X)")) {
cut();
}
else if (((JMenuItem)e.getSource()).getText().equals("粘贴(V)")) {
paste();
}
}
public void menuFormatActionPerformed(ActionEvent e) {
if (((JMenuItem)e.getSource()).getText().equals("自动换行(W)")) {
boolean bl = ((JCheckBoxMenuItem)e.getSource()).getState();
textArea.setLineWrap(bl); //激活自动换行功能
textArea.setWrapStyleWord(bl); //激活断行不断字功能
}
else if (((JMenuItem)e.getSource()).getText().equals("字体(F)")) {
Font myFont = FontDialog.showDialog(mainFrame,textArea.getFont());
if (myFont != null) {
textArea.setFont(myFont);
}
}
}
public void menuHelpActionPerformed(ActionEvent e) {
if (((JMenuItem)e.getSource()).getText().equals("帮助信息……")) {
String str = "这是江西科技师范大学软件动漫学院2018级计算机专业的实训作业之一!\r\n"+
"小宇飞刀(xieyunc)@江西南昌\r\n"+
"2019年12月25日 凌晨";
JOptionPane.showMessageDialog(mainFrame, str,"帮助信息", 1);
}
else if (((JMenuItem)e.getSource()).getText().equals("关于……")) {
String str = "小宇飞刀的记事本程序【实训作业三】,Ver 0.9.3 ......\r\n"+
"教学网址:http://blog.csdn.net/xieyunc\r\n"+
"小宇飞刀@江西南昌";
JOptionPane.showMessageDialog(mainFrame, str,"关于本程序……", 1);
}
}
public void cut() {
copy();
//标记开始位置
int start = this.textArea.getSelectionStart();
//标记结束位置
int end = this.textArea.getSelectionEnd();
//删除所选段
this.textArea.replaceRange("", start, end);
}
public void copy() {
//拖动选取文本
String temp = textArea.getSelectedText();
//把获取的内容复制到连续字符器,这个类继承了剪贴板接口
StringSelection text = new StringSelection(temp);
//把内容放在剪贴板
this.clipboard.setContents(text, null);
}
public void paste() {
//Transferable接口,把剪贴板的内容转换成数据
Transferable contents = this.clipboard.getContents(this);
//DataFalvor类判断是否能把剪贴板的内容转换成所需数据类型
DataFlavor flavor = DataFlavor.stringFlavor;
//如果可以转换
if (contents.isDataFlavorSupported(flavor)) {
String str;
try {//开始转换
str = (String) contents.getTransferData(flavor);
//如果要粘贴时,鼠标已经选中了一些字符
if (this.textArea.getSelectedText() != null) {
//定位被选中字符的开始位置
int start = this.textArea.getSelectionStart();
//定位被选中字符的末尾位置
int end = this.textArea.getSelectionEnd();
//把粘贴的内容替换成被选中的内容
this.textArea.replaceRange(str, start, end);
} else {
//获取鼠标所在TextArea的位置
int mouse = this.textArea.getCaretPosition();
//在鼠标所在的位置粘贴内容
this.textArea.insert(str, mouse);
}
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
}
private void initVar() { //初始化变量和文本框
currentFileName = "";
mainFrame.setTitle("记事本");
isModified = false;
currentFileCharset = "UTF-8";
textArea.setText("");
}
private boolean openFile() {
boolean isSucessed = false;
String fn = FileOperator.selectFile(currentFileName,JFileChooser.OPEN_DIALOG);
if (fn.equals("")) {
return false;
}
try {
String content = FileOperator.readTxt(fn);
textArea.setText(content);
currentFileName = fn;
currentFileCharset = FileOperator.getFileCharsetName(fn);
((MainFrame)mainFrame).setCurrentFileCharset(currentFileCharset);
isModified = false;
mainFrame.setTitle(new File(currentFileName).getName());
isSucessed = true;
} catch (Exception ex) {
//ex.printStackTrace();
}
return isSucessed;
}
private boolean canCloseFile() {
boolean canClose = true;
if (isModified) {
int n = JOptionPane.showConfirmDialog(null, "文件已修改但未保存,要保存吗?", "确认对话框", JOptionPane.YES_NO_CANCEL_OPTION);
if (n == JOptionPane.YES_OPTION) {
canClose = saveFile(currentFileName);
//JOptionPane.showMessageDialog(new JFrame(),"文件已保存!");
} else if (n == JOptionPane.NO_OPTION) {
//JOptionPane.showMessageDialog(new JFrame(),"已放弃保存!");
} else {
canClose = false;
}
}
return canClose;
}
private boolean saveFile(String fn) {
String fileName = fn;
if (fileName.equals("")) {
fileName = FileOperator.selectFile(currentFileName, JFileChooser.SAVE_DIALOG);
}
if (fileName.equals("")) {
return false;
}
boolean saveOK = false;
try {
String content = textArea.getText();
saveOK = FileOperator.writeTxt(fileName, content, currentFileCharset);
if (saveOK) { // && !currentFileName.equals(fileName)) {
currentFileName = fileName;
isModified = false;
currentFileCharset = FileOperator.getFileCharsetName(currentFileName);
mainFrame.setTitle(new File(currentFileName).getName());
} else {
JOptionPane.showMessageDialog(null, "文件保存失败!\r\n", "系统提示",JOptionPane.ERROR_MESSAGE);
}
}catch (Exception e) {
//e.printStackTrace();
}
return saveOK;
}
}
/**
* 文件名:FileOperator.java
* 功能描述:文件读写类
*/
import java.io.*;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
public class FileOperator {
public static void main(String[] args) {
System.out.println(selectFile("",JFileChooser.SAVE_DIALOG));
}
//打开文件对话框,返回已选择的文件名
public static String selectFile(String pathFileName,int dialogType) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(Exception e) {
//...
}
// 创建文件选择器
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);//只允许选择文件
fileChooser.setMultiSelectionEnabled(false);//不允许多选
// 设置当前目录
if (!pathFileName.equals(""))
fileChooser.setCurrentDirectory(new File(pathFileName));
fileChooser.setAcceptAllFileFilterUsed(false);//先取消文件过滤器
final String[][] fileExtNames = {
{".cvs", "CVS文件(*.cvs)"},
{".txt", "文本文档(*.txt)"}
};
// 显示所有文件
fileChooser.addChoosableFileFilter(new FileFilter() {
public boolean accept(File file) {
return true;
}
public String getDescription() {
return "所有文件(*.*)";
}
});
// 循环添加需要显示的文件
for (final String[] fileExtName : fileExtNames) {
fileChooser.setFileFilter(new FileFilter() {
public boolean accept(File file) {
if (file.getName().toLowerCase().endsWith(fileExtName[0]) || file.isDirectory()) {
return true;
}
return false;
}
public String getDescription() {
return fileExtName[1];
}
});
}
fileChooser.setDialogType(dialogType);
if (fileChooser.showDialog(null,null) ==JFileChooser.APPROVE_OPTION) {
return fileChooser.getSelectedFile().getPath();
} else {
return "";//没有选择文件,比如取消了
}
}
public static String readTxt(String path) {
StringBuilder content = new StringBuilder("");
try {
String fileCharsetName = getFileCharsetName(path);
//System.out.println("文件的编码格式为:"+fileCharsetName);
InputStream is = new FileInputStream(path);
//必须保证此处文件编码判断无误
InputStreamReader isr = new InputStreamReader(is, fileCharsetName);
BufferedReader br = new BufferedReader(isr);
BufferedReader br2 = new BufferedReader(isr);
/*
char[] charArray = new char[8192];
int len = 0;
long start1 = System.currentTimeMillis();
while((len = br2.read(charArray))>0) {
content.append(new String(charArray,0,len));
}
br2.close();
long end1 = System.currentTimeMillis();
System.out.println("charArray:"+(end1-start1));
*/
String str = "";
boolean isFirst = true;
long start2 = System.currentTimeMillis();
while (null != (str = br.readLine())) {
if (!isFirst)
content.append(System.lineSeparator());
//System.getProperty("line.separator");
else
isFirst = false;
content.append(str);
}
long end2 = System.currentTimeMillis();
System.out.println("charArray:"+(end2-start2));
br.close();
} catch (Exception e) {
e.printStackTrace();
System.err.println("读取文件:" + path + "失败!");
}
return content.toString();
}
public static boolean writeTxt(String path,String fileContent,String fileCharsetName) {
boolean saveOK = false;
try {
//System.out.println("文件的编码格式为:"+fileCharsetName);
OutputStream os = new FileOutputStream(path);
//必须保证此处文件编码判断无误
OutputStreamWriter osr = new OutputStreamWriter(os, fileCharsetName);
BufferedWriter wr = new BufferedWriter(osr);
//byte[] byteArray = new byte[8192];
//int len = 0;
wr.write(fileContent);
wr.close();
saveOK = true;
} catch (Exception e) {
//e.printStackTrace();
System.err.println("文件存盘失败:" + path + "失败!"+e.getMessage());
}
return saveOK;
}
public static String getFileCharsetName(String fileName) throws IOException {
String code = "UTF-8";
try {
code = EncodeUtils.getEncode(fileName, true);
System.out.println(code);
}catch (Exception e) {
e.printStackTrace();
}
return code;
}
/*
public static String getFileCharsetName(String fileName) throws IOException {
InputStream inputStream = new FileInputStream(fileName);
final int headSize = 3;
byte[] head = new byte[headSize];
inputStream.read(head);
String charsetName = "GBK";//或GB2312,即ANSI
if (head[0] == -1 && head[1] == -2 ) //0xFFFE
charsetName = "UTF-16";
else if (head[0] == -2 && head[1] == -1 ) //0xFEFF
charsetName = "Unicode";//包含两种编码格式:UCS2-Big-Endian和UCS2-Little-Endian
else if(head[0]==-27)// && head[1]==-101 && head[2] ==-98)
charsetName = "UTF-8"; //UTF-8(不含BOM)
else if(head[0]==-17 && head[1]==-69 && head[2] ==-65)
charsetName = "UTF-8"; //UTF-8-BOM
else
{
int i = 0;
charsetName = "UTF-8 NoBom";
while (i < headSize - 2) {
if ((head[i] & 0x00FF) < 0x80) {// (10000000)值小于0x80的为ASCII字符
i++;
continue;
} else if ((head[i] & 0x00FF) < 0xC0) {// (11000000)值在0x80和0xC0之间的,不是开头第一个
charsetName = "Not UTF-8";
System.err.println("文件编码错误: " + fileName + " : " + charsetName + "1000");
break;
} else if ((head[i] & 0x00FF) < 0xE0) {// (11100000)此范围内为2字节UTF-8字符
if ((head[i + 1] & (0xC0)) != 0x8) {
charsetName = "Not UTF-8";
System.err.println("文件编码错误: " + fileName + " : " + charsetName + "1100");
break;
} else
i += 2;
} else if ((head[i] & 0x00FF) < 0xF0) {// (11110000)此范围内为3字节UTF-8字符
if ((head[i + 1] & (0xC0)) != 0x80 || (head[i + 2] & (0xC0)) != 0x80) {
charsetName = "Not UTF-8";
System.err.println("文件编码错误: " + fileName + " : " + charsetName + "11100000" + (head[i + 1] & (0xC0)));
break;
} else
i += 3;
} else {
charsetName = "Not UTF-8";
System.err.println("文件编码错误: " + fileName + " : " + charsetName + "1111");
break;
}
}
}
inputStream.close();
//System.out.println(code);
return charsetName;
}
*/
}
/**
* 文件名:EncodeUtils.java
* 功能描述:文件编码格式判断类
*/
import java.io.*;
import java.util.BitSet;
/**
* 编码工具类,主要用于识别UTF8、UTF8 BOM、GBK
* Created by dongp on 2018/1/9.
*/
public class EncodeUtils {
private static int BYTE_SIZE = 8;
public static String CODE_UTF8 = "UTF-8";
public static String CODE_UTF8_BOM = "UTF-8_BOM";
public static String CODE_GBK = "GBK";
/**
* 通过文件全名称获取编码集名称
*
* @param fullFileName
* @param ignoreBom
* @return
* @throws Exception
*/
public static String getEncode(String fullFileName, boolean ignoreBom) throws Exception {
//log.debug("fullFileName ; {}", fullFileName);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fullFileName));
return getEncode(bis, ignoreBom);
}
/**
* 通过文件缓存流获取编码集名称,文件流必须为未曾
*
* @param bis
* @return
* @throws Exception
*/
public static String getEncode(BufferedInputStream bis, boolean ignoreBom) throws Exception {
bis.mark(0);
String encodeType = "";
byte[] head = new byte[3];
bis.read(head);
if (head[0] == -1 && head[1] == -2) {
encodeType = "UTF-16";
} else if (head[0] == -2 && head[1] == -1) {
encodeType = "Unicode";
} else if (head[0] == -17 && head[1] == -69 && head[2] == -65) { //带BOM
if (ignoreBom) {
encodeType = CODE_UTF8;
} else {
encodeType = CODE_UTF8_BOM;
}
} else if ("Unicode".equals(encodeType)) {
encodeType = "UTF-16";
} else if (isUTF8(bis)) {
encodeType = CODE_UTF8;
} else {
encodeType = CODE_GBK;
}
//log.info("result encode type : " + encodeType);
return encodeType;
}
/**
* 是否是无BOM的UTF8格式,不判断常规场景,只区分无BOM UTF8和GBK
*
* @param bis
* @return
*/
private static boolean isUTF8(BufferedInputStream bis) throws Exception {
bis.reset();
//读取第一个字节
int code = bis.read();
do {
BitSet bitSet = convert2BitSet(code);
//判断是否为单字节
if (bitSet.get(0)) {//多字节时,再读取N个字节
if (!checkMultiByte(bis, bitSet)) {//未检测通过,直接返回
return false;
}
} else {
//单字节时什么都不用做,再次读取字节
}
code = bis.read();
} while (code != -1);
return true;
}
/**
* 检测多字节,判断是否为utf8,已经读取了一个字节
*
* @param bis
* @param bitSet
* @return
*/
private static boolean checkMultiByte(BufferedInputStream bis, BitSet bitSet) throws Exception {
int count = getCountOfSequential(bitSet);
byte[] bytes = new byte[count - 1];//已经读取了一个字节,不能再读取
bis.read(bytes);
for (byte b : bytes) {
if (!checkUtf8Byte(b)) {
return false;
}
}
return true;
}
/**
* 检测单字节,判断是否为utf8
*
* @param b
* @return
*/
private static boolean checkUtf8Byte(byte b) throws Exception {
BitSet bitSet = convert2BitSet(b);
return bitSet.get(0) && !bitSet.get(1);
}
/**
* 检测bitSet中从开始有多少个连续的1
*
* @param bitSet
* @return
*/
private static int getCountOfSequential(BitSet bitSet) {
int count = 0;
for (int i = 0; i < BYTE_SIZE; i++) {
if (bitSet.get(i)) {
count++;
} else {
break;
}
}
return count;
}
/**
* 将整形转为BitSet
*
* @param code
* @return
*/
private static BitSet convert2BitSet(int code) {
BitSet bitSet = new BitSet(BYTE_SIZE);
for (int i = 0; i < BYTE_SIZE; i++) {
int tmp3 = code >> (BYTE_SIZE - i - 1);
int tmp2 = 0x1 & tmp3;
if (tmp2 == 1) {
bitSet.set(i);
}
}
return bitSet;
}
/**
* 将一指定编码的文件转换为另一编码的文件
*
* @param oldFullFileName
* @param oldCharsetName
* @param newFullFileName
* @param newCharsetName
*/
public static void convert(String oldFullFileName, String oldCharsetName, String newFullFileName, String newCharsetName) throws Exception {
//log.info("the old file name is : {}, The oldCharsetName is : {}", oldFullFileName, oldCharsetName);
//log.info("the new file name is : {}, The newCharsetName is : {}", newFullFileName, newCharsetName);
StringBuffer content = new StringBuffer();
//@Cleanup
BufferedReader bin = new BufferedReader(new InputStreamReader(new FileInputStream(oldFullFileName), oldCharsetName));
String line;
while ((line = bin.readLine()) != null) {
content.append(line);
content.append(System.getProperty("line.separator"));
}
newFullFileName = newFullFileName.replace("\\", "/");
File dir = new File(newFullFileName.substring(0, newFullFileName.lastIndexOf("/")));
if (!dir.exists()) {
dir.mkdirs();
}
//@Cleanup
Writer out = new OutputStreamWriter(new FileOutputStream(newFullFileName), newCharsetName);
out.write(content.toString());
}
}
/**
* 文件名:FontDialog.java
* 功能描述:字体选择对话框。
*/
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
import javax.swing.border.*;
public class FontDialog extends JDialog {
private static final long serialVersionUID = 1L;
private static Font resultFont = null;
JList listFontName, listFontStyle, listFontSize, listFontColor;
JTextField editFontName, editFontStyle, editFontSize, editFontColor;
JButton[] ColorButton;
String demoString;
JLabel labelExample;
JButton btnOK, btnCancel;
Color[] colorArray = {Color.BLACK, Color.BLUE, Color.CYAN, Color.DARK_GRAY,
Color.GRAY, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA,
Color.ORANGE, Color.PINK, Color.RED, Color.WHITE, Color.YELLOW};
String[] colorNameArray = {"BLACK", "BLUE", "CYAN", "DARK_GRAY", "GRAY",
"GREEN", "LIGHT_GRAY", "MAGENTA", "ORANGE", "PINK", "RED", "WHITE",
"YELLOW"};
private JFrame frame;
public FontDialog(JFrame owner, String title, boolean modal) {
super(owner, title, modal);
Container container = getContentPane();
container.setLayout(new BorderLayout());
this.frame = owner;
setLocationRelativeTo(owner);
//setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panelMain = new JPanel();
panelMain.setLayout(new GridLayout(2, 1));
JPanel panelFontSet, panelFontView;
panelFontSet = new JPanel(new GridLayout(1, 4));
panelFontView = new JPanel(new GridLayout(1, 2));
demoString = "AaBbCcDdEe";
labelExample = new JLabel(demoString, JLabel.CENTER);
labelExample.setBackground(Color.WHITE);
ListSelectionListener selectionListener = new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (((JList) e.getSource()).getName().equals("listFontName")) {
editFontName.setText((String) listFontName.getSelectedValue());
labelExample.setFont(new Font(editFontName.getText(), labelExample.getFont().getStyle(), labelExample.getFont().getSize()));
}
if (((JList) e.getSource()).getName().equals("listFontStyle")) {
editFontStyle.setText((String) listFontStyle.getSelectedValue());
labelExample.setFont(new Font(labelExample.getFont().getFontName(), listFontStyle.getSelectedIndex(), labelExample.getFont().getSize()));
}
if (((JList) e.getSource()).getName().equals("listFontSize")) {
editFontSize.setText((String) listFontSize.getSelectedValue());
try {
Integer.parseInt(editFontSize.getText());
} catch (Exception excepInt) {
editFontSize.setText(labelExample.getFont().getSize() + "");
}
labelExample.setFont(new Font(labelExample.getFont().getFontName(), labelExample.getFont().getStyle(), Integer.parseInt(editFontSize.getText())));
}
if (((JList) e.getSource()).getName().equals("listFontColor")) {
editFontColor.setText(colorNameArray[listFontColor.getSelectedIndex()]);
labelExample.setForeground(colorArray[listFontColor.getSelectedIndex()]);
}
}
};
KeyListener keyListener = new KeyListener() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 10) {
if (((JTextField) e.getSource()).getName().equals("listFontName")) {
labelExample.setFont(new Font(editFontName.getText(), labelExample.getFont().getStyle(), labelExample.getFont().getSize()));
}
if (((JTextField) e.getSource()).getName().equals("listFontStyle")) {
editFontStyle.setText((String) listFontStyle.getSelectedValue());
labelExample.setFont(new Font(labelExample.getFont().getFontName(), listFontStyle.getSelectedIndex(), labelExample.getFont().getSize()));
}
if (((JTextField) e.getSource()).getName().equals("listFontSize")) {
try {
Integer.parseInt(editFontSize.getText());
} catch (Exception excepInt) {
editFontSize.setText(labelExample.getFont().getSize() + "");
}
labelExample.setFont(new Font(labelExample.getFont().getFontName(), labelExample.getFont().getStyle(), Integer.parseInt(editFontSize.getText())));
}
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
};
// 字体
JPanel panelFontName = new JPanel();
Border border = BorderFactory.createLoweredBevelBorder();
border = BorderFactory.createTitledBorder(border, "字体");
panelFontName.setBorder(border);
Font[] fontArray = java.awt.GraphicsEnvironment
.getLocalGraphicsEnvironment().getAllFonts();
int fontArrayCount = fontArray.length;
String[] fontNameArray = new String[fontArrayCount];
for (int i = 0; i < fontArrayCount; i++) {
fontNameArray[i] = fontArray[i].getName();
}
listFontName = new JList(fontNameArray);
listFontName.setName("listFontName");
listFontName.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
listFontName.addListSelectionListener(selectionListener);
listFontName.setVisibleRowCount(6);
editFontName = new JTextField(fontNameArray[0]);
editFontName.setName("editFontName");
editFontName.addKeyListener(keyListener);
JScrollPane jspFontName = new JScrollPane(listFontName);
panelFontName.setLayout(new BoxLayout(panelFontName, BoxLayout.PAGE_AXIS));
panelFontName.add(editFontName);
panelFontName.add(jspFontName);
// 样式
JPanel panelFontstyle = new JPanel();
border = BorderFactory.createLoweredBevelBorder();
border = BorderFactory.createTitledBorder(border, "样式");
panelFontstyle.setBorder(border);
String[] fontStylesArray = {"PLAIN", "BOLD", "ITALIC", "BOLD ITALIC"};
listFontStyle = new JList(fontStylesArray);
listFontStyle.setName("listFontStyle");
listFontStyle.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
listFontStyle.addListSelectionListener(selectionListener);
listFontStyle.setVisibleRowCount(6);
editFontStyle = new JTextField(fontStylesArray[0]);
editFontStyle.setName("listFontStyle");
editFontStyle.addKeyListener(keyListener);
JScrollPane jspFontStyle = new JScrollPane(listFontStyle);
panelFontstyle.setLayout(new BoxLayout(panelFontstyle, BoxLayout.PAGE_AXIS));
panelFontstyle.add(editFontStyle);
panelFontstyle.add(jspFontStyle);
// 大小
JPanel panelFontSize = new JPanel();
border = BorderFactory.createLoweredBevelBorder();
border = BorderFactory.createTitledBorder(border, "大小");
panelFontSize.setBorder(border);
String[] fontSizeArray = {"10", "14", "18", "22", "26", "30"};
listFontSize = new JList(fontSizeArray);
listFontSize.setName("listFontSize");
listFontSize.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
listFontSize.addListSelectionListener(selectionListener);
listFontSize.setVisibleRowCount(6);
editFontSize = new JTextField(fontSizeArray[0]);
editFontSize.setName("listFontSize");
editFontSize.addKeyListener(keyListener);
JScrollPane jspFontSize = new JScrollPane(listFontSize);
panelFontSize.setLayout(new BoxLayout(panelFontSize, BoxLayout.PAGE_AXIS));
panelFontSize.add(editFontSize);
panelFontSize.add(jspFontSize);
// 颜色
JPanel panelFontColor = new JPanel();
Border borderColor = BorderFactory.createLoweredBevelBorder();
borderColor = BorderFactory.createTitledBorder(borderColor, "颜色");
panelFontColor.setBorder(borderColor);
listFontColor = new JList(colorNameArray);
listFontColor.setName("listFontColor");
listFontColor.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
listFontColor.addListSelectionListener(selectionListener);
listFontColor.setVisibleRowCount(6);
editFontColor = new JTextField(colorNameArray[0].toString());
editFontColor.setName("editFontColor");
editFontColor.addKeyListener(keyListener);
JScrollPane jspFontColor = new JScrollPane(listFontColor);
panelFontColor.setLayout(new BoxLayout(panelFontColor, BoxLayout.PAGE_AXIS));
panelFontColor.add(editFontColor);
panelFontColor.add(jspFontColor);
panelFontSet.add(panelFontName);
panelFontSet.add(panelFontstyle);
panelFontSet.add(panelFontSize);
//panelFontSet.add(panelFontColor);
panelFontView.add(labelExample);
panelMain.add(panelFontSet);
panelMain.add(panelFontView);
JPanel panelButton = new JPanel();
panelButton.setLayout(new FlowLayout());
btnOK = new JButton("确定");
btnCancel = new JButton("取消");
panelButton.add(btnOK);
panelButton.add(btnCancel);
btnOK.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
resultFont = labelExample.getFont();
FontDialog.this.setVisible(false);
}
});
btnCancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
resultFont = null;
FontDialog.this.setVisible(false);
}
});
container.add(panelMain, BorderLayout.CENTER);
container.add(panelButton, BorderLayout.SOUTH);
setSize(400, 300);
//this.setVisible(true);
}
public static Font showDialog(JFrame owner) {
FontDialog fontDialog = new FontDialog(owner, "字体设置", true);
fontDialog.setVisible(true);
return resultFont;
}
}
https://github.com/xieyunc/java_demo.git