javafx做的编辑器

发布时间 2023-05-17 11:34:06作者: 三号小玩家

javafx做的编辑器,这个是基本雏形。

这个代码是一个完整的文本编辑器,可以进行新建、打开、保存、另存为、剪切、复制、粘贴、删除、撤销、重做、全选等操作。

package com.example.javafxproject;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

import java.io.*;
import java.nio.charset.StandardCharsets;

public class TextEditor extends Application {

    private final TextArea textArea = new TextArea();
    private File currentFile = null;
    private SimpleBooleanProperty isSaved = new SimpleBooleanProperty(true);
    private Stage stage; // 用于保存 stage 的引用

    @Override
    public void start(Stage stage) {
        this.stage = stage; // 保存 stage 的引用,以便在事件处理器中使用

        BorderPane root = new BorderPane();

        // 工具栏
        ToolBar toolBar = createToolBar();
        root.setTop(toolBar);

        // 编辑区
        textArea.setWrapText(true);
        textArea.textProperty().addListener((observable, oldValue, newValue) -> {
            if (isSaved.getValue()) {
                isSaved.set(false);
                stage.setTitle(stage.getTitle() + " *");
            }
        });
        root.setCenter(textArea);

        // 状态栏
        Label statusLabel = new Label("就绪");
        isSaved.addListener((observable, oldValue, newValue) -> {
            if (newValue) {
                statusLabel.setText("已保存");
            } else {
                statusLabel.setText("未保存");
            }
        });
        root.setBottom(statusLabel);

        // 创建菜单栏
        MenuBar menuBar = createMenuBar(stage);
        root.setTop(menuBar);

        Scene scene = new Scene(root, 600, 400);
        scene.getStylesheets().add(getClass().getClassLoader().getResource("style.css").toString());
        stage.setScene(scene);
        stage.setTitle("文本编辑器");
        stage.setOnCloseRequest(event -> {
            if (!isSaved.getValue()) {
                // 弹出确认关闭窗口对话框
                Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
                alert.initOwner(stage);
                alert.setTitle("提示");
                alert.setHeaderText("文件未保存,是否要保存并退出?");

                ButtonType buttonSave = new ButtonType("保存");
                ButtonType buttonNotSave = new ButtonType("不保存");
                ButtonType buttonCancel = new ButtonType("取消", ButtonBar.ButtonData.CANCEL_CLOSE);

                alert.getButtonTypes().setAll(buttonSave, buttonNotSave, buttonCancel);
                alert.showAndWait().ifPresent(buttonType -> {
                    if (buttonType == buttonSave) {
                        saveFile();
                    }
                    if (buttonType != buttonCancel) {
                        Platform.exit();
                    }
                });
                event.consume();
            } else {
                Platform.exit();
            }
        });
        stage.show();
    }

