記錄一下本次課程設計用JAVA實現的簡單記事本。
要求:用圖形用戶界面時間。至少實現編輯、保存、另存爲、查找替換,以及剪切、複製、粘貼等功能。
提示:使用文件輸入輸出流。
1.先對記事本進行功能分析
在這裏,主要實現文件和編輯功能。
菜單欄中的文件內的子菜單功能有:新建、打開、保存、另存爲、退出
菜單欄中的編輯內的子菜單功能有:複製、粘貼、剪貼、刪除、查找、替換
2.幾個基本功能的實現
在記事本類裏面定義:
private String path = null;// 裝打開的文件的路徑
boolean save = false; // 沒有保存
int startIndex = 0; ///字符串開始的位置
2.1 打開功能
// 打開操作
openMenuItem.setOnAction(event -> {
openMethod();
});
// 打開方法
private void openMethod() {
FileChooser fc = new FileChooser(); // fileChooser打開一個目錄
fc.setTitle("選擇文件-打開"); // 設置文件選擇框的標題
// 過濾文件
fc.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("TXT", "*.txt"));
File file = fc.showOpenDialog(stage); // 打開文件
if (file != null && file.exists()) { // 文件存在
try {
// 讀取數據 放進多行文本框
FileInputStream in = new FileInputStream(file); // 用File對象創建文件輸入流對象
byte[] bs = new byte[(int) file.length()];
in.read(bs);
// 將內容設置到多行文本框
ta.setText(new String(bs));
in.close();
// 將文件路徑 保留到成員變量path中
path = file.getPath();
// 更改窗口標題
int lastIndex = path.lastIndexOf("\\"); // 查找字符串最後一次出現的位置
String title = path.substring(lastIndex + 1); // 從下標lastIndex開始到結束產生一個新的字符串
setTitle(title + "-我的記事本"); // 利用新的字符串重新設置窗口的標題
} catch (Exception e) {
}
}
}
2.2 新建功能
// 新建操作
newMenuItem.setOnAction(event -> {
newMethod();
});
// 新建方法
private void newMethod() {
if (save) { //如果內容已經保存了直接新建一個文件夾
// 清除文本框的內容
ta.setText("");
// 更改窗口標題
setTitle("新文件-我的記事本");
// 將開打的文件的路徑設置爲null
path = null;
} else if (!save && !ta.getText().isEmpty()) { //文本域內有內容且文本沒有保存時跳出提示
Stage newStage = new Stage();
VBox vBox = new VBox();
vBox.setPadding(new Insets(5,10,5,20));
vBox.setSpacing(5);
Label label1 = new Label("你還沒有保存內容!!!");
Label label2 = new Label("按“確定”則新建一個文本,");
Label label3= new Label("按“取消”則退出該窗口。");
vBox.getChildren().addAll(label1,label2,label3);
Button ok = new Button("確定");
Button cancel = new Button("取消");
HBox hBox = new HBox();
hBox.setPadding(new Insets(20,10,5,80));
hBox.setSpacing(30);
hBox.getChildren().addAll(ok,cancel);
BorderPane rootNode = new BorderPane();
rootNode.setTop(vBox);
rootNode.setCenter(hBox);
Scene scene = new Scene(rootNode,300,150);
newStage.setTitle("提示");
newStage.setScene(scene);
newStage.show();
ok.setOnAction(event->{
// 清除文本框的內容
ta.setText("");
// 更改窗口標題
setTitle("新文件-我的記事本");
// 將開打的文件的路徑設置爲null
path = null;
newStage.close();
});
cancel.setOnAction(event->{
newStage.close();
});
}
}
2.3 保存功能
// 保存操作
saveMenuItem.setOnAction(event -> {
saveMethod();
});
// 保存方法
private void saveMethod() {
// 需要判斷是新建之後的保存 還是打開之後的保存
// 新建之後的保存
if (path == null) {
FileChooser fc = new FileChooser();
fc.setTitle("選擇文件-保存");
// 獲取被用戶選擇的文件
File file = fc.showSaveDialog(stage);
// 如果用戶選了 而且文件是存在的
if (file != null && !file.exists()) {
// 將多行文本框中的內容寫到file指向的文件中去
try {
// 創建輸出流
FileOutputStream out = new FileOutputStream(file);
out.write(ta.getText().getBytes());
out.flush();
out.close();
save = true; // 已經保存了
} catch (Exception e) {
e.printStackTrace();
}
}
} else {// 打開之後的保存
try {
// 創建輸出流
FileOutputStream out = new FileOutputStream(path);
out.write(ta.getText().getBytes());
out.flush();
out.close();
save = true;// 已經保存了
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.4 另存爲功能
// 另存爲操作
saveAsMenuItem.setOnAction(event -> {
saveAsMethod();
});
// 另存爲方法
private void saveAsMethod() {
FileChooser fc = new FileChooser();
fc.setTitle("保存文件");
File file = fc.showSaveDialog(stage);
if (file != null) {
try {
FileOutputStream out = new FileOutputStream(file);
String str = ta.getText();
byte[] bs = str.getBytes();// 字符串轉換成字節數組
out.write(bs);
out.flush();
out.close();
save = true;
} catch (Exception e) {
// TODO: handle exception
}
}
}
2.5 退出操作
// 退出操作
exitMenuItem.setOnAction(event -> {
exitMethod();
});
// 退出方法
private void exitMethod() {
if (save) {
Platform.exit();
} else if (!save && !ta.getText().isEmpty()) {
Alert alert = new Alert(AlertType.WARNING);
alert.titleProperty().set("提示");
alert.headerTextProperty().set("你還沒有保存已編輯的內容!!!");
alert.show();
}
}
2.6 複製功能
// 複製操作
copyMenuItem.setOnAction(enent -> {
copyMethod();
});
// 複製方法
private void copyMethod() {
// 獲取系統剪貼板
Clipboard clipboard = Clipboard.getSystemClipboard();
ClipboardContent content = new ClipboardContent();
// 選取文本
String temp = ta.getSelectedText();
// 將獲取到的文本放到系統剪貼板中
content.putString(temp);
// 把內容放到文本剪貼板中
clipboard.setContent(content);
}
2.7剪切功能
// 剪切操作
cutMenuItem.setOnAction(event -> {
cutMethod();
});
// 剪切方法
private void cutMethod() {
// 獲取系統剪貼板
Clipboard clipboard = Clipboard.getSystemClipboard();
ClipboardContent content = new ClipboardContent();
// 選取文本
String temp = ta.getSelectedText();
// 將獲取到的文本放到系統剪貼板中
content.putString(temp);
// 把內容放到文本剪貼板中
clipboard.setContent(content);
// 用空字符串來代替選中的字符串
ta.replaceSelection("");
}
2.8 粘貼功能
// 粘貼操作
pastMenuItem.setOnAction(event -> {
pasteMethod();
});
// 粘貼方法
private void pasteMethod() {
// 獲取系統剪貼板
Clipboard clipboard = Clipboard.getSystemClipboard();
ClipboardContent content = new ClipboardContent();
Clipboard c = clipboard.getSystemClipboard();
if (c.hasContent(DataFormat.PLAIN_TEXT)) {
String s = c.getContent(DataFormat.PLAIN_TEXT).toString();
if (ta.getSelectedText() != null) { // 如果要粘貼時,鼠標已經選取了一段字符
ta.replaceSelection(s);
} else { // 如果要粘貼時,鼠標沒有選取字符,直接從光標後開始粘貼
int mouse = ta.getCaretPosition(); // 獲取文本域鼠標所在位置
ta.insertText(mouse, s);
}
}
}
2.9 刪除功能
// 刪除操作
deleteMenuItem.setOnAction(event -> {
deleteMethod();
});
// 刪除方法
private void deleteMethod() {
// 用空字符串來代替選中的字符串
ta.replaceSelection("");
}
2.10 查找功能
// 查找操作
findMenuItem.setOnAction(event -> {
findMethod();
});
// 查找方法
private void findMethod() {
HBox h1 = new HBox();
h1.setPadding(new Insets(20, 5, 20, 5));
h1.setSpacing(5);
Label lable1 = new Label("查找內容(N):");
TextField tf1 = new TextField();
h1.getChildren().addAll(lable1, tf1);
VBox v1 = new VBox();
v1.setPadding(new Insets(20, 5, 20, 10));
Button btn1 = new Button("查找下一個(F)");
v1.getChildren().add(btn1);
HBox findRootNode = new HBox();
findRootNode.getChildren().addAll(h1, v1);
Stage findStage = new Stage();
Scene scene1 = new Scene(findRootNode, 450, 90);
findStage.setTitle("查找");
findStage.setScene(scene1);
findStage.setResizable(false); // 固定窗口大小
findStage.show();
btn1.setOnAction((ActionEvent e) -> {
String textString = ta.getText(); // 獲取記事本文本域的字符串
String tfString = tf1.getText(); // 獲取要查找的字符串
if (!tf1.getText().isEmpty()) {
if (textString.contains(tfString)) {
// 查找方法
if (startIndex == -1) {// not found
Alert alert1 = new Alert(AlertType.WARNING);
alert1.titleProperty().set("提示");
alert1.headerTextProperty().set("已經找不到相關內容了!!!");
alert1.show();
}
startIndex = ta.getText().indexOf(tf1.getText(),startIndex);
if (startIndex >= 0 && startIndex < ta.getText().length()) {
ta.selectRange(startIndex, startIndex+tf1.getText().length());
startIndex += tf1.getText().length();
}
}
if (!textString.contains(tfString)) {
Alert alert1 = new Alert(AlertType.WARNING);
alert1.titleProperty().set("提示");
alert1.headerTextProperty().set("找不到相關內容了!!!");
alert1.show();
}
} else if (tf1.getText().isEmpty()) {
Alert alert1 = new Alert(AlertType.WARNING);
alert1.titleProperty().set("出錯了");
alert1.headerTextProperty().set("輸入內容爲空");
alert1.show();
}
});
}
2.11 替換功能
// 替換操作
replaceMenuItem.setOnAction(event -> {
replaceMethod();
});
// 替換方法
private void replaceMethod() {
HBox h1 = new HBox();
h1.setPadding(new Insets(20, 5, 10, 8));
h1.setSpacing(5);
Label label1 = new Label("查找下一個(F)");
TextField tf1 = new TextField();
h1.getChildren().addAll(label1, tf1);
HBox h2 = new HBox();
h2.setPadding(new Insets(5, 5, 20, 8));
h2.setSpacing(5);
Label label2 = new Label("替換內容(N):");
TextField tf2 = new TextField();
h2.getChildren().addAll(label2, tf2);
VBox v1 = new VBox();
v1.getChildren().addAll(h1, h2);
VBox v2 = new VBox();
v2.setPadding(new Insets(21, 5, 20, 10));
v2.setSpacing(13);
Button btn1 = new Button("查找下一個");
Button btn2 = new Button("替換爲");
v2.getChildren().addAll(btn1, btn2);
HBox replaceRootNode = new HBox();
replaceRootNode.getChildren().addAll(v1, v2);
Stage replaceStage = new Stage();
Scene scene = new Scene(replaceRootNode, 430, 120);
replaceStage.setTitle("替換");
replaceStage.setScene(scene);
replaceStage.setResizable(false); // 固定窗口大小
replaceStage.show();
btn1.setOnAction((ActionEvent e) -> {
String textString = ta.getText(); // 獲取記事本文本域的字符串
String tfString = tf1.getText(); // 獲取查找內容的字符串
if (!tf1.getText().isEmpty()) {
if (textString.contains(tfString)) {
if (startIndex == -1) {// not found
Alert alert1 = new Alert(AlertType.WARNING);
alert1.titleProperty().set("提示");
alert1.headerTextProperty().set("已經找不到相關內容了!!!");
alert1.show();
}
startIndex = ta.getText().indexOf(tf1.getText(),startIndex);
if (startIndex >= 0 && startIndex < ta.getText().length()) {
ta.selectRange(startIndex, startIndex+tf1.getText().length());
startIndex += tf1.getText().length();
}
btn2.setOnAction((ActionEvent e2) -> {
if(tf2.getText().isEmpty()) { //替換內容爲空時
Alert alert1 = new Alert(AlertType.WARNING);
alert1.titleProperty().set("出錯了");
alert1.headerTextProperty().set("替換內容爲空");
alert1.show();
}else { //替換內容不爲空則替換
ta.replaceSelection(tf2.getText());
}
});
}
if (!textString.contains(tfString)) {
Alert alert1 = new Alert(AlertType.WARNING);
alert1.titleProperty().set("提示");
alert1.headerTextProperty().set("找不到相關內容了!!!");
alert1.show();
}
} else if (tf1.getText().isEmpty()) {
Alert alert1 = new Alert(AlertType.WARNING);
alert1.titleProperty().set("出錯了");
alert1.headerTextProperty().set("輸入內容爲空");
alert1.show();
}
});
}