笔者是个Java小白,这几天用Java写记事本的源码,不懂的地方就在博客上查找学习,文章中有一些代码就是从CSDN上学习或者摘抄的嘻嘻!在这里笔者对在写代码的过程中进行一些总结。另外也希望读者看完可以的话给出一些建议或者指出我的不足嘻嘻,我将不胜感激!!!

//导包,创建所需组件和添加组件
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import javax.security.auth.callback.ConfirmationCallback;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.BadLocationException;
import javax.swing.undo.UndoManager;
class noteBookDemo extends JFrame implements ActionListener {private Container c = getContentPane();private JMenuBar jmb = new JMenuBar();// 菜单栏private JPopupMenu pop = new JPopupMenu();// 弹出菜单// 父菜单private JMenu fileMenu = new JMenu("文件(F)");private JMenu editMenu = new JMenu("编辑(E)");private JMenu helpMenu = new JMenu("帮助(H)");private JMenu readMenu = new JMenu("查看(V)");private JMenu formatMenu = new JMenu("格式(O)");// 子菜单private JMenuItem newMenu = new JMenuItem("   新建(N)      ");private JMenuItem openMenu = new JMenuItem("   打开(O)      ");private JMenuItem saveMenu = new JMenuItem("   保存(S)      ");private JMenuItem saveAnotherMenu = new JMenuItem("   另存为(A)      ");private JMenuItem printMenu = new JMenuItem("   打印(P)      ");private JMenuItem setPageMenu = new JMenuItem("   页面设置(U)      ");private JMenuItem exitMenu = new JMenuItem("   退出(X)      ");private JMenuItem cancelMenu1 = new JMenuItem("   撤销(U)      "), cancelMenu2 = new JMenuItem("  撤销(U)   ");private JMenuItem shearMenu1 = new JMenuItem("   剪切(T)      "), shearMenu2 = new JMenuItem("  剪切(T)   ");private JMenuItem copyMenu1 = new JMenuItem("   复制(C)      "), copyMenu2 = new JMenuItem("  复制(C)   ");private JMenuItem pasteMenu1 = new JMenuItem("   粘贴(P)      "), pasteMenu2 = new JMenuItem("  粘贴(P)   ");private JMenuItem deleteMenu1 = new JMenuItem("   删除(L)         "), deleteMenu2 = new JMenuItem("  删除(L)   ");private JMenuItem foundMenu = new JMenuItem("   查找(F)      ");private JMenuItem foundNextMenu = new JMenuItem("   查找下一个(N)    ");private JMenuItem replaceMenu = new JMenuItem("   替换(R)      ");private JMenuItem allSectionMenu1 = new JMenuItem("   全选(A)      "), allSectionMenu2 = new JMenuItem("  全选(A)   ");private JMenuItem DateMenu = new JMenuItem("   时间/日期(D)     ");private JRadioButtonMenuItem autoMenu = new JRadioButtonMenuItem("   自动换行(W)      ", true);private JMenuItem sizeMenu = new JMenuItem("   字体(F)      ");private JRadioButtonMenuItem stateMenu = new JRadioButtonMenuItem("   状态栏(S)      ");private JMenuItem readHelpMenu = new JMenuItem("   查看帮助(H)      ");private JMenuItem aboutMenu = new JMenuItem("   关于记事本(A)      ");// 其他组件private JTextArea jta = new JTextArea("");private JScrollPane jsp = new JScrollPane(jta);private FileDialog _Open = new FileDialog(this, "打开文件", FileDialog.LOAD);private FileDialog _Save = new FileDialog(this, "保存文件", FileDialog.SAVE)private UndoManager undom = new UndoManager();private JLabel jla = new JLabel("");// 构造方法noteBookDemo() {super("记事本");setJMenuBar(jmb);// 向文件菜单添加子菜单,设置键盘标识符,快捷键,添加子菜单监听器fileMenu.add(newMenu);newMenu.setMnemonic('N');newMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));newMenu.addActionListener(this);fileMenu.add(openMenu);openMenu.setMnemonic('O');openMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK));openMenu.addActionListener(this);fileMenu.add(saveMenu);saveMenu.setMnemonic('S');saveMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));saveMenu.addActionListener(this);fileMenu.add(saveAnotherMenu);saveAnotherMenu.setMnemonic('A');saveAnotherMenu.addActionListener(this);fileMenu.addSeparator();fileMenu.add(setPageMenu);setPageMenu.setMnemonic('U');setPageMenu.addActionListener(this);fileMenu.add(printMenu);printMenu.setMnemonic('P');printMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.CTRL_MASK));printMenu.addActionListener(this);fileMenu.addSeparator();fileMenu.add(exitMenu);exitMenu.setMnemonic('X');exitMenu.addActionListener(this);fileMenu.setMnemonic(KeyEvent.VK_F);// 向编辑菜单添加子菜单,设置键盘标识符,快捷键,添加子菜单监听器(包括弹出菜单)editMenu.add(cancelMenu1);cancelMenu1.setMnemonic('U');cancelMenu1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, ActionEvent.CTRL_MASK));cancelMenu1.addActionListener(this);cancelMenu2.addActionListener(this);editMenu.addSeparator();editMenu.add(shearMenu1);shearMenu1.setMnemonic('T');shearMenu1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.CTRL_MASK));shearMenu1.addActionListener(this);shearMenu2.addActionListener(this);editMenu.add(copyMenu1);copyMenu1.setMnemonic('C');copyMenu1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK));copyMenu1.addActionListener(this);copyMenu2.addActionListener(this);editMenu.add(pasteMenu1);pasteMenu1.setMnemonic('P');pasteMenu1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.CTRL_MASK));pasteMenu1.addActionListener(this);pasteMenu2.addActionListener(this);editMenu.add(deleteMenu1);deleteMenu1.setMnemonic('L');deleteMenu1.setAccelerator(KeyStroke.getKeyStroke("Delete"));deleteMenu2.setAccelerator(KeyStroke.getKeyStroke("Backspace"));deleteMenu1.addActionListener(this);deleteMenu2.addActionListener(this);editMenu.addSeparator();editMenu.add(foundMenu);foundMenu.setMnemonic('F');foundMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, ActionEvent.CTRL_MASK));foundMenu.addActionListener(this);editMenu.add(foundNextMenu);foundNextMenu.setMnemonic('N');foundNextMenu.setAccelerator(KeyStroke.getKeyStroke("F3"));foundNextMenu.addActionListener(this);editMenu.add(replaceMenu);replaceMenu.setMnemonic('R');replaceMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H, ActionEvent.CTRL_MASK));replaceMenu.addActionListener(this);editMenu.addSeparator();editMenu.add(allSectionMenu1);allSectionMenu1.setMnemonic('A');allSectionMenu1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.CTRL_MASK));allSectionMenu1.addActionListener(this);allSectionMenu2.addActionListener(this);editMenu.add(DateMenu);DateMenu.setMnemonic('D');DateMenu.setAccelerator(KeyStroke.getKeyStroke("F5"));DateMenu.addActionListener(this);editMenu.setMnemonic(KeyEvent.VK_E);// 向格式菜单添加子菜单,设置键盘标识符,快捷键,添加子菜单监听器formatMenu.add(autoMenu);autoMenu.setMnemonic('W');autoMenu.addActionListener(this);formatMenu.add(sizeMenu);sizeMenu.setMnemonic('F');sizeMenu.addActionListener(this);formatMenu.setMnemonic(KeyEvent.VK_O);// 向查看菜单添加子菜单,设置键盘标识符,快捷键,添加子菜单监听器readMenu.add(stateMenu);stateMenu.setMnemonic('S');stateMenu.addActionListener(this);readMenu.setMnemonic(KeyEvent.VK_V);// 向帮助菜单添加子菜单,设置键盘标识符,快捷键,添加子菜单监听器helpMenu.add(readHelpMenu);readHelpMenu.setMnemonic('H');readHelpMenu.addActionListener(this);helpMenu.addSeparator();helpMenu.add(aboutMenu);aboutMenu.setMnemonic('A');aboutMenu.addActionListener(this);helpMenu.setMnemonic(KeyEvent.VK_H);// 添加菜单和组件jmb.add(fileMenu);jmb.add(editMenu);jmb.add(formatMenu);jmb.add(readMenu);jmb.add(helpMenu);c.add(jsp, BorderLayout.CENTER);c.add(jla, BorderLayout.SOUTH);// 设置文本域字体和自动换行jta.setFont(new Font("宋体", 0, 25));jta.setLineWrap(true);jta.setWrapStyleWord(true);// 单词格式// 设置菜单和子菜单的字体fileMenu.setFont(new Font("宋体", 0, 20));editMenu.setFont(new Font("宋体", 0, 20));formatMenu.setFont(new Font("宋体", 0, 20));readMenu.setFont(new Font("宋体", 0, 20));helpMenu.setFont(new Font("宋体", 0, 20));newMenu.setFont(new Font("宋体", 0, 20));openMenu.setFont(new Font("宋体", 0, 20));saveMenu.setFont(new Font("宋体", 0, 20));saveAnotherMenu.setFont(new Font("宋体", 0, 20));setPageMenu.setFont(new Font("宋体", 0, 20));printMenu.setFont(new Font("宋体", 0, 20));exitMenu.setFont(new Font("宋体", 0, 20));cancelMenu1.setFont(new Font("宋体", 0, 20));cancelMenu2.setFont(new Font("宋体", 0, 20));shearMenu1.setFont(new Font("宋体", 0, 20));shearMenu2.setFont(new Font("宋体", 0, 20));copyMenu1.setFont(new Font("宋体", 0, 20));copyMenu2.setFont(new Font("宋体", 0, 20));pasteMenu1.setFont(new Font("宋体", 0, 20));pasteMenu2.setFont(new Font("宋体", 0, 20));deleteMenu1.setFont(new Font("宋体", 0, 20));deleteMenu2.setFont(new Font("宋体", 0, 20));foundMenu.setFont(new Font("宋体", 0, 20));foundNextMenu.setFont(new Font("宋体", 0, 20));replaceMenu.setFont(new Font("宋体", 0, 20));allSectionMenu1.setFont(new Font("宋体", 0, 20));allSectionMenu2.setFont(new Font("宋体", 0, 20));DateMenu.setFont(new Font("宋体", 0, 20));autoMenu.setFont(new Font("宋体", 0, 20));sizeMenu.setFont(new Font("宋体", 0, 20));stateMenu.setFont(new Font("宋体", 0, 20));readHelpMenu.setFont(new Font("宋体", 0, 20));aboutMenu.setFont(new Font("宋体", 0, 20));jla.setFont(new Font("宋体", 0, 30));// 添加弹出菜单选项pop.add(cancelMenu2);pop.add(shearMenu2);pop.add(copyMenu2);pop.add(pasteMenu2);pop.add(deleteMenu2);pop.add(allSectionMenu2);jta.requestFocus();// 设置窗口属性以及编辑器菜单的可用性checkMenuItemEnabled();foundMenu.setEnabled(false);foundNextMenu.setEnabled(false);cancelMenu1.setEnabled(false);cancelMenu2.setEnabled(false);jla.setVisible(false);setBounds(200, 200, 1114, 744);setVisible(true);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);"

总结:
1.FileDialog 类显示一个对话框窗口,用户可以从中选择文件。构造方法如下:
FileDialog(Frame parent, String title, int mode)
创建一个具有指定标题的文件对话框窗口,用于打开或保存文件。其中mode包括FileDialog.LOAD和FileDialog.SAVE
2.UndoManager与撤销操作有关(这是在CSDN上学到借鉴的代码,详细内容可以去看看API)
3.setMnemonic()方法是菜单的键盘标识符
setAccelerator(KeyStroke keyStroke)
eg:Ctrl+C的快捷键 copyMenu1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK));
setLineWrap(true/false) 设置是否自动换行
setWrapStyleWord(true/false) 设置单词格式
addSeparator() 在菜单栏添加分隔线

