源自早先想法, 打算從界面方向做些嘗試. 找到個簡單文本編輯器的實現: Simple Text Editor - Java Tutorials. 原本的菜單/按鈕界面如下. 包括基本功能: 新建/打開/保存文件, 文本編輯與剪切/復制/粘貼.
把所有菜單/按鈕替換為命令輸入后效果如下, 源碼庫在: program-in-chinese/simple-text-editor-in-Java. 與其他命令行工具一樣, 省去界面元素的代價是輸入較繁瑣. 在文本和命令兩處切換也有點麻煩.
接下去試着實現命令輸入的自動補全等等.
實現源碼如下. 不采用第三方庫, 比較粗糙的代碼180行.
public class 文本編輯器 extends JFrame {
private static final String 默認文件名 = "無名";
private JTextArea 文本區域 = new JTextArea(20, 120);
private JTextArea 命令文本區 = new JTextArea(5, 20);
private JFileChooser 對話框 = new JFileChooser(System.getProperty("user.dir"));
private String 當前文件 = 默認文件名;
private String 當前命令 = "";
private boolean 已改 = false;
public static void main(String[] arg) {
new 文本編輯器();
}
public 文本編輯器() {
文本區域.setFont(new Font("Monospaced", Font.PLAIN, 12));
JScrollPane 文本區 = new JScrollPane(文本區域, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
add(文本區, BorderLayout.CENTER);
命令文本區.setFont(new Font("Monospaced", Font.PLAIN, 12));
JScrollPane 命令區 = new JScrollPane(命令文本區, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
add(命令區, BorderLayout.EAST);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
文本區域.addKeyListener(監聽文本輸入);
命令文本區.addKeyListener(命令監聽);
setTitle(當前文件);
setVisible(true);
}
private KeyListener 監聽文本輸入 = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
已改 = true;
}
};
private KeyListener 命令監聽 = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
int 行數 = 命令文本區.getLineCount();
if (行數 == 1) {
當前命令 = 命令文本區.getText();
} else {
try {
int 上一行末位置 = 命令文本區.getLineEndOffset(行數 - 2);
當前命令 = 命令文本區.getText().substring(上一行末位置);
} catch (BadLocationException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
執行(當前命令);
}
}
};
private void 執行(String 當前命令) {
switch (當前命令) {
case "新建":
新建操作();
break;
case "打開":
打開操作();
break;
case "保存":
保存操作();
break;
case "另存":
另存文件為();
break;
case "退出":
退出操作();
break;
case "剪切":
文本區域.cut();
break;
case "復制":
文本區域.copy();
break;
case "粘貼":
文本區域.paste();
break;
default:
// TODO: 提示無此命令或顯示幫助
break;
}
}
private void 新建操作() {
保存舊文件();
文本區域.setText("");
當前文件 = 默認文件名;
setTitle(當前文件);
已改 = false;
}
private void 打開操作() {
保存舊文件();
if (對話框.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
讀入文件(對話框.getSelectedFile().getAbsolutePath());
}
}
private void 保存操作() {
if (!當前文件.equals(默認文件名))
保存文件(當前文件);
else
另存文件為();
}
private void 退出操作() {
保存舊文件();
System.exit(0);
}
private void 另存文件為() {
if (對話框.showSaveDialog(null) == JFileChooser.APPROVE_OPTION)
保存文件(對話框.getSelectedFile().getAbsolutePath());
}
private void 保存舊文件() {
if (已改) {
if (JOptionPane.showConfirmDialog(this, "保存 " + 當前文件 + " 嗎?", "保存",
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
保存文件(當前文件);
}
}
private void 讀入文件(String 文件名) {
try {
FileReader 讀 = new FileReader(文件名);
文本區域.read(讀, null);
讀.close();
當前文件 = 文件名;
setTitle(當前文件);
已改 = false;
} catch (IOException e) {
Toolkit.getDefaultToolkit().beep();
JOptionPane.showMessageDialog(this, "找不到 " + 文件名);
}
}
private void 保存文件(String 文件名) {
try {
FileWriter 寫 = new FileWriter(文件名);
文本區域.write(寫);
寫.close();
當前文件 = 文件名;
setTitle(當前文件);
已改 = false;
} catch (IOException e) {
}
}
}