一、团队介绍
成员 | 任务分配 | 团队成员博客 | |
---|---|---|---|
白靖 | 暂无 | 组长 | |
雷雯雯 | 暂无 | 组员 |
无参考项目
二、项目git链接
https://github.com/Sakura-demon/Sakura
三、项目git提交记录
四、前期调查
总规划设计主要参考word文档和文本文档。
五、功能架构图
六、面向对象设计
包图:
UML:
七、项目运行截图
文件操作
字体设置
字体大小
字体颜色
音乐播放
八、项目关键代码及模块描述
界面类:文本编辑器界面的设计
public class Text extends Application {
TextArea textArea = new TextArea();
public TextArea getTextArea() {
return textArea;
}
@Override
public void start(Stage stage) {
BorderPane root = new BorderPane();
//文本域
root.setCenter(textArea);
//设置文本域占据窗口大小
Rectangle2D screenRectangle = Screen.getPrimary().getBounds();
textArea.setMinSize(screenRectangle.getWidth()-200,screenRectangle.getHeight()-200);
textArea.setEditable(true);
//菜单栏
MenuBar menuBar = new MenuBar();
menuBar.prefWidthProperty().bind(stage.widthProperty());
root.setTop(menuBar);
//菜单
//文件
Menu fileMenu = new Menu("文件");
MenuItem newMenuItem = new MenuItem("新建文件");
MenuItem openMenuItem = new MenuItem("打开文件");
MenuItem saveMenuItem = new MenuItem("保存文件");
MenuItem saveAsMenuItem = new MenuItem("另存为");
MenuItem exitMenuItem = new MenuItem("退出");
fileMenu.getItems().addAll(newMenuItem,openMenuItem,saveMenuItem,saveAsMenuItem,exitMenuItem);
newMenuItem.setOnAction(actionEvent -> File.newFile());
openMenuItem.setOnAction(actionEvent -> File.openFile(stage));
saveMenuItem.setOnAction(actionEvent -> File.saveFile(textArea));
saveAsMenuItem.setOnAction(actionEvent -> File.saveAsFile(textArea));
exitMenuItem.setOnAction(actionEvent -> File.exit(stage));
//设置
Menu setMenu = new Menu("设置");
MenuItem typefaceMenuItem = new MenuItem("字体");
MenuItem sizeMenuItem = new MenuItem("字体大小");
MenuItem colorMenuItem = new MenuItem("字体颜色");
setMenu.getItems().addAll(typefaceMenuItem,sizeMenuItem,colorMenuItem);
typefaceMenuItem.setOnAction(actionEvent -> Set.typeface(textArea));
sizeMenuItem.setOnAction(actionEvent -> Set.size(textArea));
colorMenuItem.setOnAction(actionEvent -> Set.color(textArea));
//功能
Menu functionMenu = new Menu("功能");
MenuItem playMusicMenuItem = new MenuItem("播放音乐");
functionMenu.getItems().addAll(playMusicMenuItem);
playMusicMenuItem.setOnAction(event -> Music.playMusic());
//添加到菜单栏
menuBar.getMenus().addAll(fileMenu,setMenu,functionMenu);
Scene scene = new Scene(root);
scene.getAccelerators().put(new KeyCodeCombination(KeyCode.N, KeyCombination.CONTROL_DOWN), File::newFile);
scene.getAccelerators().put(new KeyCodeCombination(KeyCode.O, KeyCombination.CONTROL_DOWN), () -> File.openFile(stage));
scene.getAccelerators().put(new KeyCodeCombination(KeyCode.S, KeyCombination.CONTROL_DOWN), () -> File.saveFile(textArea));
scene.getAccelerators().put(new KeyCodeCombination(KeyCode.S, KeyCombination.CONTROL_DOWN, KeyCombination.SHIFT_DOWN), () -> File.saveAsFile(textArea));
scene.getAccelerators().put(new KeyCodeCombination(KeyCode.ESCAPE), () -> File.exit(stage));
stage.setScene(scene);
stage.setTitle("Sakura文本编辑器");
//设置窗口的图标.
stage.getIcons().add(new Image("/image/Icon.png"));
stage.initStyle(StageStyle.DECORATED);
stage.show();
}
}
操作类:对文件进行新建、保存、另存为、打开、退出操作
public class File {
/**
*新建文件
*/
public static void newFile(){
Text text = new Text();
text.start(new Stage());
}
/**
*打开文件
*/
public static void openFile(Stage stage){
//文件选择器选择打开文件
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("选择需要的打开的文件");
//获取要打开的文件
java.io.File file = fileChooser.showOpenDialog(stage);
//获取后缀名
String[] filename = file.toString().split("\\.");
int suffixIndex = filename.length -1;
String suffix = filename[suffixIndex];
try {
//定义读取流
BufferedReader bf = new BufferedReader(new FileReader(file));
String content = "";
StringBuilder sb = new StringBuilder();
//读取整个文件
while(true){
try {
content = bf.readLine();
} catch (IOException e) {
e.printStackTrace();
}
if(content == null){
break;
}
sb.append(content).append("\n");
}
try {
bf.close();
} catch (IOException e) {
e.printStackTrace();
}
StringBuilder str = new StringBuilder();
//判断后缀名是否为Sakura suffix.equals("sakura")
String postfix= "Sakura";
if (postfix.equals(suffix)){
int i = 0;
while (i != sb.length() - 1){
char cr = sb.charAt(i);
//将文本中的数字、大小写字母变换后一位的数
boolean existed = (sb.charAt(i) >= '0' && sb.charAt(i) <= '9') || (sb.charAt(i) >= 'a' && sb.charAt(i) <= 'z') || (sb.charAt(i) >= 'A' && sb.charAt(i) <= 'Z');
if (existed){
cr++;
str.append(cr);
}
i++;
}
}
else {
str = new StringBuilder(sb.toString());
}
//新建文件
Text text = new Text();
text.start(new Stage());
//写入文本
text.getTextArea().setText(str.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
/**
*保存文件(为加密文件后缀名.Sakura)
*/
public static void saveFile(TextArea textArea){
TextInputDialog save = new TextInputDialog();
setIcon(save);
save.setTitle("保存文件");
save.setHeaderText("请确定您文本的内容只有数字和英文字母,否则内容可能会丢失");
save.setContentText("请命名文件");
Optional<String> result = save.showAndWait();
if (result.isPresent()){
String filename = result.get();
//获取文本编辑器的文本
String str = textArea.getText();
//定义写入流
OutputStreamWriter ow;
//命名文件
String file = "src/file/"+filename+".sakura";
try {
//创建文件和定义编码
ow = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8);
try {
//写入文件
ow.write(str);
//关闭文件
ow.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
/**
* 另存为
*/
public static void saveAsFile(TextArea textArea){
Dialog<String> saveAs = new Dialog<>();
setIcon(saveAs);
saveAs.setTitle("另存为");
saveAs.setHeaderText("请确定您文本的内容只有数字和英文字母,否则内容可能会丢失");
//输入框
TextField choseFolderTextField = new TextField();
TextField nameFileTextField = new TextField();
//按钮
Button choseFolderBtn = new Button("选择路径");
choseFolderBtn.setOnMouseClicked(mouseEvent -> {
DirectoryChooser directoryChooser = new DirectoryChooser();
directoryChooser.setTitle("选择文件夹");
java.io.File folder = directoryChooser.showDialog(new Stage());
choseFolderTextField.setText(folder.toString()+"\\");
});
ButtonType loginButtonType = new ButtonType("确定", ButtonBar.ButtonData.OK_DONE);
saveAs.getDialogPane().getButtonTypes().addAll(loginButtonType, ButtonType.CANCEL);
//设置布局
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(20, 150, 10, 10));
grid.add(new Label("请选择目标路径"),0,0);
grid.add(choseFolderTextField,1,0);
grid.add(choseFolderBtn,2,0);
grid.add(new Label("请命名文件"),0,1);
grid.add(nameFileTextField,1,1);
//两个输入框没有输入时确定按钮不可用
Node loginButton = saveAs.getDialogPane().lookupButton(loginButtonType);
loginButton.setDisable(true);
choseFolderTextField.textProperty().addListener((observable, oldValue, newValue) -> loginButton.setDisable(newValue.trim().isEmpty()));
nameFileTextField.textProperty().addListener((observable, oldValue, newValue) -> loginButton.setDisable(newValue.trim().isEmpty()));
saveAs.getDialogPane().setContent(grid);
//当确定时返回两个输入框的值
saveAs.setResultConverter(dialogButton -> {
if (dialogButton == loginButtonType) {
return choseFolderTextField.getText()+","+nameFileTextField.getText();
}
return null;
});
saveAs.initStyle(StageStyle.DECORATED);
Optional<String> result = saveAs.showAndWait();
if (result.isPresent()){
String[] path = result.get().split(",");
String folderName = path[0];
String fileName = path[1];
//获取文本编辑器的文本
String str = textArea.getText();
//定义写入流
OutputStreamWriter ow;
//命名文件
String file = folderName+fileName+".sakura";
try {
//创建文件和定义编码
ow = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8);
try {
//写入文件
ow.write(str);
//关闭文件
ow.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
/**
* 退出
*/
public static void exit(Stage stage){
stage.close();
}
public static void setIcon(Dialog save) {
Stage stage = (Stage) save.getDialogPane().getScene().getWindow();
stage.getIcons().add(new Image("/image/Icon.png"));
}
}
九、项目代码扫描后修正结果
十、项目总结
-
这次课设不仅是对面向对象设计能力的提升,也是对javafx从无到有的发展。
-
有些功能还未实现,比如插入图片。
-
字体设置中,改变后的字体也不能在改变颜色后保持该字体,需要进一步改善。