添加文本框的监听器

 // 通过内部类添加弹出菜单监听器并实现文本域的鼠标事件jta.addMouseListener(new MouseAdapter() {@Overridepublic void mouseReleased(MouseEvent e) {if (e.getModifiers() == InputEvent.BUTTON3_MASK)pop.show(jta, e.getX(), e.getY());//弹出菜单弹出的位置// 设置编辑中一些功能的可用性checkMenuItemEnabled();jta.requestFocus();}// end mouseReleased}// end MouseAdapter);// end addMouseListener// 通过内部类对文本内容添加监听器jta.getDocument().addDocumentListener(new DocumentListener() {@Overridepublic void changedUpdate(DocumentEvent e) {cancelMenu1.setEnabled(true);cancelMenu2.setEnabled(true);}// end changedUpdate@Overridepublic void insertUpdate(DocumentEvent e) {cancelMenu1.setEnabled(true);cancelMenu2.setEnabled(true);// 当向文本输入内容即文本不为空,查找功能可用foundMenu.setEnabled(true);foundNextMenu.setEnabled(true);}// end insertUpdate@Overridepublic void removeUpdate(DocumentEvent e) {cancelMenu1.setEnabled(true);cancelMenu2.setEnabled(true);// 当删除(所选)文本内容时,将编辑中一些功能禁用shearMenu1.setEnabled(false);shearMenu2.setEnabled(false);copyMenu1.setEnabled(false);copyMenu2.setEnabled(false);deleteMenu1.setEnabled(false);deleteMenu2.setEnabled(false);// 当文本域无内容时,将查找功能禁用if (jta.getText().length() == 0) {foundMenu.setEnabled(false);foundNextMenu.setEnabled(false);} // end if}// end removeUpdate}// end DocumentListener);// end addDocumentListener// 通过内部类对文本内容添加监听器(撤销功能)jta.getDocument().addUndoableEditListener(new UndoableEditListener() {@Overridepublic void undoableEditHappened(UndoableEditEvent e) {undom.addEdit(e.getEdit());}// end undoableEditHappened}// end UndoableEditListener);// end addUndoableEditListener

总结:
1.getDocument() 获取与编辑器关联的模型(对文本域的内容进行监控)
2.setEnabled(true/false) 设置组件的可操作性(例如菜单中的复制操作)

// 通过内部类对窗口添加监听器(右上角关闭按钮)this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {// 如果是新文件,即标题任为记事本,则执行exit()方法if (getTitle() == "记事本")exit();// 如果不是新文件,即有标题为包含".txt"的文件名,则进行判断文本域内容是否与原文件相同// (注意:末尾存在换行问题)(这里有一点小bug)else {try {// 定义3个String对象并获得文件目录String s = _Open.getDirectory(), str1 = "", line = "";if (_Open.getDirectory() == null)s = _Save.getDirectory();// 创建指定文件和读取文件流的对象File f = new File(s + getTitle());BufferedReader r = new BufferedReader(new FileReader(f));// 一行一行的读取文件while ((line = r.readLine()) != null)str1 += line + "\n";// 处理末尾换行问题if (jta.getText().length() > 0) {if (jta.getText().charAt(jta.getText().length() - 1) != '\n')str1 = str1.substring(0, str1.length() - 1);}// 判断两者是否相等,不等则执行exit()方法,相等则直接关闭窗口if (!str1.equals(jta.getText()))exit();elseSystem.exit(0);r.close();} // end trycatch (FileNotFoundException em) {em.printStackTrace();} // end catchcatch (IOException ee) {ee.printStackTrace();} // end catch} // end else}// end windowClosing}// end WindowAdapter);// end addWindowListener}// end 构造方法

总结:WindowAdapter类:接收窗口事件的抽象适配器类。此类中的方法为空。此类存在的目的是方便创建侦听器对象。

//实现接口中的方法@Overridepublic void actionPerformed(ActionEvent e) {if (e.getActionCommand().contains("新建"))news();if (e.getActionCommand().contains("打开"))open();if (e.getActionCommand().contains("保存"))save();if (e.getActionCommand().contains("另存为"))saveAnother();if (e.getActionCommand().contains("页面设置"))setPage();if (e.getActionCommand().contains("打印"))print();if (e.getActionCommand().contains("退出"))exit();if (e.getActionCommand().contains("撤销"))cancel();if (e.getActionCommand().contains("剪切"))shear();if (e.getActionCommand().contains("复制"))copy();if (e.getActionCommand().contains("粘贴"))paste();if (e.getActionCommand().contains("删除"))delete();if (e.getActionCommand().equals("   查找(F)      "))found();if (e.getActionCommand().contains("替换"))replace();if (e.getActionCommand().contains("全选"))allSelection();if (e.getActionCommand().contains("日期"))date();if (e.getActionCommand().contains("自动换行"))auto();if (e.getActionCommand().contains("字体"))font();if (e.getActionCommand().contains("状态栏"))state();if (e.getActionCommand().contains("查看帮助"))readHelp();if (e.getActionCommand().contains("关于记事本"))about();}// 设置编辑器的功能可用性public void checkMenuItemEnabled() {String selectText = jta.getSelectedText();// 文本域没有内容被选中时一些菜单功能不可用if (selectText == null) {shearMenu1.setEnabled(false);shearMenu2.setEnabled(false);copyMenu1.setEnabled(false);copyMenu2.setEnabled(false);deleteMenu1.setEnabled(false);deleteMenu2.setEnabled(false);} // end if// 文本域有内容被选中时菜单功能可用else {shearMenu1.setEnabled(true);shearMenu2.setEnabled(true);copyMenu1.setEnabled(true);copyMenu2.setEnabled(true);deleteMenu1.setEnabled(true);deleteMenu2.setEnabled(true);} // end else}// end checkMenuItemEnabled

