2017年10月29日日曜日

テキストエディタをJavaで作成する計画5

日曜プログラマーごっこやるのもいいですが、晴れの日は外で遊びたいです。。。
今日は雨なので、久しぶりにブログ更新です!!

今回は「上書き保存」機能を実装してみます。
今作っているテキストエディタは複数ウィンドウ出て来て、それぞれファイルを開くことができることもあって、ファイルロックは実装しておきたいところです。
それと新規作成でファイルを開いていない状態からの「上書き保存」は「名前を付けて保存」ってことなので、「名前を付けて保存」が実装されたら処理変更しないといけないです。
ということで、割と重い作業なので、ファイルロックだけ実装します。

①ファイルを開くときにファイルをロックする。
②ファイルを閉じるときにロックを解除する。

ファイルロックできないときは考えてないので、とりあえず例外だけ投げて放置です。

【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);
        }
    }

ソースが長くなってきて、かなり省略してますけど、いるところ抜けてないかな?
アクションにロジック書いちゃったのはミスでした。
ファイルロックできないときは参照モードとかもいるのかな?
テキストエディタって思ったより大変ですね。

0 件のコメント:

コメントを投稿