java期末大作业:记事本

一.实验要求

在这里插入图片描述

二.设计界面

1.主界面Notepad.fxml

在这里插入图片描述

2.查找与替换界面Find.fxml

在这里插入图片描述

3.字体界面Font.fxml

在这里插入图片描述

三.主要功能

1.文件操作

1.1新建文件

	//文件新建
	@FXML
    void OnActionNew(ActionEvent event) throws FileNotFoundException, IOException, InterruptedException {
		//没保存的话要保存
		if(!isSaved)
			RequireSave();
		noteTextArea.setText(null);
    }

1.2保存文件

//文件保存 获取TextArea区域的内容,打开文件存储
	@FXML
	void OnActionSave(ActionEvent event) throws FileNotFoundException, IOException
	{
		String text=noteTextArea.getText();
		if(text.equals(""))
			return;
		FileChooser fileChooser = new FileChooser();
		//文件类型过滤
		FileChooser.ExtensionFilter extensionFilter = new FileChooser.ExtensionFilter("文本文档(*.txt)","*.txt");
		fileChooser.getExtensionFilters().add(extensionFilter);
		Stage stage=getStage();
		//获取得到的文件
		file = fileChooser.showOpenDialog(stage);
		if(file==null)
			return;
		fileOperation.WriteFile(file, "UTF-8", text);
		isSaved=true;
	}

1.3另存为文件

//文件另存为 获取TextArea区域的内容
	@FXML
    void OnActionOtherSave(ActionEvent event) throws FileNotFoundException, IOException {
		String text=noteTextArea.getText();
		FileChooser fileChooser = new FileChooser();
		//文件类型过滤
		FileChooser.ExtensionFilter extensionFilter = new FileChooser.ExtensionFilter("文本文档(*.txt)","*.txt");
		fileChooser.getExtensionFilters().add(extensionFilter);
		Stage stage=getStage();
		//获取得到的文件
		file=fileChooser.showSaveDialog(stage);
		if(file==null)
			return;
		fileOperation.WriteFile(file, "UTF-8", text);
		isSaved=true;
	}

1.4打开文件

//文件打开 打开一个txt文件,显示在TextArea上
	@FXML
    void OnActionOpen(ActionEvent event) throws IOException 
	{
		
		//打开资源管理器
		FileChooser fileChooser = new FileChooser();
		//文件类型过滤
		FileChooser.ExtensionFilter extensionFilter = new FileChooser.ExtensionFilter("文本文档(*.txt)","*.txt");
		fileChooser.getExtensionFilters().add(extensionFilter);
		Stage stage=getStage();
		//获取得到的文件
		file = fileChooser.showOpenDialog(stage);
		if(file==null)
			return;
		String text=fileOperation.ReadFile(file,"UTF-8");
		noteTextArea.setText(text);
		isSaved=true;
    }

2.查找操作

2.1查找上一个

	// 查找上一个
	@FXML
	void OnActionLast(ActionEvent event)
	{
		String target=findTextField.getText();
		String noteText=noteTextArea.getText();
		if (target.isEmpty())
		{
			Warning("查找文本为空!");
			return;
		}
		
		//查找文本不为空
		if (noteText.contains(target)) 
		{
			fromIndex=noteText.lastIndexOf(target, fromIndex);
			if (fromIndex == -1)
			{
				Warning("到第一个了");
				return;
			}
			if (fromIndex >= 0 && fromIndex < noteText.length()) 
			{
				System.out.println("fromindex:"+fromIndex);
				noteTextArea.selectRange(fromIndex, fromIndex+target.length());
				fromIndex -= target.length();
			}
		}
		else
			Warning("找不到相关内容");
	} 

2.2查找下一个

//查找下一个
    @FXML
    void OnActionNext(ActionEvent event) 
    {
    	String target=findTextField.getText();
		String noteText=noteTextArea.getText();
		if (target.isEmpty())
		{
			Warning("查找文本为空!");
			return;
		}
		//查找文本不为空
		if (noteText.contains(target)) 
		{
			System.out.println(startIndex);
			fromIndex=startIndex;
			startIndex = noteText.indexOf(target, startIndex);
			
			if (startIndex == -1)
			{
				Warning("到最后一个了");
				return;
			}
			if (startIndex >= 0 && startIndex < noteText.length()) 
			{
				noteTextArea.selectRange(startIndex, startIndex + target.length());
				startIndex += target.length();
			}
		}
		else
			Warning("找不到相关内容");
    }