新建功能
思路:判断文本域是否有内容,有内容在新建之前弹出是否保存的窗口后再进行新建,无内容则直接新建

private void news() {// 如果文本域有内容执行以下if语句中代码,否则直接执行新建功能if (!jta.getText().equals("")) {// 弹出提示窗口int result = JOptionPane.showConfirmDialog(this, "是否保存", "记事本", JOptionPane.YES_NO_CANCEL_OPTION);// 执行是按钮if (result == JOptionPane.YES_OPTION) {// 如果窗口标题为"记事本"即文件尚未存在,则执行saveAnother()方法进行另存为功能if (getTitle() == "记事本")saveAnother();// 如果窗口标题为包含“.txt”的文件名即文件已存在,则执行save()方法进行保存功能elsesave();// 保存后将文本域内容清空并将标题改为"记事本",完成新建功能jta.setText("");setTitle("记事本");} // end if// 执行否按钮,即不进行保存工作,直接将文本域内容清空并将窗口标题改为"记事本"完成新建功能if (result == JOptionPane.NO_OPTION) {jta.setText("");setTitle("记事本");} // end if} // end if}// end news()

总结:
JOptionPane 有助于方便地弹出要求用户提供值或向其发出通知的标准对话框。其中的一些方法如下:

方法名 描述
showConfirmDialog 询问一个确认问题,如 yes/no/cancel
showInputDialog 提示要求某些输入
showMessageDialog 告知用户某事已发生
showOptionDialog 上述三项的大统一 (Grand Unification)

messageType
定义 message 的样式。外观管理器根据此值对对话框进行不同地布置,并且通常提供默认图标。可能的值为:
ERROR_MESSAGE ;INFORMATION_MESSAGE; WARNING_MESSAGE;QUESTION_MESSAGE ;
PLAIN_MESSAGE
optionType
定义在对话框的底部显示的选项按钮的集合:
DEFAULT_OPTION ;YES_NO_OPTION ;
YES_NO_CANCEL_OPTION ;OK_CANCEL_OPTION

例子:JOptionPane.showConfirmDialog(this, “是否保存”, “记事本”, JOptionPane.YES_NO_CANCEL_OPTION);

打开功能
思路:打开前先弹出是否保存的窗口判断是否对当前内容进行保存,然后在弹出打开窗口选择目标文件打开,若未选择目标文件(关闭选择文件的窗口),文本域的内容不变化,仍为执行打开前的内容

// 打开功能的实现方法private void open() {String str = "";// 打开操作前判断是否进行保存工作// if (getTitle() != "记事本" || jta.getText() != null) {int result = JOptionPane.showConfirmDialog(this, "是否保存", "记事本", JOptionPane.YES_NO_CANCEL_OPTION);if (result == JOptionPane.YES_OPTION)save();if (result == JOptionPane.YES_OPTION || result == JOptionPane.NO_OPTION) {_Open.setVisible(true);// 将打开窗口可视化try {// 获得文件名并创建流File f = new File(_Open.getDirectory() + _Open.getFile());BufferedReader r = new BufferedReader(new FileReader(f));if (_Open.getFile() != null) {jta.setText("");// 读取文件内容并写入文本域中while ((str = r.readLine()) != null)jta.append(str + "\n");// 将窗口标题设置为打开文件的文件名// if (_Open.getFile() != null)this.setTitle(_Open.getFile());}r.close();} // end trycatch (FileNotFoundException e) {// 所指定的打开文件如果不存在则弹出错误窗口JOptionPane.showMessageDialog(null, "所选文件不存在或未选择文件", "错误", JOptionPane.ERROR_MESSAGE);} // end catchcatch (IOException e) {e.printStackTrace();} // end catch} // end if}// end open

保存功能
思路:若文件不存在,则弹出另存为窗口,若文件已存在,则只弹出是否保存的窗口

// 保存功能的实现方法private void save() {// 如果窗口标题为 "记事本"即不是文件名,直接执行saveAnother()方法if (this.getTitle() == "记事本")saveAnother();// 否则,执行保存功能else {try {// 创建指定文件和输出流的对象File f = new File(_Open.getDirectory() + this.getTitle());BufferedWriter w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f)));// 将文本域的内容转换为字符并写入指定文件中char[] str = jta.getText().toCharArray();for (int i = 0; i < str.length; i++) {if (str[i] != '\n')w.write(str[i]);elsew.newLine();} // end forw.close();} // end trycatch (IOException e) {e.printStackTrace();} // end catch} // end else}// end save

另存为功能
思路:弹出保存窗口,选择保存路径及文件名

// 另存为功能的方法private void saveAnother() {// 将另存为弹出的界面可视化_Save.setVisible(true);try {// 创建指定文件和写文件流的对象File f = new File(_Save.getDirectory() + _Save.getFile());BufferedWriter w = new BufferedWriter(new FileWriter(f));// 将文本域的内容转换为字符并写入指定文件中char[] str = jta.getText().toCharArray();for (int i = 0; i < str.length; i++) {if (str[i] != '\n')w.write(str[i]);elsew.newLine();} // end for// 实现另存为功能后将窗口标题改为所存的文件名,未实现则只关闭提示窗口不关闭主窗口if (_Save.getFile() != null)this.setTitle(_Save.getFile());setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);w.close();} // end trycatch (IOException e) {e.printStackTrace();} // end catch}// end saveAnother// 打印的方法private void print() {JOptionPane.showMessageDialog(null, "对不起,此菜单功能尚未实现!", "打印", JOptionPane.YES_NO_CANCEL_OPTION);}// 页面设置的方法private void setPage() {JOptionPane.showMessageDialog(null, "对不起,此菜单功能尚未实现!", "页面设置", JOptionPane.YES_NO_CANCEL_OPTION);}

总结:设置用户在此窗体上发起 “close” 时默认执行的操作。必须指定以下选项之一:
DO_NOTHING_ON_CLOSE(在 WindowConstants 中定义):不执行任何操作;要求程序在已注册的 WindowListener 对象的 windowClosing 方法中处理该操作。
HIDE_ON_CLOSE(在 WindowConstants 中定义):调用任意已注册的 WindowListener 对象后自动隐藏该窗体。
DISPOSE_ON_CLOSE(在 WindowConstants 中定义):调用任意已注册 WindowListener 的对象后自动隐藏并释放该窗体。
EXIT_ON_CLOSE(在 JFrame 中定义):使用 System exit 方法退出应用程序。仅在应用程序中使用。
默认情况下,该值被设置为 HIDE_ON_CLOSE。更改此属性的值将导致激发属性更改事件,其属性名称为 “defaultCloseOperation”。

关闭功能
思路:弹出是否保存窗口选择后关闭窗口

// 关闭的方法private void exit() {int result = JOptionPane.showConfirmDialog(this, "是否保存", "记事本", JOptionPane.YES_NO_CANCEL_OPTION);// 执行是按钮if (result == JOptionPane.YES_OPTION) {// 判断标题是否为包含“.txt”的文件名,是则执行save()方法并关闭窗口if (this.getTitle().contains(".txt")) {save();System.exit(0);}// 标题为“记事本”即为非文件名,执行saveAnother()方法,另存为动作完毕后,直接关闭窗口else {saveAnother();if (getTitle() != "记事本")System.exit(0);} // end else} // end if// 执行否按钮,直接关闭窗口if (result == JOptionPane.NO_OPTION)System.exit(1);// 设置提示窗口的属性,即未操作则只关闭提示窗口而不关闭主窗口setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);}// end exit

编辑器的撤销、剪切、复制、粘贴、删除、全选功能

 // 撤销的方法(有bug)private void cancel() {if (undom.canUndo()) // 撤销undom.undo();elseundom.redo();// 恢复}// end cancel// 剪贴的方法private void shear() {copy();// 复制所选段// 标记开始结束位置int start = jta.getSelectionStart(), end = jta.getSelectionEnd();jta.replaceRange("", start, end);// 删除所选段}// end shear// 复制的方法private void copy() {jta.requestFocus();String temp = jta.getSelectedText();// 拖动选取文本StringSelection text = new StringSelection(temp);// 把获取内容复制到连续字符器getToolkit().getSystemClipboard().setContents(text, null);// 把内容放在剪贴板}// end copy// 粘贴的方法private void paste() {// Transferable接口,把剪贴板内容转换为数据Transferable contents = getToolkit().getSystemClipboard().getContents(this);// DataFlavor类判断是否能把剪贴板的内容转换为所需数据的类型DataFlavor flavor = DataFlavor.stringFlavor;// 如果能转换if (contents.isDataFlavorSupported(flavor)) {String str;try {// 开始转换str = (String) contents.getTransferData(flavor);// 鼠标已选中内容if (jta.getSelectedText() != null) {// 定义被选中内容的开始和末尾位置int start = jta.getSelectionStart(), end = jta.getSelectionEnd();jta.replaceRange(str, start, end);// 把选中的内容替换为剪贴板的内容} // end if// 鼠标未选中内容else {// 获得鼠标在文本域的位置并插入剪贴板的内容int mouse = jta.getCaretPosition();jta.insert(str, mouse);} // end else} // end trycatch (UnsupportedFlavorException e) {e.printStackTrace();} // end catchcatch (IOException e) {e.printStackTrace();} // end catchcatch (IllegalArgumentException e) {e.printStackTrace();} // end catch} // end if}// end paste// 删除的方法private void delete() {jta.replaceSelection("");}// 全选的方法private void allSelection() {jta.selectAll();}// end allSelection

总结:
1./标记开始结束位置
int start = jta.getSelectionStart(), end = jta.getSelectionEnd();
jta.replaceRange(str, start, end); 将选中的内容替换为str
2.requestFocus() 方法用于请求此 Component 获取输入焦点。
getCaretPosition()方法用于获得鼠标在文本域的位置
setCaretPosition()方法用于设置鼠标在文本域的位置
insert(str, mouse)方法用于在光标位置插入字符串str
3.粘贴方法的实现
StringSelection(String data) 此构造方法用于创建能传输指定 String 的 Transferable。
getToolkit().getSystemClipboard().setContents(text, null); 把内容放在剪贴板 Transferable接口,把剪贴板内容转换为数据
Transferable contents = getToolkit().getSystemClipboard().getContents(this);
DataFlavor类判断是否能把剪贴板的内容转换为所需数据的类型
DataFlavor flavor = DataFlavor.stringFlavor;
判断是否能转换 :contents.isDataFlavorSupported(flavor)
能转换则转为字符串准备进行粘贴工作 (String)contents.getTransferData(flavor)

查找功能
思路:创建查找窗口,并给其组件添加监听器(注意是否区分大小写,查找的方向)。窗口的截图和代码如下

 // 查找的方法private void found() {// 创建查找窗口所需组件JDialog findDialog = new JDialog(this, "查找", false);Container con = findDialog.getContentPane();JLabel findLabel = new JLabel("查找内容(N)");JTextField findText = new JTextField((15));JButton findNextButton = new JButton("查找下一个");JButton cancelButton = new JButton("取消");JRadioButton upButton = new JRadioButton("向上(U)");JRadioButton downButton = new JRadioButton("向下(D)");ButtonGroup bg = new ButtonGroup();JCheckBox findCheckButton = new JCheckBox("区分大小写");GridLayout g = new GridLayout(2, 1);g.setVgap(10);// 设置网格布局器的垂直间距bg.add(upButton);bg.add(downButton);JPanel p1 = new JPanel();JPanel p2 = new JPanel();JPanel p3 = new JPanel();JPanel p4 = new JPanel();JPanel p5 = new JPanel();p3.setBorder(BorderFactory.createTitledBorder("方向"));// 设置布局管理器con.setLayout(new FlowLayout());p4.setLayout(new BorderLayout());p5.setLayout(g);// 添加组件p1.add(findLabel);p1.add(findText);p2.add(findCheckButton);p2.add(p3);p3.add(upButton);p3.add(downButton);p4.add(p1, BorderLayout.NORTH);p4.add(p2, BorderLayout.CENTER);p5.add(findNextButton);p5.add(cancelButton);con.add(p4, BorderLayout.CENTER);con.add(p5, BorderLayout.EAST);// 设置查找窗口属性downButton.setSelected(true);// 默认向下查找findNextButton.setEnabled(false);findDialog.setBounds(230, 280, 410, 150);findDialog.setResizable(false);findDialog.setVisible(true);// 添加取消按钮的监听器(内部类的形式)cancelButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {findDialog.dispose();}// end actionPerformed}// end ActionListener);// end addActionListener// 添加查找文本框内容的监听器(内部类的形式)findText.getDocument().addDocumentListener(new DocumentListener() {@Overridepublic void changedUpdate(DocumentEvent e) {}@Override// 查找文本框内容不为空时查找按钮可用public void insertUpdate(DocumentEvent e) {findNextButton.setEnabled(true);}// end insertUpdate@Override// 查找文本框内容为空时查找按钮不可用public void removeUpdate(DocumentEvent e) {if (findText.getText().length() == 0)findNextButton.setEnabled(false);}// end removeUpdate}// end ActionListener);// end addActionListener// 添加查找下一个按钮的监听器(内部类的形式)findNextButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {int k = 0;String str1, str2, str3, str4, strA, strB;str1 = jta.getText();str2 = findText.getText();str3 = str1.toUpperCase();str4 = str2.toUpperCase();// 区分大小写if (findCheckButton.isSelected()) {strA = str1;strB = str2;}// 不区分大小写else {strA = str3;strB = str4;}// 向上查找的方式if (upButton.isSelected()) {// 文本未选中内容if (jta.getSelectedText() == null)k = strA.lastIndexOf(strB, jta.getCaretPosition());// 文本已选中内容elsek = strA.lastIndexOf(strB, jta.getCaretPosition() - strB.length() - 1);// 查找未结束,继续向上查找if (k != -1) {jta.setCaretPosition(k);jta.select(k, k + strB.length());}// 查找结束,弹出错误窗口elseJOptionPane.showMessageDialog(null, "找不到" + " “ " + findText.getText() + " ” ", "查找",JOptionPane.INFORMATION_MESSAGE);} // end 向上查找// 向下查找的方式else if (downButton.isSelected()) {// 文本未选中内容if (jta.getSelectedText() == null) {k = strA.indexOf(strB, jta.getCaretPosition());}// 文本已选中内容elsek = strA.indexOf(strB, jta.getCaretPosition() - strB.length() + 1);// 查找未结束,继续向下查找if (k != -1) {jta.setCaretPosition(k);jta.select(k, k + strB.length());}// 查找结束,弹出错误窗口elseJOptionPane.showMessageDialog(null, "找不到" + " “ " + findText.getText() + " ” ", "查找",JOptionPane.INFORMATION_MESSAGE);} // end 向下查找}// end actionPerformed}// end ActionListener);// end addActionListener// 添加菜单中查找下一个菜单的监听器(有bug)foundNextMenu.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {int k = 0;String str1, str2, str3, str4, strA, strB;str1 = jta.getText();str2 = findText.getText();str3 = str1.toUpperCase();str4 = str2.toUpperCase();// 区分大小写if (findCheckButton.isSelected()) {strA = str1;strB = str2;}// 不区分大小写else {strA = str3;strB = str4;}// 向上查找的方式if (upButton.isSelected()) {// 文本未选中内容if (jta.getSelectedText() == null)k = strA.lastIndexOf(strB, jta.getCaretPosition());// 文本已选中内容elsek = strA.lastIndexOf(strB, jta.getCaretPosition() - strB.length() - 1);// 查找未结束,继续向上查找if (k != -1) {jta.setCaretPosition(k);jta.select(k, k + strB.length());}// 查找结束,弹出错误窗口elseJOptionPane.showMessageDialog(null, "找不到" + " “ " + findText.getText() + " ” ", "查找",JOptionPane.INFORMATION_MESSAGE);} // end 向上查找// 向下查找的方式else if (downButton.isSelected()) {// 文本未选中内容if (jta.getSelectedText() == null) {k = strA.indexOf(strB, jta.getCaretPosition());}// 文本已选中内容elsek = strA.indexOf(strB, jta.getCaretPosition() - strB.length() + 1);// 查找未结束,继续向下查找if (k != -1) {jta.setCaretPosition(k);jta.select(k, k + strB.length());}// 查找结束,弹出错误窗口elseJOptionPane.showMessageDialog(null, "找不到" + " “ " + findText.getText() + " ” ", "查找",JOptionPane.INFORMATION_MESSAGE);} // end 向下查找}// end actionPerformed}// end ActionListener);// end addActionListener}// end found

总结:
1.JDialog(Dialog owner, String title, boolean modal)
此构造方法用于创建一个具有指定标题、模式和指定所有者 Dialog 的自定义对话框。参数如下:
owner - 显示该对话框的所有者 Dialog;如果此对话框没有所有者,则为 null
title - 该对话框的标题栏中所显示的 String
modal - 指定对话框在显示时是否阻塞用户向其他顶层窗口输入。如果为 true,则模式类型属性被设置为 DEFAULT_MODALITY_TYPE;否则对话框是无模式的
2.网络布局管理器中setHgap(int hgap) 方法用于将组件之间的水平间距设置为指定值。setVgap(int vgap) 方法用于将组件之间的垂直间距设置为指定值。
3.setSelected(true/false)方法用于默认选中组件
dispose()方法简单地理解可理解为关闭窗口。
select(int start,int end) 选中内容范围
setBorder(BorderFactory.createTitledBorder(String str))方法用于向现有边框添加一个标题,使其具有默认的位置(位于顶线上)、默认的调整 (leading),以及默认的字体和文本颜色。(BorderFactory类具体构造方法可参考API)

替换功能
思路:与查找功能基本一致,通过查找功能将查找出的内容替换。窗口截图和代码如下。

// 替换的方法private void replace() {// 定义替换提示窗口所需组件JDialog replaceDialog = new JDialog(this, "替换", false);Container replaceCon = replaceDialog.getContentPane();JLabel findContentLabel = new JLabel("查找内容(N):");JLabel replaceLabel = new JLabel("替换为(P):");JTextField findField = new JTextField(15);JTextField replaceField = new JTextField(15);JButton findNextButton = new JButton("查找下一个(F)");JButton replaceButton = new JButton("替换(R)");JButton replaceAllButton = new JButton("全部替换(A)");JButton cancelButton = new JButton("取消");JCheckBox checkButton = new JCheckBox("区分大小写");JRadioButton upButton = new JRadioButton("向上(U)");JRadioButton downButton = new JRadioButton("向下(D)");ButtonGroup bg = new ButtonGroup();bg.add(upButton);bg.add(downButton);GridLayout g = new GridLayout(4, 1);JPanel p1 = new JPanel();JPanel p2 = new JPanel();JPanel p3 = new JPanel();JPanel p4 = new JPanel();JPanel p5 = new JPanel();JPanel p6 = new JPanel();JPanel p7 = new JPanel();p2.setBorder(BorderFactory.createTitledBorder("方向"));// 设置布局管理器p1.setLayout(new BorderLayout());p4.setLayout(new BorderLayout());p5.setLayout(g);g.setVgap(5);// 设置网格布局管理器垂直间距p6.setLayout(new BorderLayout());p7.setLayout(new BorderLayout());replaceCon.setLayout(new FlowLayout(10));// 添加组件p1.add(findContentLabel, BorderLayout.NORTH);p1.add(replaceLabel, BorderLayout.CENTER);p6.add(findField, BorderLayout.NORTH);p6.add(replaceField, BorderLayout.CENTER);p7.add(p1, BorderLayout.WEST);p7.add(p6, BorderLayout.CENTER);p2.add(upButton);p2.add(downButton);p3.add(checkButton);p3.add(p2);p4.add(p7, BorderLayout.NORTH);p4.add(p3, BorderLayout.CENTER);p5.add(findNextButton);p5.add(replaceButton);p5.add(replaceAllButton);p5.add(cancelButton);replaceCon.add(p4);replaceCon.add(p5);// 设置替换窗口属性downButton.setSelected(true);// 默认向下查找findNextButton.setEnabled(false);replaceButton.setEnabled(false);replaceAllButton.setEnabled(false);replaceDialog.setBounds(230, 280, 410, 180);replaceDialog.setVisible(true);replaceDialog.setResizable(false);// 添加取消按钮的监听器(内部类的形式)cancelButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {replaceDialog.dispose();}// end actionPerformed}// end ActionListener);// end addActionListener// 通过内部类的形式添加文本域内容的监听器findField.getDocument().addDocumentListener(new DocumentListener() {@Overridepublic void changedUpdate(DocumentEvent e) {}@Override// 查找文本框内容不为空时查找按钮,替换按钮,全部替换按钮都可用public void insertUpdate(DocumentEvent e) {findNextButton.setEnabled(true);replaceButton.setEnabled(true);replaceAllButton.setEnabled(true);}// end insertUpdate@Override// 查找文本框内容为空时查找按钮,替换按钮,全部替换按钮都不可用public void removeUpdate(DocumentEvent e) {if (findField.getText().length() == 0) {findNextButton.setEnabled(false);replaceButton.setEnabled(false);replaceAllButton.setEnabled(false);}}// end removeUpdate}// end DocumentListener);// end addDocumentListener// 添加查找下一个按钮的监听器(内部类的形式)findNextButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {int k;String str1, str2, str3, str4, strA, strB;str1 = jta.getText();str2 = findField.getText();str3 = str1.toUpperCase();str4 = str2.toUpperCase();// 区分大小写if (checkButton.isSelected()) {strA = str1;strB = str2;}// 不区分大小写else {strA = str3;strB = str4;}// 向上查找的方式if (upButton.isSelected()) {// 文本未选中内容if (jta.getSelectedText() == null)k = strA.lastIndexOf(strB, jta.getCaretPosition());// 文本已选中内容elsek = strA.lastIndexOf(strB, jta.getCaretPosition() - strB.length() - 1);// 查找未结束,继续向上查找if (k != -1) {jta.setCaretPosition(k);jta.select(k, k + strB.length());}// 查找结束,弹出错误窗口elseJOptionPane.showMessageDialog(null, "找不到" + " “ " + findField.getText() + " ” ", "查找",JOptionPane.INFORMATION_MESSAGE);} // end 向上查找// 向下查找的方式else if (downButton.isSelected()) {// 文本未选中内容if (jta.getSelectedText() == null)k = strA.lastIndexOf(strB, jta.getCaretPosition());// 文本已选中内容elsek = strA.lastIndexOf(strB, jta.getCaretPosition() - strB.length() + 1);// 查找未结束,继续向下查找if (k != -1) {jta.setCaretPosition(k);jta.select(k, k + strB.length());}// 查找结束,弹出错误窗口elseJOptionPane.showMessageDialog(null, "找不到" + " “ " + findField.getText() + " ” ", "查找",JOptionPane.INFORMATION_MESSAGE);} // end 向下查找}// end actionPerformed}// end ActionListener);// end addActionListener// 添加替换按钮的监听器(内部类的形式)replaceButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {int k = 0;String str1, str2, str3, str4, str5, strA, strB;str1 = jta.getText();str2 = findField.getText();str3 = str1.toUpperCase();str4 = str2.toUpperCase();str5 = replaceField.getText();// 区分大小写if (checkButton.isSelected()) {strA = str1;strB = str2;}// 不区分大小写else {strA = str3;strB = str4;}// 向上查找的方式if (upButton.isSelected()) {// 文本未选中内容if (jta.getSelectedText() == null)k = strA.lastIndexOf(strB, jta.getCaretPosition());// 文本已选中内容elsek = strA.lastIndexOf(strB, jta.getCaretPosition() - strB.length() - 1);// 查找未结束,继续向上查找if (k != -1) {// 将所查找的内容替换并选中jta.setCaretPosition(k);jta.select(k, k + strB.length());jta.replaceSelection(str5);jta.select(k, k + str5.length());}// 查找替换结束,弹出错误窗口elseJOptionPane.showMessageDialog(null, "找不到" + " “ " + findField.getText() + " ” ", "替换",JOptionPane.INFORMATION_MESSAGE);} // end 向上查找// 向下查找的方式else if (downButton.isSelected()) {// 文本未选中内容if (jta.getSelectedText() == null)k = strA.indexOf(strB, jta.getCaretPosition());// 文本已选中内容elsek = strA.indexOf(strB, jta.getCaretPosition() - strB.length() + 1);// 查找未结束,继续向下查找if (k != -1) {// 将所查找的内容替换并选中jta.setCaretPosition(k);jta.select(k, k + strB.length());jta.replaceSelection(str5);jta.select(k, k + str5.length());}// 查找替换结束,弹出错误窗口elseJOptionPane.showMessageDialog(null, "找不到" + " “ " + findField.getText() + " ” ", "替换",JOptionPane.INFORMATION_MESSAGE);}}// end ActionPerformed}// end ActionListener);// end addActionListener// 添加全部替换按钮的监听器(内部类)replaceAllButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {int k = 0;String str1, str2, str3, str4, str5, strA, strB;str1 = jta.getText();str2 = findField.getText();str3 = str1.toUpperCase();str4 = str2.toUpperCase();str5 = replaceField.getText();// 区分大小写if (checkButton.isSelected()) {strA = str1;strB = str2;}// 不区分大小写else {strA = str3;strB = str4;}// 如果文本未选中内容,将文本中所查找的内容全部替换if (jta.getSelectedText() != null)jta.setText(jta.getText().replace(jta.getSelectedText(), jta.getSelectedText().replace(strB, str5)));// 如果文本有选中的内容,则在此内容内将所查找的内容全部替换elsejta.setText(jta.getText().replace(strB, str5));}// end actionPerformed}// end ActionListener);// end addActionListener}// end replace

插入当前时间的功能
思路:在光标位置插入当前时间

// 获取当前时间的方法private void date() {Calendar cal = Calendar.getInstance();GregorianCalendar time = new GregorianCalendar();// 获得小时,分钟,秒钟并解决小于10的问题String hour = "" + time.get(Calendar.HOUR_OF_DAY), min = "" + time.get(Calendar.MINUTE),second = "" + time.get(Calendar.SECOND), year = "" + cal.get(Calendar.YEAR),month = cal.get(Calendar.MONTH) + 1 + "", day = "" + cal.get(Calendar.DATE);if (Integer.valueOf(hour).intValue() < 10)hour = "0" + hour;if (Integer.valueOf(min).intValue() < 10)min = "0" + min;if (Integer.valueOf(second).intValue() < 10)second = "0" + second;if (Integer.valueOf(month).intValue() < 10)month = "0" + month;if (Integer.valueOf(day).intValue() < 10)day = "0" + day;String str = "当前时间:" + hour + ":" + min + ":" + second + " " + year + "/" + month + "/" + day;// 将鼠标所指位置插入当前时间jta.insert(str, jta.getCaretPosition());}// end date```

自动换行功能

 // 自动换行的方法private void auto() {// 判断自动换行菜单按钮是否被选中if (!autoMenu.isSelected())jta.setLineWrap(false);elsejta.setLineWrap(true);}// end auto

字体功能
思路:通过列表来设置文本框内容的字体、字形、大小。窗口截图和代码如下

 // 自定义方法返回字体大小(有偏差)private int setSize(JTextField jtf, int size) {switch (jtf.getText()) {case "初号":size = 42;break;case "小初":size = 36;break;case "一号":size = 26;break;case "小一":size = 24;break;case "二号":size = 22;break;case "小二":size = 18;break;case "三号":size = 16;break;case "小三":size = 15;break;case "四号":size = 14;break;case "小四":size = 12;break;case "五号":size = 11;break;case "小五":size = 9;break;case "六号":size = 8;break;case "小六":size = 7;break;case "七号":size = 6;break;case "八号":size = 5;break;default:size = Integer.valueOf(jtf.getText());}return size;}// end setSize// 字体的方法private void font() {String fontName[] = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();String styleName[] = { "常规", "粗体", "斜体", "粗斜体" };String sizeName[] = { "8", "9", "10", "11", "12", "14", "16", "18", "20", "22", "24", "26", "28", "36", "48","72", "初号", "小初", "一号", "小一", "二号", "小二", "三号", "小三", "四号", "小四", "五号", "小五", "六号", "小六", "七号", "八号" };String script[] = { "中文GB2312", "西欧语言", "希腊语", "中欧字符" };// 定义字体窗口所需的组件JDialog fontDialog = new JDialog(this, "字体", false);Container sizeCon = fontDialog.getContentPane();JLabel fontLabel = new JLabel("字体(F)");JLabel styleLabel = new JLabel("字形(Y)");JLabel sizeLabel = new JLabel("大小(S)");JLabel scriptLable = new JLabel("脚本(R)");JLabel nullLabel = new JLabel();JTextField egjtf = new JTextField(20);JTextField fontField = new JTextField(15);JTextField styleField = new JTextField(15);JTextField sizeField = new JTextField(5);JComboBox scriptBox = new JComboBox(script);JList fontList = new JList(fontName);JList styleList = new JList(styleName);JList sizeList = new JList(sizeName);JScrollPane jsp1 = new JScrollPane(fontList);JScrollPane jsp2 = new JScrollPane(styleList);JScrollPane jsp3 = new JScrollPane(sizeList);JButton bt1 = new JButton("确定");JButton bt2 = new JButton("取消");JPanel p1 = new JPanel();JPanel p2 = new JPanel();JPanel p3 = new JPanel();JPanel p4 = new JPanel();JPanel p5 = new JPanel();JPanel p6 = new JPanel();JPanel p7 = new JPanel();JPanel p8 = new JPanel();JPanel p9 = new JPanel();JPanel p10 = new JPanel();// 设置布局管理器p1.setLayout(new BorderLayout());p2.setLayout(new BorderLayout());p3.setLayout(new BorderLayout());p4.setLayout(new FlowLayout(20, 20, FlowLayout.CENTER));p5.setLayout(new BorderLayout());p6.setLayout(new BorderLayout(10, 10));p7.setLayout(new FlowLayout(10, 10, FlowLayout.CENTER));p8.setLayout(new BorderLayout(10, 10));p9.setLayout(new BorderLayout(330, 20));// 添加组件p1.add(fontLabel, BorderLayout.NORTH);p1.add(fontField, BorderLayout.CENTER);p1.add(jsp1, BorderLayout.SOUTH);p2.add(styleLabel, BorderLayout.NORTH);p2.add(styleField, BorderLayout.CENTER);p2.add(jsp2, BorderLayout.SOUTH);p3.add(sizeLabel, BorderLayout.NORTH);p3.add(sizeField, BorderLayout.CENTER);p3.add(jsp3, BorderLayout.SOUTH);p4.add(p1);p4.add(p2);p4.add(p3);p5.setBorder(BorderFactory.createTitledBorder("示例"));p5.add(egjtf, BorderLayout.NORTH);p5.add(nullLabel, BorderLayout.CENTER);p6.add(scriptBox, BorderLayout.CENTER);p6.add(scriptLable, BorderLayout.NORTH);p10.add(p6);p7.add(bt1);p7.add(bt2);p8.add(p5, BorderLayout.NORTH);p8.add(p6, BorderLayout.CENTER);p8.add(p7, BorderLayout.SOUTH);p9.add(nullLabel, BorderLayout.WEST);p9.add(p8, BorderLayout.CENTER);sizeCon.add(p4, BorderLayout.NORTH);sizeCon.add(p9, BorderLayout.CENTER);// 设置示例文本框的属性egjtf.setFont(new Font(jta.getFont().getFontName(), jta.getFont().getStyle(), jta.getFont().getSize()));egjtf.setHorizontalAlignment(JTextField.CENTER);egjtf.setEnabled(false);// 设置标签,文本框,列表,下拉列表的字体属性fontLabel.setFont(new Font("宋体", 0, 20));styleLabel.setFont(new Font("宋体", 0, 20));sizeLabel.setFont(new Font("宋体", 0, 20));fontField.setFont(new Font("宋体", 0, 20));styleField.setFont(new Font("宋体", 0, 20));sizeField.setFont(new Font("宋体", 0, 20));fontList.setFont(new Font("宋体", 0, 20));styleList.setFont(new Font("宋体", 0, 20));sizeList.setFont(new Font("宋体", 0, 20));scriptLable.setFont(new Font("宋体", 0, 20));scriptBox.setFont(new Font("宋体", 0, 20));// 设置窗口属性fontDialog.setVisible(true);setEnabled(false);fontDialog.setResizable(false);fontDialog.setBounds(200, 200, 600, 480);// 设置文本框的初始内容fontField.setText(jta.getFont().getFontName());egjtf.setText(jta.getFont().getFontName());if (jta.getFont().getStyle() == Font.PLAIN)styleField.setText("常规");if (jta.getFont().getStyle() == Font.ITALIC)styleField.setText("倾斜");if (jta.getFont().getStyle() == Font.BOLD)styleField.setText("粗体");if (jta.getFont().getStyle() == Font.BOLD + Font.ITALIC)styleField.setText("粗斜体");// 以数字的形式设置初始字体大小文本框的内容for (int i = 0; i < 100000; i++) {if (jta.getFont().getSize() == i)sizeField.setText(i + "");}// 添加下拉列表的监听器(内部类的形式)scriptBox.addItemListener(new ItemListener() {@Overridepublic void itemStateChanged(ItemEvent e) {// 通过选择下拉列表来设置示例文本框的内容if (scriptBox.getSelectedIndex() == 0)egjtf.setText(fontField.getText());if (scriptBox.getSelectedIndex() == 1)egjtf.setText("ABCYyZz");if (scriptBox.getSelectedIndex() == 2)egjtf.setText("AaBbAαBβ");if (scriptBox.getSelectedIndex() == 3)egjtf.setText("AaBbÁáÔô");}// end itemStateChanged}// end ItemListener);// end addItemListenerfontField.selectAll();fontList.setSelectedValue(jta.getFont().getFontName(), true);// 从列表中选择指定的对象// 添加字体列表的监听器(内部类的形式)fontList.addListSelectionListener(new ListSelectionListener() {@Overridepublic void valueChanged(ListSelectionEvent e) {int size = 0;// 定义字体大小变量fontField.setText(fontName[fontList.getSelectedIndex()]);// 将字体文本框内容变为所选字体名称// 选中字体文本框中的内容(有颜色)fontField.requestFocus();fontField.select(0, fontField.getText().length());// 通过自定义的方法获得字体大小并将示例文本框的字体设置为目标字体属性size = setSize(sizeField, size);egjtf.setFont(new Font(fontField.getText(), styleList.getSelectedIndex(), size));}// end valueChanged}// end ListSelectionListener);// end addListSelectionListener// 添加字形列表的监听器(内部类的形式)styleList.addListSelectionListener(new ListSelectionListener() {@Overridepublic void valueChanged(ListSelectionEvent e) {int size = 0;// 定义字体大小变量styleField.setText((String) styleList.getSelectedValue());// 将字形文本框内容变为所选字形名称// 选中字体文本框中的内容(有颜色)styleField.requestFocus();styleField.select(0, styleField.getText().length());// 通过自定义的方法获得字体大小并将示例文本框的字体设置为目标字体属性size = setSize(sizeField, size);egjtf.setFont(new Font(fontField.getText(), styleList.getSelectedIndex(), size));}// end valueChanged}// end ListSelectionListener);// end addListSelectionListener// 添加字体大小列表的监听器(内部类的形式)sizeList.addListSelectionListener(new ListSelectionListener() {@Overridepublic void valueChanged(ListSelectionEvent e) {int size = 0;// 定义字体大小变量sizeField.setText((String) sizeList.getSelectedValue());// 将字形文本框内容变为所选字体大小// 选中字体文本框中的内容(有颜色)sizeField.requestFocus();sizeField.select(0, sizeField.getText().length());// 通过自定义的方法获得字体大小并将示例文本框的字体设置为目标字体属性size = setSize(sizeField, size);egjtf.setFont(new Font(fontField.getText(), styleList.getSelectedIndex(), size));}// end valueChanged}// end ListSelectionListener);// end addListSelectionListener// 添加确定按钮的监听器bt1.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {int size = 0, len = 0;// 定义字体大小和fontName的长度变量String fontname = fontField.getText(), style = styleField.getText();// 定义fontname和字形字符串变量try {size = setSize(sizeField, size);// 通过自定义的方法获得字体大小// 通过for循环判断字体文本框的内容在系统中是否存在,存在则跳出循环,不存在则至循环结束for (len = 0; len < fontName.length; len++) {if (fontname.equals(fontName[len]))break;}// 如果if条件成立,即for循环完整的结束,抛出匹配异常if (len == fontName.length)throw new InputMismatchException();// 如果if条件成立,即字形文本框内容中的字形有误,抛出匹配异常if (!(style.equals("常规") || style.equals("斜体") || style.equals("粗体") || style.equals("粗斜体")))throw new InputMismatchException();// 设置记事本文本框的字体属性jta.setFont(new Font(fontname, styleList.getSelectedIndex(), size));// 设置完关闭字体窗口并将记事本窗口恢复可操作性fontDialog.dispose();setEnabled(true);} // end trycatch (InputMismatchException em) {// 如果字体名称系统不存在,捕获异常,弹出警告窗口if (len == fontName.length)JOptionPane.showMessageDialog(null, "没有该名称的字体" + "\n请从字体列表中选择字体", "字体",JOptionPane.WARNING_MESSAGE);// 如果字形名称输入有误,捕获异常,弹出警告窗口if (!(style.equals("常规") || style.equals("斜体") || style.equals("粗体") || style.equals("粗斜体")))JOptionPane.showMessageDialog(null, "没有该字形的字体" + "\n请从字形列表中选择字形", "字体",JOptionPane.WARNING_MESSAGE);} // end catchcatch (NumberFormatException en) {// 如果输入的字体大小不是整数,捕获异常,弹出警告窗口JOptionPane.showMessageDialog(null, "“大小”必须是整数", "字体", JOptionPane.WARNING_MESSAGE);} // end catch}// end actionPerformed}// end ActionEvent);// end addActionEvent// 添加取消按钮的监听器(内部类的形式)bt2.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// 不设置字体,关闭字体窗口并将记事本窗口恢复可操作性fontDialog.dispose();setEnabled(true);}// end actionPerformed}// end ActionListener);// end addActionListener// 添加字体文本框的监听器(内部类的形式)fontField.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {int size = 0, len = 0;// 定义字体大小和fontName的长度变量String fontname = fontField.getText(), style = styleField.getText();// 定义fontname和字形字符串变量try {size = setSize(sizeField, size);// 通过自定义的方法获得字体大小// 通过for循环判断字体文本框的内容在系统中是否存在,存在则跳出循环,不存在则至循环结束for (len = 0; len < fontName.length; len++) {if (fontname.equals(fontName[len]))break;}// 如果if条件成立,即for循环完整的结束,抛出匹配异常if (len == fontName.length)throw new InputMismatchException();// 如果if条件成立,即字形文本框内容中的字形有误,抛出匹配异常if (!(style.equals("常规") || style.equals("斜体") || style.equals("粗体") || style.equals("粗斜体")))throw new InputMismatchException();// 设置记事本文本框的字体属性jta.setFont(new Font(fontname, styleList.getSelectedIndex(), size));// 设置完关闭字体窗口并将记事本窗口恢复可操作性fontDialog.dispose();setEnabled(true);} // end trycatch (InputMismatchException em) {// 如果字体名称系统不存在,捕获异常,弹出警告窗口if (len == fontName.length)JOptionPane.showMessageDialog(null, "没有该名称的字体" + "\n请从字体列表中选择字体", "字体",JOptionPane.WARNING_MESSAGE);// 如果字形名称输入有误,捕获异常,弹出警告窗口if (!(style.equals("常规") || style.equals("斜体") || style.equals("粗体") || style.equals("粗斜体")))JOptionPane.showMessageDialog(null, "没有该字形的字体" + "\n请从字形列表中选择字形", "字体",JOptionPane.WARNING_MESSAGE);} // end catchcatch (NumberFormatException en) {// 如果输入的字体大小不是整数,捕获异常,弹出警告窗口JOptionPane.showMessageDialog(null, "“大小”必须是整数", "字体", JOptionPane.WARNING_MESSAGE);} // end catch}// end actionPerformed}// end ActionEvent);// end addActionEvent// 添加字形文本框的监听器(内部类的形式)styleField.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {int size = 0, len = 0;// 定义字体大小和fontName的长度变量String fontname = fontField.getText(), style = styleField.getText();// 定义fontname和字形字符串变量try {size = setSize(sizeField, size);// 通过自定义的方法获得字体大小// 通过for循环判断字体文本框的内容在系统中是否存在,存在则跳出循环,不存在则至循环结束for (len = 0; len < fontName.length; len++) {if (fontname.equals(fontName[len]))break;}// 如果if条件成立,即for循环完整的结束,抛出匹配异常if (len == fontName.length)throw new InputMismatchException();// 如果if条件成立,即字形文本框内容中的字形有误,抛出匹配异常if (!(style.equals("常规") || style.equals("斜体") || style.equals("粗体") || style.equals("粗斜体")))throw new InputMismatchException();// 设置记事本文本框的字体属性jta.setFont(new Font(fontname, styleList.getSelectedIndex(), size));// 设置完关闭字体窗口并将记事本窗口恢复可操作性fontDialog.dispose();setEnabled(true);} // end trycatch (InputMismatchException em) {// 如果字体名称系统不存在,捕获异常,弹出警告窗口if (len == fontName.length)JOptionPane.showMessageDialog(null, "没有该名称的字体" + "\n请从字体列表中选择字体", "字体",JOptionPane.WARNING_MESSAGE);// 如果字形名称输入有误,捕获异常,弹出警告窗口if (!(style.equals("常规") || style.equals("斜体") || style.equals("粗体") || style.equals("粗斜体")))JOptionPane.showMessageDialog(null, "没有该字形的字体" + "\n请从字形列表中选择字形", "字体",JOptionPane.WARNING_MESSAGE);} // end catchcatch (NumberFormatException en) {// 如果输入的字体大小不是整数,捕获异常,弹出警告窗口JOptionPane.showMessageDialog(null, "“大小”必须是整数", "字体", JOptionPane.WARNING_MESSAGE);} // end catch}// end actionPerformed}// end ActionEvent);// end addActionEvent// 添加字体大小文本框的监听器(内部类的形式)sizeField.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {int size = 0, len = 0;// 定义字体大小和fontName的长度变量String fontname = fontField.getText(), style = styleField.getText();// 定义fontname和字形字符串变量try {size = setSize(sizeField, size);// 通过自定义的方法获得字体大小// 通过for循环判断字体文本框的内容在系统中是否存在,存在则跳出循环,不存在则至循环结束for (len = 0; len < fontName.length; len++) {if (fontname.equals(fontName[len]))break;}// 如果if条件成立,即for循环完整的结束,抛出匹配异常if (len == fontName.length)throw new InputMismatchException();// 如果if条件成立,即字形文本框内容中的字形有误,抛出匹配异常if (!(style.equals("常规") || style.equals("斜体") || style.equals("粗体") || style.equals("粗斜体")))throw new InputMismatchException();// 设置记事本文本框的字体属性jta.setFont(new Font(fontname, styleList.getSelectedIndex(), size));// 设置完关闭字体窗口并将记事本窗口恢复可操作性fontDialog.dispose();setEnabled(true);} // end trycatch (InputMismatchException em) {// 如果字体名称系统不存在,捕获异常,弹出警告窗口if (len == fontName.length)JOptionPane.showMessageDialog(null, "没有该名称的字体" + "\n请从字体列表中选择字体", "字体",JOptionPane.WARNING_MESSAGE);// 如果字形名称输入有误,捕获异常,弹出警告窗口if (!(style.equals("常规") || style.equals("斜体") || style.equals("粗体") || style.equals("粗斜体")))JOptionPane.showMessageDialog(null, "没有该字形的字体" + "\n请从字形列表中选择字形", "字体",JOptionPane.WARNING_MESSAGE);} // end catchcatch (NumberFormatException en) {// 如果输入的字体大小不是整数,捕获异常,弹出警告窗口JOptionPane.showMessageDialog(null, "“大小”必须是整数", "字体", JOptionPane.WARNING_MESSAGE);} // end catch}// end actionPerformed}// end ActionEvent);// end addActionEvent// 设置字体窗口右上角关闭按钮的监听器(内部类)fontDialog.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {setEnabled(true);// 关闭字体窗口并恢复记事本窗口的可操作性}// end windowClosing}// end WindowAdapter);// end addWindowListener}// end font

总结:
1.GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();方法用于返回本地的字体名称(以字符串的形式)。
2.setHorizontalAlignment()方法用于设置文本对齐方式

状态栏功能
思路:激活状态栏时,文本域下方显示光标位置的状态并显示总字数。

核心代码
int caretpos = jta.getCaretPosition();// 返回文本组件的文本插入符的位置
int lineNum = jta.getLineOfOffset(caretpos);// 将组件文本中的偏移量转换为行号(从0开始)
int columnNum = caretpos - jta.getLineStartOffset(lineNum);// 文本插入符位置减去给定行起始处的偏移量就是列数lineNum += 1;// 返回文本的行数(从1开始)setText("第" + lineNum + "行,第" + columnNum + "列       " + "共" + num + "字");

截图和代码如下

// 状态栏的方法private void state() {// 状态栏被激活if (stateMenu.isSelected()) {try {// 激活时显示初始状态栏信息jla.setText("第" + String.valueOf(jta.getLineOfOffset(jta.getCaretPosition()) + 1) + "行,第"+ String.valueOf(jta.getCaretPosition() - jta.getLineStartOffset(jta.getCaretPosition()))+ "列       " + "共" + jta.getText().length() + "字");} // end trycatch (BadLocationException e) {System.out.println();} // end catchjta.addCaretListener(new CaretListener() {@Overridepublic void caretUpdate(CaretEvent e) {int lineNum = 0, columnNum = 0, num = jta.getText().length();try {int caretpos = jta.getCaretPosition();// 返回文本组件的文本插入符的位置lineNum = jta.getLineOfOffset(caretpos);// 将组件文本中的偏移量转换为行号(从0开始)columnNum = caretpos - jta.getLineStartOffset(lineNum);// 文本插入符位置减去给定行起始处的偏移量就是列数lineNum += 1;// 返回文本的行数(从1开始)jla.setText("第" + lineNum + "行,第" + columnNum + "列       " + "共" + num + "字");} // end trycatch (BadLocationException ex) {ex.printStackTrace();} // end catch}// end caretUpdate}// end CaretListener);// end addCaretListenerjla.setVisible(true);// 设置状态栏可视化} // end if// 屏蔽状态栏elsejla.setVisible(false);}// end state
}// end noteBookDemo