    /**
     * 创建菜单栏
     */
    private MenuBar createMenuBar(Stage stage) {
        MenuBar menuBar = new MenuBar();

        // 文件菜单
        Menu fileMenu = new Menu("_文件");
        MenuItem newMenuItem = new MenuItem("_新建");
        newMenuItem.setOnAction(event -> createNewFile(stage));
        MenuItem openMenuItem = new MenuItem("_打开");
        openMenuItem.setOnAction(event -> openFile(stage));
        MenuItem saveMenuItem = new MenuItem("_保存");
        saveMenuItem.setOnAction(event -> saveFile());
        MenuItem saveAsMenuItem = new MenuItem("另存为...");
        saveAsMenuItem.setOnAction(event -> saveAsFile(stage));
        MenuItem exitMenuItem = new MenuItem("_退出");
        exitMenuItem.setOnAction(event -> {
            if (!isSaved.getValue()) {
                // 弹出确认关闭窗口对话框
                Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
                alert.initOwner(stage);
                alert.setTitle("提示");
                alert.setHeaderText("文件未保存,是否要保存并退出?");

                ButtonType buttonSave = new ButtonType("保存");
                ButtonType buttonNotSave = new ButtonType("不保存");
                ButtonType buttonCancel = new ButtonType("取消", ButtonBar.ButtonData.CANCEL_CLOSE);

                alert.getButtonTypes().setAll(buttonSave, buttonNotSave, buttonCancel);
                alert.showAndWait().ifPresent(buttonType -> {
                    if (buttonType == buttonSave) {
                        saveFile();
                    }
                    if (buttonType != buttonCancel) {
                        Platform.exit();
                    }
                });
            } else {
                Platform.exit();
            }
        });
        fileMenu.getItems().addAll(newMenuItem, openMenuItem, saveMenuItem, saveAsMenuItem, new SeparatorMenuItem(), exitMenuItem);

        // 编辑菜单
        Menu editMenu = new Menu("_编辑");
        MenuItem cutMenuItem = new MenuItem("_剪切");
        cutMenuItem.setOnAction(event -> textArea.cut());
        MenuItem copyMenuItem = new MenuItem("_复制");
        copyMenuItem.setOnAction(event -> textArea.copy());
        MenuItem pasteMenuItem = new MenuItem("_粘贴");
        pasteMenuItem.setOnAction(event -> textArea.paste());
        MenuItem deleteMenuItem = new MenuItem("_删除");
        deleteMenuItem.setOnAction(event -> textArea.deleteText(textArea.getSelection()));
        MenuItem selectAllMenuItem = new MenuItem("_全选");
        selectAllMenuItem.setOnAction(event -> textArea.selectAll());
        MenuItem undoMenuItem = new MenuItem("_撤销");
        undoMenuItem.setOnAction(event -> textArea.undo());
        MenuItem redoMenuItem = new MenuItem("_重做");
        redoMenuItem.setOnAction(event -> textArea.redo());
        editMenu.getItems().addAll(cutMenuItem, copyMenuItem, pasteMenuItem, deleteMenuItem, new SeparatorMenuItem(), selectAllMenuItem, undoMenuItem, redoMenuItem);

        // 关于菜单
        Menu helpMenu = new Menu("_帮助");
        MenuItem aboutMenuItem = new MenuItem("_关于");
        aboutMenuItem.setOnAction(event -> showAboutDialog());
        helpMenu.getItems().addAll(aboutMenuItem);

        menuBar.getMenus().addAll(fileMenu, editMenu, helpMenu);

        return menuBar;
    }

    /**
     * 创建工具栏
     */
    private ToolBar createToolBar() {
        Button newButton = new Button();
        newButton.setTooltip(new Tooltip("新建"));
        newButton.getStyleClass().add("icon-button");
        newButton.setOnAction(event -> createNewFile(null));
        newButton.setId(" new-button"); // 设置 CSS 样式


        Button openButton = new Button();
        openButton.setTooltip(new Tooltip("打开"));
        openButton.getStyleClass().add("icon-button");
        openButton.setOnAction(event -> openFile(null));
        openButton.setId("open-button");

        Button saveButton = new Button();
        saveButton.setTooltip(new Tooltip("保存"));
        saveButton.getStyleClass().add("icon-button");
        saveButton.setOnAction(event -> saveFile());
        saveButton.setId("save-button");

        ToolBar toolBar = new ToolBar(newButton, openButton, saveButton);
        toolBar.getStyleClass().add("toolbar");

        return toolBar;
    }

    /**
     * 新建文件
     */
    private void createNewFile(Stage stage) {
        if (!isSaved.getValue()) {
            saveFile();
        }
        textArea.clear();
        currentFile = null;
        isSaved.set(true);
        if (stage != null) {
            stage.setTitle("新建文档");
        } else {
            this.stage.setTitle("新建文档");
        }
    }