3.替换操作

3.1一个一个替换

//一个一个替换
    @FXML
    void OnActionReplace(ActionEvent event) {
    	String target=findTextField.getText();
    	String replaceText=replaceTextField.getText();
    	String noteText=noteTextArea.getText();
    	if(replaceText.isEmpty())
    	{
    		Warning("替换文本不能为空!");
    		return;
    	}
    	if(noteText.contains(target))
    	{
    		fromIndex=startIndex;
			startIndex = noteText.indexOf(target, startIndex);
			if (startIndex == -1)
			{
				Warning("已经替换到最后一个了");
				return;
			}
			if (startIndex >= 0 && startIndex < noteText.length()) 
			{
				noteTextArea.selectRange(startIndex, startIndex + target.length());
				startIndex += target.length();
			}
			
			noteTextArea.replaceSelection(replaceText);
    	}
    	else
    		Warning("找不到相关内容");
    }

3.2全部替换

//一个一个替换
    @FXML
    void OnActionReplace(ActionEvent event) {
    	String target=findTextField.getText();
    	String replaceText=replaceTextField.getText();
    	String noteText=noteTextArea.getText();
    	if(replaceText.isEmpty())
    	{
    		Warning("替换文本不能为空!");
    		return;
    	}
    	if(noteText.contains(target))
    	{
    		fromIndex=startIndex;
			startIndex = noteText.indexOf(target, startIndex);
			if (startIndex == -1)
			{
				Warning("已经替换到最后一个了");
				return;
			}
			if (startIndex >= 0 && startIndex < noteText.length()) 
			{
				noteTextArea.selectRange(startIndex, startIndex + target.length());
				startIndex += target.length();
			}
			
			noteTextArea.replaceSelection(replaceText);
    	}
    	else
    		Warning("找不到相关内容");
    }

4.字体操作

4.1改变字体

//改变字体
	@FXML
    void fontChange(ActionEvent event) {
		FontType=fontComboBox.getValue();
		font=Font.font(FontType,FontSize);
		sampleTextArea.setFont(font);
    }

4.2改变样式

注意这个功能不是对所有字体都适用,所以不用纠结为什么有的效果不展示

//改变风格
    @FXML
    void styleChange(ActionEvent event) {
    	switch(styleComboBox.getValue())
    	{
    	case "常规":font=Font.font(FontType,FontWeight.NORMAL,
    			FontPosture.REGULAR,FontSize);break;
    	case "粗体":font=Font.font(FontType,FontWeight.BOLD,
    			FontPosture.REGULAR,FontSize);break;
    	case "斜体":font=Font.font(FontType,FontWeight.NORMAL,
    			FontPosture.ITALIC,FontSize);break;
    	case "粗斜体":font=Font.font(FontType,FontWeight.BOLD,
    			FontPosture.ITALIC,FontSize);break;
    	}
    	sampleTextArea.setFont(font);
    }

4.3改变大小

 //改变大小
    @FXML
    void sizeChange(ActionEvent event) {
    	FontSize=Integer.parseInt(sizeComboBox.getValue());
    	font=Font.font(FontType,FontSize);
    	sampleTextArea.setFont(font);
    }

四.全部代码

1.主界面

1.1FileController

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Optional;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextArea;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.text.Font;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

/**
 * @author xuchi
 * 2022年5月15日
 */
public class FileController {
	
	@FXML
    private TextArea noteTextArea;
	
	@FXML
	private MenuItem backMenuItem;

	@FXML
	private MenuItem redoMenuItem;

    @FXML
    private MenuItem findMenuItem;

    @FXML
    private MenuItem replaceMenuItem;
    
    @FXML
    private Label posLabel;
    
    @FXML
    private Label scaleLabel;

    File file;
	FileOperation fileOperation;
	
	public boolean isReplace=false;
	public boolean isChanged=false;
	public boolean isSaved=false;
	
