diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..359bb53 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..e8fe5af --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..712ab9d --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..d5cd614 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 742682c..0000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# jnotepad - -#### Description -{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md index 27bb15e..a61cc16 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,5 @@ # jnotepad -#### 介绍 -{**以下是 Gitee 平台说明,您可以替换此简介** -Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 -无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} - -#### 软件架构 -软件架构说明 - - #### 安装教程 1. xxxx @@ -27,13 +18,3 @@ Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request - - -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..b878016 --- /dev/null +++ b/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + org.example + JnotePad + 1.0-SNAPSHOT + + + 8 + 8 + UTF-8 + + + \ No newline at end of file diff --git a/src/main/java/JnotePad.java b/src/main/java/JnotePad.java new file mode 100644 index 0000000..e75dfe1 --- /dev/null +++ b/src/main/java/JnotePad.java @@ -0,0 +1,197 @@ +import javafx.application.Application; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.geometry.Insets; +import javafx.scene.Scene; +import javafx.scene.control.*; +import javafx.scene.image.Image; +import javafx.scene.layout.BorderPane; +import javafx.stage.FileChooser; +import javafx.stage.Stage; + +import java.io.*; + +public class JnotePad extends Application { + String iconSrc = "img/icon.png"; + + // 定义菜单栏 + MenuBar menuBar; + Menu fileMenu; + MenuItem newItem, openItem, saveItem, saveAsItem; + + // 定义主界面 + BorderPane root; + + // 定义多个Tab页 + TabPane tabPane; + int tabIndex = 0; + + // 定义状态栏 + Label statusLabel; + + @Override + public void start(Stage primaryStage) { + primaryStage.setTitle("JnotePad"); + + // 创建菜单栏并添加菜单项 + menuBar = new MenuBar(); + fileMenu = new Menu("文件"); + newItem = new MenuItem("新建"); + openItem = new MenuItem("打开"); + saveItem = new MenuItem("保存"); + saveAsItem = new MenuItem("另存为"); + fileMenu.getItems().addAll(newItem, openItem, saveItem, saveAsItem); + menuBar.getMenus().add(fileMenu); + + // 为菜单项添加事件处理器 + newItem.setOnAction(new NewFileEventHandler()); + openItem.setOnAction(new OpenFileEventHandler()); + saveItem.setOnAction(new SaveFileEventHandler()); + saveAsItem.setOnAction(new SaveAsFileEventHandler()); + + // 创建主界面 + root = new BorderPane(); + root.setTop(menuBar); + + // 创建Tab页和文本编辑区 + tabPane = new TabPane(); + root.setCenter(tabPane); + + // 创建状态栏 + statusLabel = new Label("行: 1 \t列: 1 \t字数: 0"); + root.setBottom(statusLabel); + BorderPane.setMargin(statusLabel, new Insets(5, 10, 5, 10)); + + // 创建场景并设置主界面 + Scene scene = new Scene(root, 800, 600); + primaryStage.setScene(scene); + primaryStage.getIcons().add(new Image(iconSrc)); + primaryStage.show(); + } + + // 新建文件事件处理器 + private class NewFileEventHandler implements EventHandler { + @Override + public void handle(ActionEvent event) { + TextArea textArea = new TextArea(); // 创建新的文本编辑区 + Tab tab = new Tab("新建文件 " + ++tabIndex); // 创建新的Tab页 + tab.setContent(textArea); + tabPane.getTabs().add(tab); + tabPane.getSelectionModel().select(tab); + updateStatusLabel(textArea); + } + } + + // 打开文件事件处理器 + private class OpenFileEventHandler implements EventHandler { + @Override + public void handle(ActionEvent event) { + FileChooser fileChooser = new FileChooser(); + File file = fileChooser.showOpenDialog(null); + if (file != null) { + try { + BufferedReader reader = new BufferedReader(new FileReader(file)); + String line; + StringBuilder textBuilder = new StringBuilder(); + while ((line = reader.readLine()) != null) { + textBuilder.append(line).append("\n"); // 读取文件内容 + } + reader.close(); + String text = textBuilder.toString(); + + TextArea textArea = new TextArea(text); // 创建新的文本编辑区 + Tab tab = new Tab(file.getName()); // 创建新的Tab页 + tab.setContent(textArea); + tab.setUserData(file); // 将文件对象保存到Tab页的UserData中 + tabPane.getTabs().add(tab); + tabPane.getSelectionModel().select(tab); + updateStatusLabel(textArea); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + // 保存文件事件处理器 + private class SaveFileEventHandler implements EventHandler { + @Override + public void handle(ActionEvent event) { + Tab selectedTab = tabPane.getSelectionModel().getSelectedItem(); + if (selectedTab != null) { + File file = (File) selectedTab.getUserData(); // 获取当前Tab页对应的文件对象 + if (file.exists()) { + try { + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + TextArea textArea = (TextArea) selectedTab.getContent(); // 获取当前Tab页的文本编辑区 + String text = textArea.getText(); + writer.write(text); // 写入文件内容 + writer.flush(); + writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } else { + saveAsFile(); + } + } + } + } + + // 另存为文件事件处理器 + private class SaveAsFileEventHandler implements EventHandler { + @Override + public void handle(ActionEvent event) { + saveAsFile(); + } + } + + // 另存为文件方法 + private void saveAsFile() { + Tab selectedTab = tabPane.getSelectionModel().getSelectedItem(); + if (selectedTab != null) { + FileChooser fileChooser = new FileChooser(); + File file = fileChooser.showSaveDialog(null); + if (file != null) { + try { + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + TextArea textArea = (TextArea) selectedTab.getContent(); // 获取当前Tab页的文本编辑区 + String text = textArea.getText(); + writer.write(text); // 写入文件内容 + writer.flush(); + writer.close(); + selectedTab.setText(file.getName()); // 更新Tab页标签上的文件名 + selectedTab.setUserData(file); // 将文件对象保存到Tab页的UserData中 + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + // 更新状态栏 + private void updateStatusLabel(TextArea textArea) { + textArea.caretPositionProperty().addListener((observable, oldValue, newValue) -> { + int row = getRow(textArea.getCaretPosition(), textArea.getText()); + int column = getColumn(textArea.getCaretPosition(), textArea.getText()); + int length = textArea.getLength(); + statusLabel.setText("行: " + row + " \t列: " + column + " \t字数: " + length); + }); + } + + // 获取光标所在行数 + private int getRow(int caretPosition, String text) { + return text.substring(0, caretPosition).split("\n").length; + } + + + // 获取光标所在列数 + private int getColumn(int caretPosition, String text) { + return caretPosition - text.lastIndexOf("\n", caretPosition - 1); + } + + public static void main(String[] args) { + launch(args); + } +} diff --git a/src/main/resources/img/icon.ico b/src/main/resources/img/icon.ico new file mode 100644 index 0000000..e3c1800 Binary files /dev/null and b/src/main/resources/img/icon.ico differ diff --git a/src/main/resources/img/icon.png b/src/main/resources/img/icon.png new file mode 100644 index 0000000..e057380 Binary files /dev/null and b/src/main/resources/img/icon.png differ