diff --git a/resources/images/notepad.png b/resources/images/notepad.png new file mode 100644 index 0000000000000000000000000000000000000000..8b00276d75d3f48b03978c050f6f884fcb161a6a Binary files /dev/null and b/resources/images/notepad.png differ diff --git a/src/java2022spring/EditMenu.java b/src/java2022spring/EditMenu.java new file mode 100644 index 0000000000000000000000000000000000000000..7e09bd9d09a62f58fb4c43daba02e8bade71a93b --- /dev/null +++ b/src/java2022spring/EditMenu.java @@ -0,0 +1,467 @@ +package java2022spring; +import javax.swing.BorderFactory; +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JRadioButton; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.KeyStroke; +import javax.swing.undo.UndoManager; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Calendar; +import java.util.GregorianCalendar; + +public class EditMenu extends JMenu{ + JFrame frame; + JTextArea textArea; + UndoManager undoManager; + GregorianCalendar myCalendar; + EditMenu(JFrame frame, JTextArea textArea) { + super("编辑(E)"); + this.frame = frame; + this.textArea = textArea; + undoManager = new UndoManager(); + myCalendar = new GregorianCalendar(); + initEditMenu(); + } + public void initEditMenu() { + JMenuItem cancelBtn = new JMenuItem("撤销(U)"); + cancelBtn.setMnemonic(java.awt.event.KeyEvent.VK_U); + cancelBtn.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Z, + java.awt.event.KeyEvent.CTRL_MASK)); + JMenuItem cutBtn = new JMenuItem("剪切(T)"); + cutBtn.setMnemonic(java.awt.event.KeyEvent.VK_T); + cutBtn.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, + java.awt.event.KeyEvent.CTRL_MASK)); + JMenuItem copyBtn = new JMenuItem("复制(C)"); + copyBtn.setMnemonic(java.awt.event.KeyEvent.VK_C); + copyBtn.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, + java.awt.event.KeyEvent.CTRL_MASK)); + JMenuItem pasteBtn = new JMenuItem("粘贴(P)"); + pasteBtn.setMnemonic(java.awt.event.KeyEvent.VK_P); + pasteBtn.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_V, + java.awt.event.KeyEvent.CTRL_MASK)); + JMenuItem delBtn = new JMenuItem("删除(L)"); + delBtn.setMnemonic(java.awt.event.KeyEvent.VK_L); + JMenuItem findAlterBtn = new JMenuItem("查找/替换(F)"); + findAlterBtn.setMnemonic(java.awt.event.KeyEvent.VK_F); + findAlterBtn.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F, + java.awt.event.KeyEvent.CTRL_MASK)); + JMenuItem turnBtn = new JMenuItem("转到(G)"); + turnBtn.setMnemonic(java.awt.event.KeyEvent.VK_G); + turnBtn.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_G, + java.awt.event.KeyEvent.CTRL_MASK)); + JMenuItem selectAllBtn = new JMenuItem("全选(A)"); + selectAllBtn.setMnemonic(java.awt.event.KeyEvent.VK_A); + selectAllBtn.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A, + java.awt.event.KeyEvent.CTRL_MASK)); + JMenuItem datetimeBtn = new JMenuItem("时间/日期(D)"); + delBtn.setMnemonic(java.awt.event.KeyEvent.VK_D); + datetimeBtn.setAccelerator(KeyStroke.getKeyStroke("F5")); + add(cancelBtn); + addSeparator(); + add(cutBtn); + add(copyBtn); + add(pasteBtn); + add(delBtn); + addSeparator(); + add(findAlterBtn); + add(turnBtn); + addSeparator(); + add(selectAllBtn); + add(datetimeBtn); + + // 绑定UndoManager + textArea.getDocument().addUndoableEditListener(undoManager); + + // 实现右键弹出菜单 + textArea.addMouseListener(new MouseAdapter() { + public void mouseReleased(MouseEvent e) { + if(e.getButton()==MouseEvent.BUTTON3) { + showPopupMenu(e.getX(), e.getY()); + } + } + }); + + // 撤销内容 + cancelBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if(undoManager.canUndo()) + undoManager.undo(); + else { + JOptionPane.showMessageDialog(frame, "无法进行撤销操作"); + } + } + }); + + // 剪切内容 + cutBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textArea.cut(); + } + }); + + // 复制内容 + copyBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textArea.copy(); + } + }); + + // 粘贴内容 + pasteBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textArea.paste(); + } + }); + + // 删除内容 + delBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + String text = textArea.getText().toString(); + // 删除选中的部分 + String beforeText = text.substring(0, textArea.getSelectionStart()); + String afterText = text.substring(textArea.getSelectionEnd(), text.length()); + textArea.setText(beforeText + afterText); + } + }); + + // 查找内容 + findAlterBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + new FindAlterDialog(); + } + }); + + // 转到内容 + turnBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + JDialog turnDialog = new JDialog(); + turnDialog.setTitle("转到"); + turnDialog.setSize(400, 80); + turnDialog.setResizable(false); + turnDialog.setLocationRelativeTo(frame); + + JLabel textLbl = new JLabel("转到行数:"); + JTextField textField = new JTextField(22); + JButton turnBtn = new JButton("转到"); + turnBtn.setPreferredSize(new Dimension(80, 20)); + + JPanel contentPane = new JPanel(); + turnDialog.setContentPane(contentPane); + + contentPane.add(textLbl); + contentPane.add(textField); + contentPane.add(turnBtn); + + turnDialog.setVisible(true); + + turnBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int totalLines = textArea.getLineCount(); + int pos = 0; + int[] linePos = new int[totalLines + 1]; + System.out.println(totalLines); + int num = 1; + + while(true) { + pos = textArea.getText().indexOf('\12', pos); + if(pos == -1) break; + linePos[num++] = pos; + pos += 1; + } + + int getLine = Integer.parseInt(textField.getText()); + if(getLine > totalLines) textArea.setCaretPosition(0); + else { + int newPos = linePos[getLine - 1]; + textArea.setCaretPosition(newPos + 1); + } + } + }); + } + }); + + // 全选内容 + selectAllBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textArea.selectAll(); + } + }); + + // 时间/日期显示 + datetimeBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + String datetime = myCalendar.get(Calendar.HOUR_OF_DAY)+":"+ myCalendar.get(Calendar.MINUTE) + + " " + myCalendar.get(Calendar.YEAR)+"/"+(myCalendar.get(Calendar.MONTH)+1) + + "/" + myCalendar.get(Calendar.DAY_OF_MONTH); + String text = textArea.getText(); + int caretPos = textArea.getCaretPosition(); + textArea.setText(text.substring(0, caretPos) + datetime + text.substring(caretPos)); + } + }); + } + public void showPopupMenu(int x, int y) { + JPopupMenu popupMenu = new JPopupMenu(); + + // 菜单项 + JMenuItem undoMenuItem = new JMenuItem("撤销"); + JMenuItem cutMenuItem = new JMenuItem("剪切"); + JMenuItem copyMenuItem = new JMenuItem("复制"); + JMenuItem pasteMenuItem = new JMenuItem("粘贴"); + JMenuItem delMenuItem = new JMenuItem("删除"); + JMenuItem selectAllMenuItem = new JMenuItem("全选"); + + + // 添加 一级菜单 到 弹出菜单 + popupMenu.add(undoMenuItem); + popupMenu.addSeparator(); + popupMenu.add(cutMenuItem); + popupMenu.add(copyMenuItem); + popupMenu.add(pasteMenuItem); + popupMenu.add(delMenuItem); + popupMenu.addSeparator(); // 添加一条分隔符 + popupMenu.add(selectAllMenuItem); + + // 添加菜单项的点击监听器 + undoMenuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(undoManager.canUndo()) + undoManager.undo(); + else { + JOptionPane.showMessageDialog(frame, "无法进行撤销操作"); + } + } + }); + cutMenuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + textArea.cut(); + } + }); + copyMenuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + textArea.copy(); + + } + }); + pasteMenuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + textArea.paste(); + } + }); + delMenuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + String text = textArea.getText().toString(); + // 删除选中的部分 + String beforeText = text.substring(0, textArea.getSelectionStart()); + String afterText = text.substring(textArea.getSelectionEnd(), text.length()); + textArea.setText(beforeText + afterText); + } + }); + selectAllMenuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + textArea.selectAll(); + + } + }); + popupMenu.show(textArea, x, y); + } + + // 查找, 替换文字对话框 + class FindAlterDialog extends JDialog { + private JLabel inputLbl; + private JTextField inputField; + private JButton findBtn; + private JButton cancelBtn; + private JCheckBox judgeCaseBtn; + private ButtonGroup btnGroup; + private JRadioButton upBtn; + private JRadioButton downBtn; + private JPanel findPanel; + private JLabel alterLabel; + private JTextField alterField; + private JButton alterBtn; + private JButton alterAllBtn; + private JPanel alterPanel; + private JPanel alterBtnPanel; + private JPanel directionPanel; + private JPanel bottomPanel; + + FindAlterDialog() { + super(frame, "查找与替换", false); + setSize(480, 220); + setResizable(false); + setLocationRelativeTo(frame); + Container container = getContentPane(); + container.setLayout(new FlowLayout(FlowLayout.LEFT)); + + inputLbl = new JLabel("查找内容(N): "); + alterLabel = new JLabel("替换其为(P): "); + inputField = new JTextField(22); + alterField = new JTextField(22); + findBtn = new JButton("查找下一个(F)"); + alterBtn = new JButton("替换(R)"); + alterAllBtn = new JButton("全部替换(A)"); + findBtn.setPreferredSize(new Dimension(120, 22)); + alterBtn.setPreferredSize(new Dimension(120, 22)); + alterAllBtn.setPreferredSize(new Dimension(120, 22)); + + btnGroup = new ButtonGroup(); + upBtn = new JRadioButton("向上(U)"); + downBtn = new JRadioButton("向下(D)"); + downBtn.setSelected(true); + btnGroup.add(upBtn); + btnGroup.add(downBtn); + + cancelBtn = new JButton("取消"); + cancelBtn.setPreferredSize(new Dimension(120, 22)); + judgeCaseBtn = new JCheckBox("区分大小写"); + + + findPanel = new JPanel(); + alterPanel = new JPanel(); + bottomPanel = new JPanel(); + + findPanel.add(inputLbl); + findPanel.add(inputField); + findPanel.add(findBtn); + + alterBtnPanel = new JPanel(); + alterBtnPanel.setLayout(new GridLayout(2, 1, 0, 5)); + alterBtnPanel.add(alterBtn); + alterBtnPanel.add(alterAllBtn); + alterBtnPanel.add(cancelBtn); + + alterPanel.add(alterLabel); + alterPanel.add(alterField); + alterPanel.add(alterBtnPanel); + + directionPanel = new JPanel(); + directionPanel.setPreferredSize(new Dimension(170, 60)); + directionPanel.setBorder(BorderFactory.createTitledBorder("方向 ")); + directionPanel.add(upBtn); + directionPanel.add(downBtn); + + bottomPanel.add(judgeCaseBtn); + bottomPanel.add(directionPanel); + bottomPanel.add(cancelBtn); + + container.add(findPanel); + container.add(alterPanel); + container.add(bottomPanel); + + + // 添加事件 + findBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + String textCont = textArea.getText(); + String findText = inputField.getText(); + if(!judgeCaseBtn.isSelected()) { + textCont = textCont.toLowerCase(); + findText = findText.toLowerCase(); + } + int objPos; + int caretPos = textArea.getCaretPosition(); + if(upBtn.isSelected()) { + objPos = textCont.lastIndexOf(findText, caretPos - findText.length() - 1); + } + else { + objPos = textCont.indexOf(findText, caretPos); + } + + if(objPos != -1) { + textArea.setCaretPosition(objPos); + textArea.select(objPos, objPos + findText.length()); + } + else { + JOptionPane.showMessageDialog(null, "抱歉, 未查询到该内容", "确认", JOptionPane.INFORMATION_MESSAGE); + } + } + }); + + alterBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + String alterText = alterField.getText(); + if(textArea.getSelectedText() != null) { + textArea.replaceSelection(alterText); + } + else { + JOptionPane.showMessageDialog(null, "您没有选中任何内容", "确认", JOptionPane.INFORMATION_MESSAGE); + } + } + }); + + alterAllBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + String textCont = textArea.getText(); + String findText = inputField.getText(); + String alterText = alterField.getText(); + + if(judgeCaseBtn.isSelected()) { + textCont = textCont.toLowerCase(); + findText = findText.toLowerCase(); + } + + int objPos = -1; + int count = 0; + + do { + // 更新每一次修改后的文本 + textCont = textArea.getText(); + objPos = textCont.indexOf(findText, objPos + 1); + if (objPos != -1) { + textArea.select(objPos, objPos + findText.length()); + try { + Thread.sleep(1000); + } catch (InterruptedException e1) { + // TODO 自动生成的 catch 块 + e1.printStackTrace(); + } + textArea.replaceSelection(alterText.length() == 0 ? "" : alterText); + count++; + } + }while (objPos != -1); + JOptionPane.showMessageDialog(null, "成功替换" + count + "个匹配内容!", "替换成功", JOptionPane.INFORMATION_MESSAGE); + } + }); + + cancelBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + dispose(); + } + }); + + + setVisible(true); + + } + } +} diff --git a/src/java2022spring/FileMenu.java b/src/java2022spring/FileMenu.java new file mode 100644 index 0000000000000000000000000000000000000000..3f9c80b8fb3918cd8bbbdd93b11ddd9a625d02d4 --- /dev/null +++ b/src/java2022spring/FileMenu.java @@ -0,0 +1,293 @@ +package java2022spring; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JTextArea; +import javax.swing.KeyStroke; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.OutputStreamWriter; + +public class FileMenu extends JMenu{ + File file = null; + MainFrame frame; + JTextArea textArea; + JFileChooser fileChooser; + private boolean haveSelectedFile = false; + private boolean isSaved = true; + FileMenu(MainFrame frame, JTextArea textArea) { + super("文本(F)"); + this.frame = frame; + this.textArea = textArea; + fileChooser = new JFileChooser(); + initFileMenu(); + } + + + + // 读取文件 + public String readFile() { + BufferedReader reader = null; + StringBuilder fileString = null; + try { + fileString = new StringBuilder(); + reader = new BufferedReader(new FileReader(file)); + String str; + // 将文件中的文本读取到str中 + while((str = reader.readLine()) != null) { + fileString.append(str); + fileString.append('\n'); // 添加换行符, 保留文件原本格式 + } + } catch (FileNotFoundException e1) { + JOptionPane.showMessageDialog(null, "未找到该文件!"); + return null; + } catch (IOException e1) { + JOptionPane.showMessageDialog(null, "文件读取异常"); + return null; + } finally { + // 关闭字符流 + try { + if (reader != null) + reader.close(); + } catch (IOException e1) {} + } + return fileString.toString(); + } + + // 弹出是否需要保存消息框 + public boolean needSave() { + int select = JOptionPane.showConfirmDialog(null, "是否保存修改?"); + if (select == JOptionPane.YES_OPTION) { + return true; + } + return false; + } + + // 判断文件是否被保存 + public boolean checkIfSaved() { + // 选中并更改了文件 + if(haveSelectedFile) + return textArea.getText().equals(readFile()); + // 新文件在保存文件后也会获得文件句柄, 如果没有句柄说明没有保存 + else + // 未选中文件则判断文本区域是否为空 + return textArea.getText().equals(""); + } + + // 保存文件 + public boolean saveFile() { + if(haveSelectedFile) { + BufferedWriter writer = null; + try { + // 如果不存在会直接创建文件 + writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))); + writer.write(textArea.getText()); + writer.flush(); + isSaved = true; + } catch (FileNotFoundException e) { + JOptionPane.showMessageDialog(frame, "文件保存出错" + e.getMessage()); + } catch (IOException e) { + JOptionPane.showMessageDialog(frame, "文件写入异常" + e.getMessage()); + } finally { + try { + if (writer != null) + writer.close(); + } catch (IOException e1) {} + } + } + else { + // 选择是否保存为新文件, 或者覆盖其他文件 + while(true) { + if(fileChooser.showSaveDialog(frame) != JFileChooser.APPROVE_OPTION) + return false; // 如果取消保存则什么也不做 + file = fileChooser.getSelectedFile();// 获取选中的文件 + if(file.exists()) { + // 询问是否覆盖 + int option = JOptionPane.showConfirmDialog( + frame, + "该文件已存在,是否覆盖原文件", + "确认", JOptionPane.YES_NO_OPTION); + if(option == JOptionPane.NO_OPTION) { + // 如果不想覆盖就再做选择 + file = null; + } + else break; + } + else break; + } + // 确认覆盖后获取到当前选择文件句柄, 保存进去 + haveSelectedFile = true; + saveFile(); + } + return true; + } + + public void initFileMenu() { + JMenuItem newFileBtn = new JMenuItem("新建(N)", 'N'); + newFileBtn.setMnemonic(java.awt.event.KeyEvent.VK_N); + newFileBtn.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, + java.awt.event.KeyEvent.CTRL_MASK)); + JMenuItem newFrameBtn = new JMenuItem("新窗口(W)"); + newFrameBtn.setMnemonic(java.awt.event.KeyEvent.VK_W); + newFrameBtn.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, + java.awt.event.KeyEvent.VK_CONTROL)); + JMenuItem openFileBtn = new JMenuItem("打开(O)"); + openFileBtn.setMnemonic(java.awt.event.KeyEvent.VK_O); + openFileBtn.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, + java.awt.event.KeyEvent.CTRL_MASK)); + JMenuItem saveFileBtn = new JMenuItem("保存(S)"); + saveFileBtn.setMnemonic(java.awt.event.KeyEvent.VK_S); + saveFileBtn.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, + java.awt.event.KeyEvent.CTRL_MASK)); + JMenuItem saveAsFileBtn = new JMenuItem("另存为(A)"); + saveAsFileBtn.setMnemonic(java.awt.event.KeyEvent.VK_A); + JMenuItem exitBtn = new JMenuItem("退出(X)"); + exitBtn.setMnemonic(java.awt.event.KeyEvent.VK_X); + add(newFileBtn); + add(newFrameBtn); + add(openFileBtn); + add(saveFileBtn); + add(saveAsFileBtn); + addSeparator(); + add(exitBtn); + + // 添加关闭窗口时的监听器 + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + // 先用直接关闭替代 + isSaved = checkIfSaved(); + // 询问是否需要保存文件 + if(!isSaved) { + if(needSave()) + saveFile(); + } + + System.exit(0); + } + }); + + textArea.addKeyListener(new KeyAdapter() { + @Override + public void keyTyped(KeyEvent e) { + if(file != null) + frame.setTitle('*' + file.getName() + " - 记事本"); + }}); + + // 新建文件 + newFileBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + isSaved = checkIfSaved(); + // 询问是否需要保存文件 + if(!isSaved) { + if(needSave()) + saveFile(); + } + // 清空原本文本信息 + file = null; + textArea.setText(""); + frame.setTitle("无标题 - 记事本"); + haveSelectedFile = false; + // System.out.println("被按了!"); + } + }); + // 打开新窗口 + newFrameBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + new MainFrame(false, frame.offset); + } + }); + // 打开文件 + openFileBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + boolean flag = false; + isSaved = checkIfSaved(); + // 询问是否需要保存文件 + if(!isSaved) { + if(needSave()) + saveFile(); + else flag = true; + } + + if(flag || isSaved) { + int select = fileChooser.showOpenDialog(frame); + if(select == JFileChooser.APPROVE_OPTION) { + haveSelectedFile = true; + file = fileChooser.getSelectedFile(); + frame.setTitle(file.getName() + " - 记事本"); + textArea.setText(readFile()); + textArea.setCaretPosition(0); + System.out.println(textArea.getText()); + } + } + } + }); + // 保存文件 + saveFileBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + // 保存文件后去除*号 + if(saveFile() && haveSelectedFile) { + frame.setTitle(file.getName() + " - 记事本"); + } + frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); + } + }); + + // 文件另存为 + saveAsFileBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + while(true) { + if(fileChooser.showSaveDialog(frame) != JFileChooser.APPROVE_OPTION) + return; // 如果取消保存则什么也不做 + file = fileChooser.getSelectedFile();// 获取选中的文件 + if(file.exists()) { + // 询问是否覆盖 + int option = JOptionPane.showConfirmDialog( + frame, + "该文件已存在,是否覆盖原文件", + "确认", JOptionPane.YES_NO_OPTION); + if(option == JOptionPane.NO_OPTION) { + // 如果不想覆盖就再做选择 + file = null; + } + else break; + } + else break; + } + haveSelectedFile = true; + saveFile(); + frame.setTitle(file.getName() + " - 记事本"); + frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); + } + }); + + // 退出窗口 + exitBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + isSaved = checkIfSaved(); + // 询问是否需要保存文件 + if(!isSaved) { + if(needSave()) + saveFile(); + } + + System.exit(0); + } + }); + } + +} diff --git a/src/java2022spring/MainFrame.java b/src/java2022spring/MainFrame.java new file mode 100644 index 0000000000000000000000000000000000000000..7510aeb6c72b4ac6ca2332eb0969b2f9bca71483 --- /dev/null +++ b/src/java2022spring/MainFrame.java @@ -0,0 +1,157 @@ +package java2022spring; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Image; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.*; +import javax.swing.*; +import javax.swing.event.CaretEvent; +import javax.swing.event.CaretListener; + + +public class MainFrame extends JFrame{ + protected int offset = 0; // 新建窗口偏移位置 + protected JLabel posLabel; + protected String posText; + int fontSize = 16; + private JPanel posPane; + private JPanel contentPane; + private JMenuBar menuBar; + private JTextArea textArea; + private JScrollPane scrollPane; + private JFileChooser fileChooser = new JFileChooser(); + private String fileName = "无标题"; + + MainFrame(boolean isFirst, int offset) { + // 创建的新窗口偏移部分位置 + if(!isFirst) this.offset = offset + 25; + setBounds(300 + this.offset, 100, 800, 600); + setTitle(fileName + " - 记事本"); + //设置图标 + Image myImage = Toolkit.getDefaultToolkit().getImage("resources/images/notepad.png"); + this.setIconImage(myImage); + setLayout(new BorderLayout()); + // 取消默认关闭操作, 在关闭前先判断文件是否需要保存 + setDefaultCloseOperation(0); + + contentPane = new JPanel(); + contentPane.setLayout(new BorderLayout()); + setContentPane(contentPane); + // 文本框面板 + textArea = new JTextArea(); + textArea.setFont(new Font("华文中宋", Font.PLAIN, 16)); + scrollPane = new JScrollPane( + textArea + ,ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS + ,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS + ); + contentPane.add(scrollPane, BorderLayout.CENTER); + + // 添加菜单 + menuBar = new JMenuBar(); + setJMenuBar(menuBar); + + /* 一级菜单区域 */ + JMenu fileMenu = new FileMenu(this, textArea); + JMenu editMenu = new EditMenu(this, textArea); + JMenu formMenu = new formatMenu(this, textArea, scrollPane); + JMenu lookMenu = new JMenu("查看(V)"); + JMenu helpMenu = new JMenu("帮助(H)"); + menuBar.add(fileMenu); + menuBar.add(editMenu); + menuBar.add(formMenu); + menuBar.add(lookMenu); + menuBar.add(helpMenu); + + // "查看"菜单内容 + JMenu changeSizeBtn = new JMenu("缩放(Z)"); + changeSizeBtn.setMnemonic(java.awt.event.KeyEvent.VK_Z); + JCheckBox statusBarBtn = new JCheckBox("状态栏"); + statusBarBtn.setSelected(true); + lookMenu.add(changeSizeBtn); + lookMenu.add(statusBarBtn); + + statusBarBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if(statusBarBtn.isSelected()) + posPane.setVisible(true); + else posPane.setVisible(false); + } + }); + + JMenuItem largeBtn = new JMenuItem("放大(I)"); + largeBtn.setMnemonic(java.awt.event.KeyEvent.VK_I); + largeBtn.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_PLUS, + java.awt.event.KeyEvent.CTRL_MASK)); + JMenuItem smallBtn = new JMenuItem("缩小(O)"); + smallBtn.setMnemonic(java.awt.event.KeyEvent.VK_O); + smallBtn.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_MINUS, + java.awt.event.KeyEvent.CTRL_MASK)); + JMenuItem defaultBtn = new JMenuItem("恢复默认缩放"); + defaultBtn.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_0, + java.awt.event.KeyEvent.CTRL_MASK)); + changeSizeBtn.add(largeBtn); + changeSizeBtn.add(smallBtn); + changeSizeBtn.add(defaultBtn); + + largeBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textArea.setFont(new Font("华文中宋", Font.PLAIN, fontSize += 2)); + } + }); + + smallBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textArea.setFont(new Font("华文中宋", Font.PLAIN, fontSize -= 2)); + } + }); + + defaultBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textArea.setFont(new Font("华文中宋", Font.PLAIN, fontSize = 16)); + } + }); + + // 帮助菜单内容 + JMenuItem helpInfo = new JMenuItem("关于帮助(H)"); + JMenuItem sendBack = new JMenuItem("发送反馈(F)"); + JMenuItem notepadInfo = new JMenuItem("关于记事本(A)"); + helpMenu.add(helpInfo); + helpMenu.add(sendBack); + helpMenu.addSeparator(); + helpMenu.add(notepadInfo); + + // 窗口底部面板 + posPane = new JPanel(); + posPane.setLayout(new BorderLayout()); + contentPane.add(posPane, BorderLayout.SOUTH); + posText = "第 1 行, 第 1 列 "; + posLabel = new JLabel(posText); + posPane.add(posLabel, BorderLayout.EAST); + + textArea.addCaretListener(new CaretListener() { //记录行数和列数 + public void caretUpdate(CaretEvent e) { + try { + int caretPos = textArea.getCaretPosition(); + int row = textArea.getLineOfOffset(caretPos); + int col = caretPos - textArea.getLineStartOffset(row); + row += 1; + col += 1; + posLabel.setText("第 " + row + " 行, " + "第 " + col + " 列 "); + } + catch(Exception ex) { } + }}); + + setVisible(true); + validate(); + } + + public static void main(String[] args) { + new MainFrame(true, 0); + } +} diff --git a/src/java2022spring/Test.java b/src/java2022spring/Test.java deleted file mode 100644 index 24deb29bfc0e5f50fdedcd21b504e77b529d48b6..0000000000000000000000000000000000000000 --- a/src/java2022spring/Test.java +++ /dev/null @@ -1,7 +0,0 @@ -package java2022spring; - -public class Test { - public static void main(String[] args) { - System.out.println("Hello world!"); - } -} diff --git a/src/java2022spring/formatMenu.java b/src/java2022spring/formatMenu.java new file mode 100644 index 0000000000000000000000000000000000000000..d9c483e518f953b67e6d6c41027a119a3b1259ec --- /dev/null +++ b/src/java2022spring/formatMenu.java @@ -0,0 +1,202 @@ +package java2022spring; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.ListModel; +import javax.swing.ScrollPaneConstants; +import javax.swing.border.Border; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +public class formatMenu extends JMenu{ + JTextArea textArea; + JFrame frame; + JScrollPane scrollPane; + + formatMenu(JFrame frame, JTextArea textArea, JScrollPane scrollPane) { + super("格式(O)"); + this.textArea = textArea; + this.frame = frame; + this.scrollPane = scrollPane; + initFormatMenu(); + } + + public void initFormatMenu() { + JCheckBox autoNextBtn = new JCheckBox("自动换行(W)"); + JMenuItem fontBtn = new JMenuItem("字体(F)"); + fontBtn.setMnemonic(java.awt.event.KeyEvent.VK_F); + + add(autoNextBtn); + add(fontBtn); + + // 自动换行事件 + autoNextBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if(autoNextBtn.isSelected()) { + textArea.setLineWrap(true); + scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + } + else { + textArea.setLineWrap(false); + scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); + } + } + }); + + // 字体窗口事件 + fontBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + new FontFrame(); + } + }); + } + + + class FontFrame extends JDialog { + String family = "华文中宋"; + int size = 16; + String[] familyKinds = {"Times New Roman", "Consolas", "等线", "黑体", "华文中宋", "楷体", "隶书", "宋体", "微软雅黑"}; + Integer[] sizeKinds = {8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 36}; + JLabel instance; + + FontFrame() { + super(frame, "字体", true); + setSize(280, 340); + setLayout(null); // 设置为绝对布局 + setResizable(false); + setLocationRelativeTo(frame); + + final JList familyList = new JList(); + final JList sizeList = new JList(); + familyList.setListData(familyKinds); + sizeList.setListData(sizeKinds); + // 设置默认选项 + familyList.setSelectedIndex(4); + sizeList.setSelectedIndex(6); + + // 菜单标签 + JPanel headText1 = new JPanel(); + JPanel headText2 = new JPanel(); + JLabel familyLbl = new JLabel("字体(F):"); + JLabel sizeLbl = new JLabel("大小(S):"); + headText1.add(familyLbl); + headText2.add(sizeLbl); + headText1.setBounds(0, 5, 64, 24); + headText2.setBounds(190, 5, 64, 24); + add(headText1); + add(headText2); + + // 滚动菜单 + JScrollPane familyPane = new JScrollPane( + familyList, + ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + JScrollPane sizePane = new JScrollPane( + sizeList, + ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER + ); + familyPane.setBounds(10, 30, 180, 120); + sizePane.setBounds(200, 30, 65, 120); + add(familyPane); + add(sizePane); + + // 选中事件 + familyList.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + // 获取目标索引 + int index = familyList.getSelectedIndex(); + // 获取数据的 + ListModel listModel = familyList.getModel(); + + family = listModel.getElementAt(index); + instance.setFont(new Font(family, Font.PLAIN, size)); + + System.out.println(family); + } + }); + + sizeList.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + // 获取目标索引 + int index = sizeList.getSelectedIndex(); + // 获取数据的 + ListModel listModel = sizeList.getModel(); + + size = listModel.getElementAt(index); + instance.setFont(new Font(family, Font.PLAIN, size)); + System.out.println(size); + } + }); + + // 示例 + JPanel instancePane = new JPanel(); + JLabel textLbl = new JLabel("示例:"); + JPanel instanceBox = new JPanel(); + instance = new JLabel("AaBbCcDd"); + instance.setFont(new Font("华文中宋", Font.PLAIN, 16)); + + instancePane.setBounds(10, 160, 200, 75); + add(instancePane); + instancePane.setLayout(null); + textLbl.setBounds(0, 0, 200, 24); + instanceBox.setBounds(0, 30, 200, 75-24); + instancePane.add(textLbl); + instancePane.add(instanceBox); + instanceBox.setLayout(new BorderLayout()); + instanceBox.add(instance, BorderLayout.CENTER); + + // 按钮 + JPanel btnPane = new JPanel(); + JButton confirmBtn = new JButton("确定"); + JButton cancelBtn = new JButton("取消"); + confirmBtn.setFont(new Font("华文中宋", Font.PLAIN, 16)); + cancelBtn.setFont(new Font("华文中宋", Font.PLAIN, 16)); + confirmBtn.setPreferredSize(new Dimension(70,20)); + cancelBtn.setPreferredSize(new Dimension(70,20)); + + btnPane.setLayout(new BorderLayout()); + btnPane.add(confirmBtn, BorderLayout.WEST); + btnPane.add(cancelBtn, BorderLayout.EAST); + btnPane.setBounds(40, 260, 180, 30); + add(btnPane); + + // 按钮事件 + confirmBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textArea.setFont(new Font(family, Font.PLAIN, size)); + dispose(); + } + }); + + cancelBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + dispose(); + } + }); + + setVisible(true); + validate(); + } + } +}