	// 初始化
	@FXML
	void initialize()
	{
		//把controller加到hashmap:controllers里
		Main.controllers.put(this.getClass().getSimpleName(), this);
		 
		//实例化文件操作类
		fileOperation=new FileOperation();
		
		
		//初始化撤销重做,查找按钮
		backMenuItem.setDisable(true);
		redoMenuItem.setDisable(true);
		findMenuItem.setDisable(true);
		replaceMenuItem.setDisable(true);
		//释放键盘之后,撤销键可用
		noteTextArea.setOnKeyReleased(e->
		{
			//对于撤销重做
			backMenuItem.setDisable(false);

			//对于查找
			if(!noteTextArea.getText().isEmpty())
			{
				findMenuItem.setDisable(false);
				replaceMenuItem.setDisable(false);
			}
			else
			{
				findMenuItem.setDisable(true);
				replaceMenuItem.setDisable(true);
			}
		});
		
		//只要文本值改变了
		noteTextArea.textProperty()
		.addListener(new ChangeListener<String>() 
		{
            @Override
            public void changed
            (ObservableValue<? extends String> observable,
            		String oldValue, String newValue) 
            {
                isChanged=true;
            }
        });
		
		//点击查找
		findMenuItem.setOnAction(e->
		{
			isReplace=false;
			try
			{
				ShowFXML("Find.fxml","查找");
			} catch (IOException e1)
			{
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
		}
		);
		
		replaceMenuItem.setOnAction(e->
		{
			isReplace=true;
			try
			{
				ShowFXML("Find.fxml","替换");
			} catch (IOException e1)
			{
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
		}
		);
	    //当前光标的位置
        noteTextArea.caretPositionProperty().addListener((o,oldValue,newValue)->{
            int num= newValue.intValue();
            String textContain=noteTextArea.getText();
            int line=1,col=1;
            for(int i=0;i<num;i++)
            {
                if(textContain.charAt(i)=='\n')
                {
                	line++;
                    col=1;
                }
                else
                    col++;
            }
            String posText=String.format("第 %d 行,第 %d 列",line,col);
            posLabel.setText(posText);
        });
	}
	
	public TextArea getTextArea()
	{
		return noteTextArea;
	}
	
	public boolean RequireSave() throws FileNotFoundException, IOException, InterruptedException {
		// TODO Auto-generated method stub
		if(!isChanged)
			return false;
		Alert alert = new Alert(AlertType.CONFIRMATION);
		alert.setHeaderText("记事本");
		
		if(isSaved&&isChanged)
			alert.setContentText("是否将更改保存到"+file.getPath()+"?");
		else if(!isSaved)
			alert.setContentText("是否保存?");
		
		ButtonType save = new ButtonType("保存");
		ButtonType notsave = new ButtonType("不保存");
		ButtonType cancel = new ButtonType("取消");

		alert.getButtonTypes().setAll(save, notsave,cancel);

		Optional<ButtonType> result = alert.showAndWait();
		if(result.get()==notsave)
			return false;
		if(result.get()==cancel)
			return true;
		if(isSaved&&isChanged)
			fileOperation.WriteFile(file, "UTF-8", noteTextArea.getText());
		else if(!isSaved)
		{
			String text=noteTextArea.getText();
			FileChooser fileChooser = new FileChooser();
			//文件类型过滤
			FileChooser.ExtensionFilter extensionFilter = new FileChooser.ExtensionFilter("文本文档(*.txt)","*.txt");
			fileChooser.getExtensionFilters().add(extensionFilter);
			Stage stage=getStage();
			//获取得到的文件
			file=fileChooser.showSaveDialog(stage);
			//字体关闭,取消回到原位,
			if(file==null)
				return false;
			fileOperation.WriteFile(file, "UTF-8", text);
			isSaved=true;
		}
		return false;
	}
	
	
	//右键菜单->复制
    @FXML
    void OnActionCopy(ActionEvent event) {
    	noteTextArea.copy();
    }

    //右键菜单->粘贴
    @FXML
    void OnActionPaste(ActionEvent event) {
    	noteTextArea.paste();
    }

    //右键菜单->全选
    @FXML
    void OnActionSelectAll(ActionEvent event) {
    	noteTextArea.selectAll();
    }

    //右键菜单->剪切
    @FXML
    void OnActionCut(ActionEvent event) {
    	noteTextArea.cut();
    }
	
	//帮助
	 @FXML
    void OnActionHelp(ActionEvent event) throws IOException {
		 ShowFXML("Help.fxml", "帮助");
    }
	
	//缩放->字体变大
	 @FXML
    void OnActionBig(ActionEvent event) {
		Font CurrentFont = noteTextArea.getFont();
        double NewSize = CurrentFont.getSize() + 1;
        Font NewFont = Font.font(CurrentFont.getName(), NewSize);
        noteTextArea.setFont(NewFont);
        int scale=Integer.parseInt(scaleLabel.getText());
        scale+=10;
        scaleLabel.setText(Integer.toString(scale));
    }

	//缩放->字体变小
    @FXML
    void OnActionSmall(ActionEvent event) {
    	Font CurrentFont = noteTextArea.getFont();
        double NewSize = CurrentFont.getSize() - 1;
        Font NewFont = Font.font(CurrentFont.getName(), NewSize);
        noteTextArea.setFont(NewFont);
        int scale=Integer.parseInt(scaleLabel.getText());
        scale-=10;
        scaleLabel.setText(Integer.toString(scale));
    }
	
	//展示查找与替换界面
	private void ShowFXML(String FxmlName,String title) throws IOException
	{
		// 初始化fxml界面
		Stage FindStage = new Stage();
		Parent root = FXMLLoader.load(getClass().getResource(FxmlName));
		Scene scene = new Scene(root, 350, 70);
		FindStage.setScene(scene);
		FindStage.setTitle(title);
		FindStage.show();
		// 查找
	}
	
	//自动换行
	@FXML
    void OnActionWrap(ActionEvent event) {
		noteTextArea.wrapTextProperty().set(true);
    }
	
	//重做
	@FXML
	void OnActionRedo(ActionEvent event) {
		noteTextArea.redo();
		redoMenuItem.setDisable(true);
		backMenuItem.setDisable(false);
	}
	
	//撤销一步 
	@FXML
	void OnActionBack(ActionEvent event) {
		noteTextArea.undo();
		backMenuItem.setDisable(true);
		redoMenuItem.setDisable(false);
	}

	//文件新建
	@FXML
    void OnActionNew(ActionEvent event) throws FileNotFoundException, IOException, InterruptedException {
		//没保存的话要保存
		if(!isSaved)
			RequireSave();
		noteTextArea.setText(null);
    }
	
	//文件另存为 获取TextArea区域的内容
	@FXML
    void OnActionOtherSave(ActionEvent event) throws FileNotFoundException, IOException {
		String text=noteTextArea.getText();
		FileChooser fileChooser = new FileChooser();
		//文件类型过滤
		FileChooser.ExtensionFilter extensionFilter = new FileChooser.ExtensionFilter("文本文档(*.txt)","*.txt");
		fileChooser.getExtensionFilters().add(extensionFilter);
		Stage stage=getStage();
		//获取得到的文件
		file=fileChooser.showSaveDialog(stage);
		if(file==null)
			return;
		fileOperation.WriteFile(file, "UTF-8", text);
		isSaved=true;
	}
	
	//文件保存 获取TextArea区域的内容,打开文件存储
	@FXML
	void OnActionSave(ActionEvent event) throws FileNotFoundException, IOException
	{
		String text=noteTextArea.getText();
		if(text.equals(""))
			return;
		FileChooser fileChooser = new FileChooser();
		//文件类型过滤
		FileChooser.ExtensionFilter extensionFilter = new FileChooser.ExtensionFilter("文本文档(*.txt)","*.txt");
		fileChooser.getExtensionFilters().add(extensionFilter);
		Stage stage=getStage();
		//获取得到的文件
		file = fileChooser.showOpenDialog(stage);
		if(file==null)
			return;
		fileOperation.WriteFile(file, "UTF-8", text);
		isSaved=true;
	}
	
	//文件打开 打开一个txt文件,显示在TextArea上
	@FXML
    void OnActionOpen(ActionEvent event) throws IOException 
	{
		
		//打开资源管理器
		FileChooser fileChooser = new FileChooser();
		//文件类型过滤
		FileChooser.ExtensionFilter extensionFilter = new FileChooser.ExtensionFilter("文本文档(*.txt)","*.txt");
		fileChooser.getExtensionFilters().add(extensionFilter);
		Stage stage=getStage();
		//获取得到的文件
		file = fileChooser.showOpenDialog(stage);
		if(file==null)
			return;
		String text=fileOperation.ReadFile(file,"UTF-8");
		noteTextArea.setText(text);
		isSaved=true;
    }
		
	// 获取当前stage
	private Stage getStage()
	{
		return (Stage) noteTextArea.getScene().getWindow();
	}

	//进入字体界面
	@FXML
	void OnActionFont(ActionEvent event) throws IOException
	{
		// 初始化fxml界面
		Stage FindStage = new Stage();
		Parent root = FXMLLoader.load(getClass().getResource("Font.fxml"));
		Scene scene = new Scene(root, 400, 400);
		FindStage.setScene(scene);
		FindStage.setTitle("字体");
		FindStage.show();
	}
}

1.2FileOperation

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;


/**
 * @author xuchi
 * 2022年5月15日
 */
public class FileOperation {
	
	//读文件
	public String ReadFile(File file,String CharType) throws IOException
	{
		String text = "";
		// 1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称
		InputStreamReader isr = new InputStreamReader(new FileInputStream(file), CharType);
		// 2.使用InputStreamReader对象中的方法read读取文件
		int ch = 0;
		while ((ch = isr.read()) != -1)
			text += (char) ch;
		// 3.释放资源。
		isr.close();
		return text;
    }
	
	//写文件
	public void WriteFile(File file,String CharType,String content) throws IOException, FileNotFoundException
	{
		OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream(file), CharType);
		osw.write(content);
		osw.close();
	}
}

1.3Notepad.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.FileController">
   <top>
      <MenuBar BorderPane.alignment="CENTER">
        <menus>
          <Menu mnemonicParsing="false" text="文件">
            <items>
                  <MenuItem mnemonicParsing="false" onAction="#OnActionNew" text="新建" />
                  <MenuItem mnemonicParsing="false" onAction="#OnActionSave" text="保存" />
              <MenuItem mnemonicParsing="false" onAction="#OnActionOtherSave" text="另存为" />
                  <MenuItem mnemonicParsing="false" onAction="#OnActionOpen" text="打开" />
            </items>
          </Menu>
          <Menu mnemonicParsing="false" text="编辑">
            <items>
              <MenuItem fx:id="backMenuItem" mnemonicParsing="false" onAction="#OnActionBack" text="撤销" />
                  <MenuItem fx:id="redoMenuItem" mnemonicParsing="false" onAction="#OnActionRedo" text="重做" />
                  <MenuItem fx:id="findMenuItem" mnemonicParsing="false" text="查找" />
                  <MenuItem fx:id="replaceMenuItem" mnemonicParsing="false" text="替换" />
                  <MenuItem mnemonicParsing="false" onAction="#OnActionFont" text="字体" />
            </items>
          </Menu>
          <Menu mnemonicParsing="false" text="查看">
            <items>
                  <MenuItem mnemonicParsing="false" onAction="#OnActionHelp" text="帮助" />
              <MenuItem mnemonicParsing="false" onAction="#OnActionWrap" text="自动换行" />
                  <Menu mnemonicParsing="false" text="缩放">
                    <items>
                      <MenuItem mnemonicParsing="false" onAction="#OnActionBig" text="放大" />
                        <MenuItem mnemonicParsing="false" onAction="#OnActionSmall" text="缩小" />
                    </items>
                  </Menu>
            </items>
          </Menu>
        </menus>
      </MenuBar>
   </top>
   <center>
      <TextArea fx:id="noteTextArea" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
         <contextMenu>
            <ContextMenu>
              <items>
                  <MenuItem mnemonicParsing="false" onAction="#OnActionCopy" text="复制" />
                  <MenuItem mnemonicParsing="false" onAction="#OnActionPaste" text="粘贴" />
                  <MenuItem mnemonicParsing="false" onAction="#OnActionSelectAll" text="全选" />
                <MenuItem mnemonicParsing="false" onAction="#OnActionCut" text="剪切" />
              </items>
            </ContextMenu>
         </contextMenu></TextArea>
   </center>
   <bottom>
      <HBox prefHeight="36.0" prefWidth="600.0" BorderPane.alignment="CENTER">
         <children>
            <Label fx:id="posLabel" prefHeight="34.0" prefWidth="225.0" text="行1,列1" />
            <Separator orientation="VERTICAL" prefHeight="36.0" prefWidth="0.0" />
            <Label fx:id="scaleLabel" prefHeight="36.0" prefWidth="39.0" text="100" />
            <Label prefHeight="37.0" prefWidth="51.0" text="\%" />
            <Separator orientation="VERTICAL" prefHeight="200.0" />
            <Label prefHeight="36.0" prefWidth="161.0" text="Windows(CRLF)" />
            <Separator orientation="VERTICAL" prefHeight="200.0" />
            <Label prefHeight="40.0" prefWidth="55.0" text="UTF-8" />
         </children>
      </HBox>
   </bottom>
</BorderPane>

2.查找与替换

2.1FindController

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;

/**
 * @author xuchi
 * 2022年5月18日
 */
public class FindController {
    
