这个例子参考书《java 7 学习笔记》 作者 林信良
这本书挺不错的,台湾人写的书品质就是好。
只是宣传得有点夸张,比如他的另外一本书 《Servlet jsp 学习笔记》,
在 《java 7 学习笔记》中说书中有一个微博的例子,其实只是一个书签的例子。
好书是经得起考验的,不需要出版社过度的夸张宣传。
JNotePad.java
package com.xjh.swing;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.swing.BorderFactory;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
public class JNotePad extends JFrame {
private JMenuBar menuBar;
private JMenu fileMenu;
private JMenuItem menuOpen;
private JMenuItem menuSave;
private JMenuItem menuSaveAs;
private JMenuItem menuClose;
private JMenu editMenu;
private JMenuItem menuCut;
private JMenuItem menuCopy;
private JMenuItem menuPaste;
private JMenu aboutMenu;
private JMenuItem menuAbout;
private JTextArea textArea;
private JLabel stateBar;
private JPopupMenu popUpMenu;
private TextDAO textDAO;
private JFileChooser fileChooser;
public JNotePad(TextDAO textDAO) {
this();
this.textDAO = textDAO;
}
public JNotePad() {
initCompanents();
initEventListeners();
}
private void initCompanents() {
setTitle("新增纯文本文件");
setSize(400, 300);
// 设置"文件"菜单
fileMenu = new JMenu("文件");
menuOpen = new JMenuItem("打开文件");
menuSave = new JMenuItem("保存文件");
menuSaveAs = new JMenuItem("另存新文件");
menuClose = new JMenuItem("关闭");
fileMenu.add(menuOpen);
fileMenu.addSeparator(); // 分隔线
fileMenu.add(menuSave);
fileMenu.add(menuSaveAs);
fileMenu.addSeparator(); // 分隔线
fileMenu.add(menuClose);
// 设置"编辑"菜单
editMenu = new JMenu("编辑");
menuCut = new JMenuItem("剪贴");
menuCopy = new JMenuItem("拷贝");
menuPaste = new JMenuItem("粘贴");
editMenu.add(menuCut);
editMenu.add(menuCopy);
editMenu.add(menuPaste);
// 设置"关于"菜单
aboutMenu = new JMenu("关于");
menuAbout = new JMenuItem("关于JNotePad");
aboutMenu.add(menuAbout);
// 菜单列
menuBar = new JMenuBar();
menuBar.add(fileMenu); // 文件
menuBar.add(editMenu); // 编辑
menuBar.add(aboutMenu); // 关于
// 设置菜单列
setJMenuBar(menuBar);
// 文字编辑区
textArea = new JTextArea();
textArea.setFont(new Font("宋体", Font.PLAIN, 16));
textArea.setLineWrap(true); // 设置自动换行
// 水平滚动条(不显示)和垂直滚动条(当有需要的时候显示)
JScrollPane pane = new JScrollPane(textArea,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
Container contentPane = this.getContentPane();
contentPane.add(pane, BorderLayout.CENTER);
// 状态栏
stateBar = new JLabel("未修改");
stateBar.setHorizontalAlignment(SwingConstants.LEFT); // 文字左对齐
stateBar.setBorder(BorderFactory.createEtchedBorder());
contentPane.add(stateBar, BorderLayout.SOUTH); // 布局管理器
popUpMenu = editMenu.getPopupMenu();
fileChooser = new JFileChooser();
}
private void initEventListeners() {
// 点击窗口开关按钮事件处理
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
closeFile();
}
});
// 菜单-打开文件
menuOpen.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
openFile();
}
});
// 菜单-保存文件
menuSave.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
saveFile();
}
});
// 菜单-另存新文件
menuSaveAs.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
saveFileAs();
}
});
// 菜单-关闭文件
menuClose.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
closeFile();
}
});
// 菜单-剪切
menuCut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
cut();
}
});
// 菜单-复制
menuCopy.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
copy();
}
});
// 菜单-粘贴
menuPaste.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
paste();
}
});
// 菜单-关于
menuAbout.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// 显示对话框
JOptionPane.showOptionDialog(null,
"JNotePad 0.1",
"关于JNotePad",
JOptionPane.DEFAULT_OPTION,
JOptionPane.INFORMATION_MESSAGE,
null,
null,
null);
}
});
// 编辑区键盘事件
textArea.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
jtextAreaActionPerformed();
}
});
// 编辑区鼠标事件
textArea.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
popUpMenu.show(editMenu, e.getX(), e.getY());
}
}
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {
popUpMenu.setVisible(false);
}
}
});
// this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 快捷键设置
menuOpen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,
InputEvent.CTRL_MASK));
menuSave.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
InputEvent.CTRL_MASK));
menuClose.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
InputEvent.CTRL_MASK));
menuCut.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,
InputEvent.CTRL_MASK));
menuCopy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,
InputEvent.CTRL_MASK));
menuPaste.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V,
InputEvent.CTRL_MASK));
}
private void openFile() {
if (stateBar.getText().equals("未修改")) { // 文件是否为存储状态
showFileDialog(); // 打开文件
} else {
int option = JOptionPane.showConfirmDialog(null,
"文件已修改,是否保存?",
"保存文件?",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE,
null);
switch (option) {
case JOptionPane.YES_OPTION: // 确认文件保存
saveFile(); // 保存文件
break;
case JOptionPane.NO_OPTION: // 放弃文件保存
showFileDialog();
break;
}
}
}
private void showFileDialog() {
int option = fileChooser.showDialog(null, null); // 文件选取对话框
// 使用者单击确认键
if (option == JFileChooser.APPROVE_OPTION) {
try {
setTitle(fileChooser.getSelectedFile().toString());
textArea.setText("");
stateBar.setText("未修改");
String text = textDAO.read(fileChooser.getSelectedFile().toString());
textArea.setText(text);
} catch (Throwable e) {
JOptionPane.showMessageDialog(null, e.toString(),
"打开文件失败", JOptionPane.ERROR_MESSAGE);
}
}
}
private void saveFile() {
// 从标题栏获取文件名
Path path = Paths.get(getTitle());
if (Files.notExists(path)) {
saveFileAs();
} else {
try {
textDAO.save(path.toString(), textArea.getText());
stateBar.setText("未修改");
} catch (Throwable e) {
JOptionPane.showMessageDialog(null, e.toString(),
"写入文件失败", JOptionPane.ERROR_MESSAGE);
}
}
}
private void saveFileAs() {
int option = fileChooser.showDialog(null, null);
if (option == JFileChooser.APPROVE_OPTION) {
setTitle(fileChooser.getSelectedFile().toString());
textDAO.create(fileChooser.getSelectedFile().toString());
saveFile();
}
}
private void closeFile() {
if (stateBar.getText().equals("未修改")) {
dispose();
} else {
int option = JOptionPane.showConfirmDialog(null, "文件已经修改, 是否保存?",
"保存文件?",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE,
null);
switch (option) {
case JOptionPane.YES_OPTION:
saveFile();
break;
case JOptionPane.NO_OPTION:
dispose();
}
}
}
private void cut() {
textArea.cut();
stateBar.setText("已修改");
popUpMenu.setVisible(false);
}
private void copy() {
textArea.copy();
popUpMenu.setVisible(false);
}
private void paste() {
textArea.paste();
stateBar.setText("已修改");
popUpMenu.setVisible(false);
}
private void jtextAreaActionPerformed() {}
public static void main(String[] args) throws InvocationTargetException,
InterruptedException {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
new JNotePad().setVisible(true);
}
});
}
}
TextDAO.java
package com.xjh.swing;
public interface TextDAO {
void create(String file);
String read(String toString);
void save(String file, String text);
}
FileTextDAO.java
package com.xjh.swing;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.logging.Level;
import java.util.logging.Logger;
public class FileTextDAO implements TextDAO {
@Override
public String read(String file) {
byte[] datas = null;
try {
datas = Files.readAllBytes(Paths.get(file));
} catch (IOException ex) {
Logger.getLogger(FileTextDAO.class.getName()).log(Level.SEVERE, null, ex);
}
return new String(datas);
}
@Override
public void save(String file, String text) {
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(file),
Charset.forName(System.getProperty("file.endoding")))) {
writer.write(text);
} catch (IOException ex) {
Logger.getLogger(FileTextDAO.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
public void create(String file) {
try {
Files.createFile(Paths.get(file));
} catch (IOException ex) {
Logger.getLogger(FileTextDAO.class.getName()).log(Level.SEVERE, null, ex);
}
}
}