主方法

public class noteBook {public static void main(String[] args) {new noteBookDemo();}// end main
}// end noteBook

以上便是笔者对本次写记事本代码过程的总结。其中的不足就是有一些弹出窗口的快捷键未实现以及一些功能有一点bug。另外,笔者在这个写代码的过程中可以说是受益匪浅了嘻嘻!

总结用Java写记事本的过程相关推荐

  1. Java写记事本:文本超出范围时实现滚动条功能

    问题背景 本次Java课程的作业是做一个记事本,能够实现记事本的基本功能,如图所示 问题描述 想要实现内容超出文本框范围时,自动添加垂直滚动条和横向自适应. 添加了JScrollPane scroll ...

  2. java记事本获取当前时间_calendar 用Java写的日历,有查询时间日期,还有记事本以及到点提醒功能。 Develop 238万源代码下载- www.pudn.com...

    文件名称: calendar下载 收藏√  [ 5  4  3  2  1 ] 开发工具: Java 文件大小: 4465 KB 上传时间: 2013-06-30 下载次数: 3 提 供 者: 陈园园 ...

  3. 用JAVA写一个简单版的记事本

    下面的代码是一个简单版的记事本.如果需要更多的功能,可以自己去摸索一下更多的功能. import java.awt.FlowLayout; import java.awt.event.ActionEv ...

  4. 学了编译原理能否用 Java 写一个编译器或解释器?

    16 个回答 默认排序​ RednaxelaFX JavaScript.编译原理.编程 等 7 个话题的优秀回答者 282 人赞同了该回答 能.我一开始学编译原理的时候就是用Java写了好多小编译器和 ...

  5. 文本文件 java,java 写文本文件

    code 1:将特定String写入特定文件,不覆盖. import java.io.*; import java.util.*; public class OutputLog { public st ...

  6. java buffer 记事本_Java实现记事本|IO流/GUI

    Java实现记事本 题目 利用GUI实现一个简单的记事本(notepad),即打开文件,文字内容显示在界面上: 允许对文字内容进行编辑,并可以保存到文件. 代码 class notPadcontain ...

  7. Java对象的创建过程:类的初始化与实例化

    一.Java对象创建时机 我们知道,一个对象在可以被使用之前必须要被正确地实例化.在Java代码中,有很多行为可以引起对象的创建,最为直观的一种就是使用new关键字来调用一个类的构造函数显式地创建对象 ...

  8. java实现迷你计算机,用JAVA写一个迷你编辑器.doc

    用JAVA写一个迷你编辑器 用JAVA编写一个迷你编辑器 WINDOWS的记事本程序是非常方便的一个文字处理工具,用它来编辑纯文本文件快捷而灵巧.我用JAVA写了一个编辑器程序,模仿"记事本 ...

  9. Java简单记事本设计实验报告_基于JAVA的记事本设计报告.doc

    基于JAVA的记事本设计报告 华北科技学院计算机系综合性实验报告 PAGE 第 PAGE 11 页 XX学校计算机系综合性实验 实 验 报 告 课程名称 Java程序设计 实验学期 至 学年 第 学期 ...

最新文章

  1. 学习HTML5之塔克大战(详细记录)
  2. 动态规划之矩阵连乘讲解
  3. s6-5 TCP 连接的建立
  4. VS 编程常见错误及解决方法
  5. 未来计算机打蜡机,电脑洗车机的未来发展方向:多样化or精简化?
  6. AI需要你帮忙 | 把两栖爬行动物框出来,提高AI识别准确率
  7. 美国的卫星导航系统服务器,中国的北斗卫星和美国的gps到底哪个更厉害?
  8. word最后一页空白页删除
  9. python之父996icu_Python之父声援中国程序员996ICU计划,Python要拒绝996公司?
  10. 魔兽和星际最大差别是什么?
  11. HTML+CSS简单的淘宝首页框架布局小练(三)
  12. ftp工具绿色版,四款好用的绿色版ftp工具
  13. 小象学院 nlp 自然语言处理项目实战
  14. PC版微信加密图片解密思路与代码实现_Python
  15. C语言读取txt文件
  16. java实验5_java实验5
  17. 【深度学习】(问题记录)<对一个变量求梯度得到什么>-线性回归-小批量随机梯度下降
  18. 记录本地 Docker 新建镜像,推送到Daocloud
  19. 程序员生存定律--细论软件这个行当的根本特征
  20. 一分钟快速搭建Windows防污染DNS服务器——Pcap_DNSProxy

热门文章

  1. NOI2018湖北省队集训Day4 T2 djq 的朋友圈
  2. 不用刷机的 MIUI?小米系统 APP 初体验
  3. 微信小程序图片高度按照图片真实宽高比自适应
  4. 【IoT】硬件设计:PCB 工装设计要求
  5. vue报错:If you want to include a polyfii,you can use an empty module like this:resolve.fallback
  6. 【CSS】<Cascading Style Sheets>CSS盒子模型
  7. OkHttp原理分析总结
  8. 怎么用python实现哈夫曼树_数据结构-哈夫曼树(python实现)
  9. RSA公钥密码体制及C++代码实现
  10. 苏宁首页案例-移动端