	@FXML
    private TextField findTextField;
	
	@FXML
	public TextField replaceTextField;

	@FXML
	public Button replaceButton;

	@FXML
	public Button replaceallButton;
	
	TextArea noteTextArea;
	int startIndex=0;
	int fromIndex;

	
	//初始化,得到filecontroller
    @FXML
    void initialize()
    {
    	FileController controller = (FileController) Main.controllers.get(FileController.class.getSimpleName());
    	noteTextArea=controller.getTextArea();
    	fromIndex=noteTextArea.getText().length();
    	if(controller.isReplace)
    	{
    		replaceallButton.setVisible(true);
    		replaceButton.setVisible(true);
    		replaceTextField.setVisible(true);
    	}
    }
    
	// 用于弹出警示
	private void Warning(String warningInfo)
	{
		Alert alert = new Alert(AlertType.WARNING);
		alert.setTitle("Warning Dialog");
		alert.setContentText(warningInfo);
		alert.showAndWait();
	}

	// 查找上一个
	@FXML
	void OnActionLast(ActionEvent event)
	{
		String target=findTextField.getText();
		String noteText=noteTextArea.getText();
		if (target.isEmpty())
		{
			Warning("查找文本为空!");
			return;
		}
		
		//查找文本不为空
		if (noteText.contains(target)) 
		{
			fromIndex=noteText.lastIndexOf(target, fromIndex);
			if (fromIndex == -1)
			{
				Warning("到第一个了");
				return;
			}
			if (fromIndex >= 0 && fromIndex < noteText.length()) 
			{
				System.out.println("fromindex:"+fromIndex);
				noteTextArea.selectRange(fromIndex, fromIndex+target.length());
				fromIndex -= target.length();
			}
		}
		else
			Warning("找不到相关内容");
	} 