    /**
     * 打开文件
     */
    private void openFile(Stage stage) {
        if (!isSaved.getValue()) {
            saveFile();
        }
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("打开文件");
        fileChooser.getExtensionFilters().addAll(
                new FileChooser.ExtensionFilter("所有文件", "*.*"),
                new FileChooser.ExtensionFilter("文本文件", "*.txt"),
                new FileChooser.ExtensionFilter("Java 文件", "*.java")
        );
        if (currentFile != null) {
            fileChooser.setInitialDirectory(currentFile.getParentFile());
        }
        File selectedFile = fileChooser.showOpenDialog(stage);
        if (selectedFile != null) {
            try {
                BufferedReader reader = new BufferedReader(new FileReader(selectedFile, StandardCharsets.UTF_8));
                String line;
                StringBuilder sb = new StringBuilder();
                while ((line = reader.readLine()) != null) {
                    sb.append(line).append(System.lineSeparator());
                }
                textArea.setText(sb.toString());
                currentFile = selectedFile;
                isSaved.set(true);
                if (stage != null) {
                    stage.setTitle(currentFile.getName());
                } else {
                    this.stage.setTitle(currentFile.getName());
                }
            } catch (IOException e) {
                e.printStackTrace();
                Alert alert = new Alert(Alert.AlertType.ERROR);
                alert.initOwner(stage);
                alert.setTitle("错误");
                alert.setHeaderText("无法打开文件");
                alert.setContentText(e.getMessage());
                alert.showAndWait();
            }
        }
    }

    /**
     * 保存文件
     */
    private void saveFile() {
        if (currentFile == null) {
            saveAsFile(null);
        } else {
            try {
                BufferedWriter writer = new BufferedWriter(new FileWriter(currentFile, StandardCharsets.UTF_8));
                writer.write(textArea.getText());
                writer.flush();
                writer.close();
                isSaved.set(true);
                stage.setTitle(currentFile.getName());
            } catch (IOException e) {
                e.printStackTrace();
                Alert alert = new Alert(Alert.AlertType.ERROR);
                alert.initOwner(stage);
                alert.setTitle("错误");
                alert.setHeaderText("无法保存文件");
                alert.setContentText(e.getMessage());
                alert.showAndWait();
            }
        }
    }

    /**
     * 另存为文件
     */
    private void saveAsFile(Stage stage) {
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("另存为...");
        fileChooser.getExtensionFilters().addAll(
                new FileChooser.ExtensionFilter("文本文件", "*.txt"),
                new FileChooser.ExtensionFilter("Java 文件", "*.java"),
                new FileChooser.ExtensionFilter("所有文件", "*.*")
        );
        if (currentFile != null) {
            fileChooser.setInitialDirectory(currentFile.getParentFile());
        }
        File selectedFile = fileChooser.showSaveDialog(stage);
        if (selectedFile != null) {
            currentFile = selectedFile;
            saveFile();
        }
    }

    /**
     * 显示关于对话框
     */
    private void showAboutDialog() {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.initOwner(stage);
        alert.setTitle("关于");
        alert.setHeaderText("文本编辑器 v1.0");
        alert.setContentText("作者:binjie09\n邮箱:binjie09@qq.com");
        alert.showAndWait();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

style.css

.icon-button {
    -fx-background-color: transparent;
    -fx-background-insets: 0;
    -fx-background-radius: 0;
    -fx-padding: 0.5rem;
}

.icon-button:hover {
    -fx-background-color: #F3F3F3;
}

.icon-button .graphic {
    -fx-font-size: 1.5rem;
    -fx-fill: #666666;
}

.toolbar {
    -fx-padding: 0.5rem;
    -fx-background-color: #F3F3F3;
    -fx-border-width: 0 0 1px 0;
    -fx-border-color: #CCCCCC;
}

#new-button .graphic {
    -fx-shape: "M 4.5,6 H 3 V 9 H 0.5 V 10.5 H 3 V 14.5 H 4.5 V 11 H 7 V 9 H 4.5 Z";
}

#open-button .graphic {
    -fx-shape: "M 2.5,8.5 L 2.5,6.5 H 9.5 L 9.5,8.5 Z M 2.5,11.5 L 2.5,9.5 H 9.5 L 9.5,11.5 Z M 2.5,14.5 L 2.5,12.5 H 9.5 L 9.5,14.5 Z M 12.5,6.5 H 11 V 14.5 H 12.5 V 6.5 Z";
}

#save-button .graphic {
    -fx-shape: "M 3,9 H 1 V 14.5 H 13 V 9 H 11 V 12 H 3 Z M 6,10 V 8 H 8 V 10 Z M 10,10 V 8 H 12 V 10 Z";
}

.text-area {
    -fx-font-family: "Microsoft YaHei";
    -fx-font-size: 16px;
}