今日は雨なので、久しぶりにブログ更新です!!
今回は「上書き保存」機能を実装してみます。
今作っているテキストエディタは複数ウィンドウ出て来て、それぞれファイルを開くことができることもあって、ファイルロックは実装しておきたいところです。
それと新規作成でファイルを開いていない状態からの「上書き保存」は「名前を付けて保存」ってことなので、「名前を付けて保存」が実装されたら処理変更しないといけないです。
ということで、割と重い作業なので、ファイルロックだけ実装します。
①ファイルを開くときにファイルをロックする。
②ファイルを閉じるときにロックを解除する。
ファイルロックできないときは考えてないので、とりあえず例外だけ投げて放置です。
【FXMLDocumentController】
private ProcessManager pm;
private void openAction(ActionEvent event) {
bottomLabel.setText("開く");
pm.setSelectedFile(pm.openFileChooser(scene));
// ファイルが選択されたとき
if (pm.getSelectedFile() != null) {
pm.setCurrentFilePath(Paths.get(pm.getSelectedFile().getAbsolutePath()));
try {
// ファイルチャンネルを設定する
pm.setFileChannel(FileChannel.open(pm.getSelectedFile().toPath(),
StandardOpenOption.CREATE,
StandardOpenOption.WRITE));
if (pm.getFileChannel().tryLock() != null) {
// ファイルロックができれば表示する
textArea.setText(new String(Files.readAllBytes(pm.getCurrentFilePath()), pm.getCharset()));
}
} catch (OverlappingFileLockException ex) {
// 別のプロセスがロック中
} catch (IOException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
bottomLabel.setText(pm.getSelectedFile().getName());
}
}
/**
* MenuItem[閉じる] イベントが発生したウィンドウを非表示にします。
*
* @param event
*/
@FXML
void closeAction(ActionEvent event) {
bottomLabel.setText("閉じる");
try {
// ファイルロック解除
if(pm.getFileChannel() != null) {
pm.getFileChannel().close();
}
} catch (IOException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
pm.terminateTextEditer(getScene());
}
/**
* メニューの「上書き保存」を押下しすると、saveTextメソッドを呼び出します。
*
* @param event
*/
@FXML
private void saveAction(ActionEvent event) {
bottomLabel.setText("上書き保存");
pm.saveText(textArea.getText());
}
【ProcessManager】
/**
* 編集中のファイルパス
*/
private Path currentFilePath;
/**
* 作業中のファイルチャンネル
*/
private FileChannel fileChannel;
/**
* 開いているファイルにテキストデータを上書き保存します。
*
* @param text 保存するテキストデータ
*/
public void saveText(String text) {
try {
Files.write(currentFilePath, text.getBytes(charset),
StandardOpenOption.CREATE,
StandardOpenOption.WRITE,
StandardOpenOption.TRUNCATE_EXISTING
);
} catch (IOException ex) {
Logger.getLogger(ProcessManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
ソースが長くなってきて、かなり省略してますけど、いるところ抜けてないかな?
アクションにロジック書いちゃったのはミスでした。
ファイルロックできないときは参照モードとかもいるのかな?
テキストエディタって思ったより大変ですね。