    //查找下一个
    @FXML
    void OnActionNext(ActionEvent event) 
    {
    	String target=findTextField.getText();
		String noteText=noteTextArea.getText();
		if (target.isEmpty())
		{
			Warning("查找文本为空!");
			return;
		}
		//查找文本不为空
		if (noteText.contains(target)) 
		{
			System.out.println(startIndex);
			fromIndex=startIndex;
			startIndex = noteText.indexOf(target, startIndex);
			
			if (startIndex == -1)
			{
				Warning("到最后一个了");
				return;
			}
			if (startIndex >= 0 && startIndex < noteText.length()) 
			{
				noteTextArea.selectRange(startIndex, startIndex + target.length());
				startIndex += target.length();
			}
		}
		else
			Warning("找不到相关内容");
    }
    
    //一个一个替换
    @FXML
    void OnActionReplace(ActionEvent event) {
    	String target=findTextField.getText();
    	String replaceText=replaceTextField.getText();
    	String noteText=noteTextArea.getText();
    	if(replaceText.isEmpty())
    	{
    		Warning("替换文本不能为空!");
    		return;
    	}
    	if(noteText.contains(target))
    	{
    		fromIndex=startIndex;
			startIndex = noteText.indexOf(target, startIndex);
			if (startIndex == -1)
			{
				Warning("已经替换到最后一个了");
				return;
			}
			if (startIndex >= 0 && startIndex < noteText.length()) 
			{
				noteTextArea.selectRange(startIndex, startIndex + target.length());
				startIndex += target.length();
			}
			
			noteTextArea.replaceSelection(replaceText);
    	}
    	else
    		Warning("找不到相关内容");
    }

    //全部替换
    @FXML
    void OnActionReplaceAll(ActionEvent event) {
    	String target=findTextField.getText();
    	String replaceText=replaceTextField.getText();
    	String noteText=noteTextArea.getText();
    	noteTextArea.setText(noteText.replaceAll(target, replaceText));
    }
}

2.2Find.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="187.0" prefWidth="470.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.FindController">
   <children>
      <GridPane layoutX="8.0" layoutY="4.0">
        <columnConstraints>
          <ColumnConstraints hgrow="SOMETIMES" maxWidth="116.0" minWidth="10.0" prefWidth="110.0" />
          <ColumnConstraints hgrow="SOMETIMES" maxWidth="95.0" minWidth="10.0" prefWidth="90.0" />
            <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        </rowConstraints>
         <children>
            <TextField fx:id="findTextField" promptText="查找" />
            <Button mnemonicParsing="false" onAction="#OnActionLast" text="上一条" GridPane.columnIndex="1" />
            <Button mnemonicParsing="false" onAction="#OnActionNext" text="下一条" GridPane.columnIndex="2" />
            <TextField fx:id="replaceTextField" promptText="替换" visible="false" GridPane.rowIndex="1" />
            <Button fx:id="replaceButton" mnemonicParsing="false" onAction="#OnActionReplace" text="替换" visible="false" GridPane.columnIndex="1" GridPane.rowIndex="1" />
            <Button fx:id="replaceallButton" mnemonicParsing="false" onAction="#OnActionReplaceAll" text="全部替换" visible="false" GridPane.columnIndex="2" GridPane.rowIndex="1" />
         </children>
      </GridPane>
   </children>
</AnchorPane>

3.字体

3.1FontController

import java.util.List;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextArea;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;

/**
 * @author xuchi
 * 2022年5月18日
 */
public class FontController {

	@FXML
    private ComboBox<String> fontComboBox;

    @FXML
    private ComboBox<String> styleComboBox;

    @FXML
    private ComboBox<String> sizeComboBox;

    @FXML
    private TextArea sampleTextArea;
    
    TextArea noteTextArea;
    
    //用于实时记录字体,大小
    private String FontType="System Regular";
    private int FontSize=12;
    
    private Font font;
    
    //初始化文本和combobox
	@FXML
	void initialize()
	{
		//向combobox里加入字体,样式,大小
		List<String> FontList=Font.getFontNames();
		fontComboBox.getItems().addAll(FontList);
		ObservableList<String> StyleList=
    			FXCollections.observableArrayList("常规","粗体","斜体","粗斜体");
		styleComboBox.setItems(StyleList);
		for(int i=2;i<=72;i=i+2)
	    	sizeComboBox.getItems().add(i+"");
		
		//初始化测试文本
		sampleTextArea.setText("这是测试文本");
		
		FileController controller = (FileController) Main.controllers.get(FileController.class.getSimpleName());
    	noteTextArea=controller.getTextArea();
	}
	
	
	//改变字体
	@FXML
    void fontChange(ActionEvent event) {
		FontType=fontComboBox.getValue();
		font=Font.font(FontType,FontSize);
		sampleTextArea.setFont(font);
    }

	//改变风格
    @FXML
    void styleChange(ActionEvent event) {
    	switch(styleComboBox.getValue())
    	{
    	case "常规":font=Font.font(FontType,FontWeight.NORMAL,
    			FontPosture.REGULAR,FontSize);break;
    	case "粗体":font=Font.font(FontType,FontWeight.BOLD,
    			FontPosture.REGULAR,FontSize);break;
    	case "斜体":font=Font.font(FontType,FontWeight.NORMAL,
    			FontPosture.ITALIC,FontSize);break;
    	case "粗斜体":font=Font.font(FontType,FontWeight.BOLD,
    			FontPosture.ITALIC,FontSize);break;
    	}
    	sampleTextArea.setFont(font);
    }

    //改变大小
    @FXML
    void sizeChange(ActionEvent event) {
    	FontSize=Integer.parseInt(sizeComboBox.getValue());
    	font=Font.font(FontType,FontSize);
    	sampleTextArea.setFont(font);
    }
    
    //确认后自动关闭设置字体的界面
    @FXML
    void notepadFontChange(ActionEvent event) {
    	noteTextArea.setFont(font);
    	Stage stage=(Stage)sampleTextArea.getScene().getWindow();
    	stage.close();
    }
}

3.2Font.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.FontController">
   <children>
      <GridPane layoutX="51.0" layoutY="43.0">
        <columnConstraints>
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        </rowConstraints>
         <children>
            <ComboBox fx:id="fontComboBox" onAction="#fontChange" prefWidth="150.0" GridPane.rowIndex="1" />
            <ComboBox fx:id="styleComboBox" onAction="#styleChange" prefWidth="150.0" GridPane.columnIndex="1" GridPane.rowIndex="1" />
            <ComboBox fx:id="sizeComboBox" onAction="#sizeChange" prefWidth="150.0" GridPane.columnIndex="2" GridPane.rowIndex="1" />
            <Label text="字体" />
            <Label text="样式" GridPane.columnIndex="1" />
            <Label text="大小" GridPane.columnIndex="2" />
         </children>
      </GridPane>
      <TextArea fx:id="sampleTextArea" layoutX="43.0" layoutY="135.0" prefHeight="156.0" prefWidth="312.0" />
      <Button layoutX="158.0" layoutY="307.0" mnemonicParsing="false" onAction="#notepadFontChange" text="确认" />
   </children>
</AnchorPane>

4.帮助

4.1HelpController

import javafx.fxml.FXML;
import javafx.scene.control.Label;

/**
 * @author xuchi
 * 2022年5月20日
 */
public class HelpController {
    @FXML
    private Label helpLabel;
    
    @FXML
    void initialize()
    {
    	helpLabel.setText("author:xuchi");
    }
}

4.2Help.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>


<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.HelpController">
   <children>
      <Label fx:id="helpLabel" layoutX="14.0" layoutY="14.0" text="Label" />
   </children>
</AnchorPane>

5.Main

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import javafx.scene.Parent;
import javafx.scene.Scene;

public class Main extends Application {
	
	 //创建一个Controller容器
    public static Map<String, Object> controllers = new HashMap<String, Object>();
	
	@Override
	public void start(Stage primaryStage) {
		try {
			Parent root =FXMLLoader.load(getClass().getResource("Notepad.fxml"));
			Scene scene = new Scene(root,600,400);
			scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
			primaryStage.setScene(scene);
			primaryStage.setTitle("新建");
			primaryStage.show();
			FileController controller = (FileController) Main.controllers.get(FileController.class.getSimpleName());
			primaryStage.setOnCloseRequest((EventHandler<WindowEvent>) new EventHandler<WindowEvent>() {
				@Override
				public void handle(WindowEvent event)
				{
					try
					{  
						//监听窗口关闭,询问是否保存,点击取消时,主界面继续运行,不能关闭
						if(controller.RequireSave())
							event.consume();
					} 
					catch (IOException | InterruptedException e)
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			});
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		launch(args);
	}
}

五.实验总结

1.不同controller之间的相互通信

我在做查找与替换的功能的时候,不知道怎么在FindController里面获取到FileController里的noteTextArea,也不知道怎么在一个controller里对另一个controller里的控件进行操作
解决办法:
在FileController里的initialize函数里写

Main.controllers.put(this.getClass().getSimpleName(), this);

然后在FindController里写

FileController controller = (FileController) Main.controllers
.get(FileController.class.getSimpleName());
noteTextArea=controller.getTextArea();

2.监听窗口关闭函数

primaryStage.setOnCloseRequest((EventHandler<WindowEvent>) new EventHandler<WindowEvent>() {
				@Override
				public void handle(WindowEvent event)
				{
					//这里写监听到之后要做的
				}
			});

3.展示其他fxml

	//展示查找与替换界面
	private void ShowFXML(String FxmlName,String title) throws IOException
	{
		// 初始化fxml界面
		Stage FindStage = new Stage();
		Parent root = FXMLLoader.load(getClass().getResource(FxmlName));
		Scene scene = new Scene(root, 350, 70);
		FindStage.setScene(scene);
		FindStage.setTitle(title);
		FindStage.show();
	}

4.文件类型过滤

//文件类型过滤
FileChooser.ExtensionFilter extensionFilter = new FileChooser.ExtensionFilter
("文本文档(*.txt)","*.txt");
fileChooser.getExtensionFilters().add(extensionFilter);
  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迟迟迟迟迟子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值