2018年2月25日日曜日

Raspberry Piでもスクリーンショットできるようにする件

ネットで調べてみると、いくつか方法があるようですが、
今回は「ksnapshot」を使うことにしました。

ターミナルで「sudo apt-get install ksnapshot」と入力すると、インストールできます。

インストールが完了すると、

メニュー > アクセサリ > Spectacle

で起動できるようになります。


少し英語が読めれば、分かりやすいし問題なく使えると思います。

Raspberry Pi に日本語入力を設定する件

設定しないと日本語入力できないことが分かったので、
設定方法調べました。バージョンによってやり方違うようですが、
僕の環境だと、LXTerminalを起動して、次のコマンドを入力するだけ。

「sudo apt-get install ibus-mozc」

インストールが完了すると、

「reboot」と入力して再起動すると、日本語入力できるようになりました。

Raspberry Pi 3 Model Bをセットアップしてみた件

今日は暇なので、ブログを更新です。

ラズベリーパイを使ってみます!!
最近はIOTが流行っているらしいので、僕もつまみ食いしてみようと思いました。

ラズベリーパイはOSがLinuxなので、僕にとっては勉強にもなるということで一石二鳥です。

ということで、僕が準備したものはこちら。

①Raspberry Pi 3 Model B
②microSDカード(16GB スピードクラス10) ⇒たぶん8GBで十分
③専用ケース ⇒必須ではないけど、壊しそうなのであった方が断然安心
④HDMIで接続できるモニタ
⑤USBで接続できるキーボード
⑥USBで接続できるマウス
⑦SD Card Formatter ⇒SDカードをフォーマットできるフリーソフト
⑧NOOBS_v2_4_5.zip ⇒https://www.raspberrypi.org/downloads/noobs/ からダウンロード


【手順1】
SD Card Formatterをインストールしてフォーマットする。


【手順2】
NOOBS_v2_4_5.zipを解凍して、SDカードにコピー


【手順3】
ラズパイにSDカードを挿して、USBをつなげると自動的に起動してOSのインストール画面が表示される。
言語=日本語
キーボード=jp
にしてから[インストール]をクリック
だいたい20分ぐらいで完了する。

【手順4】
右上のアイコンからWi-Fiを設定する。

【手順5】
左上のLXTerminalをクリックして、「sudo apt-get update」を入力する。
次に「sudo apt-get upgrade」を入力する。
しばらくすると、「続行しますか」と聞かれるので「y」を入力して続行。
30分ぐらいで完了した。


という具合に1時間程度で完了しました。

2017年12月23日土曜日

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

続きまして、第7回はポップアップ作成です。
バージョン情報を表示できるようにします。

【EditerView.fxml】

<Menu mnemonicParsing="false" text="ヘルプ">
    <items>
         <MenuItem mnemonicParsing="false" onAction="#aboutAction" text="バージョン情報" />
    </items>
</Menu>



【EditerController.java】

    private Editer editer;

    /**
     * バージョン情報
     *
     * @param event
     */
    @FXML
    private void aboutAction(ActionEvent event) {
        editer.showAboutInformationDialog();
    }



【Editer.java】

    /**
     * バージョン情報を表示します。
     */
    public void showAboutInformationDialog() {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle(CommonConst.ABOUT_INFORMATION_TITLE);
        alert.setHeaderText(CommonConst.ABOUT_INFORMATION_HEADER_TEXT);
        alert.setContentText(CommonConst.ABOUT_INFORMATION_CONTENT_TEXT);
        alert.showAndWait();
    }



【CommonConst.java】

    /**
     * バージョン情報画面 タイトル
     */
    public static final String ABOUT_INFORMATION_TITLE = "バージョン情報";

    /**
     * バージョン情報画面 ヘッダー
     */
    public static final String ABOUT_INFORMATION_HEADER_TEXT =
            "ヘッダー1行目\n" +            "ヘッダー2行目\n" +
            "ヘッダー3行目\n";

    /**
     * バージョン情報画面 コンテンツ
     */
    public static final String ABOUT_INFORMATION_CONTENT_TEXT =
            "コンテンツ1行目\n" +            "コンテンツ2行目\n" +
            "コンテンツ3行目\n";

[バージョン情報]をクリックすると、ポップアップが表示されるようになりました。









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

久しぶりにブログ更新です。

作成中のテキストエディタですが、ロジックがぐちゃぐちゃになってきそうなので、一旦構造を変えてみることにしました。

ターミナルで find コマンド入力するとこんな感じです。
XXXXXXXXXXX:src XXXXXXXXXX$ find .
./textediter
./textediter/controller
./textediter/controller/DialogController.java
./textediter/controller/EditerController.java
./textediter/controller/FindController.java
./textediter/controller/ReplaceController.java
./textediter/model
./textediter/model/CommonConst.java
./textediter/model/Dialog.java
./textediter/model/Editer.java
./textediter/model/Find.java
./textediter/model/Main.java
./textediter/model/Replace.java
./textediter/view
./textediter/view/DialogView.fxml
./textediter/view/EditerView.fxml
./textediter/view/FindView.fxm
./textediter/view/ReplaceView.fxml

これで実装し直してみたわけですが、FXMLファイルを別のパッケージに移動させると実行時エラーが出て地味に大変だったです。


Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalStateException: Location is not set.
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2434)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
at textediter.model.Editer.start(Editer.java:52)
at textediter.model.Main.start(Main.java:18)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Exception running application textediter.model.Main

いっぱい出てきましたが、一言で言うとFXMLファイルが参照できなかったみたいですね。
色々試してみた結果、これで治りました。

        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/textediter/view/EditerView.fxml"));

次はポップアップ作ろうと思います。

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

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

2017年10月1日日曜日

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

今回はファイルを「開く」機能を追加します。

流れとしては、

①メニューの「開く」ボタンを押下する。
②FileChooserを用いてファイルを選択する。
③選択したファイルのデータがTextAreaに表示される。

です。下記の内容で実装してみました。

【FXMLDocumentControllerクラス】FileChooserを呼び出し、戻り値のFileをUTF-8で読み込み、値をTextAreaにセットします。ついでに、ウィンドウの下の方にファイル名が表示されるようにしました。
public class FXMLDocumentController implements Initializable {

    private ProcessManager pm;
    private Scene scene;

    private void openAction(ActionEvent event) {
        bottomLabel.setText("開く");
        File selectedFile = pm.openFileChooser(scene);
        if(selectedFile != null) {
            try {
                textArea.setText(new String(Files.readAllBytes(Paths.get(selectedFile.getAbsolutePath())), StandardCharsets.UTF_8.name()));
            } catch(IOException e) {
                e.printStackTrace();
            }
            bottomLabel.setText(selectedFile.getName());
        }
    }
}


【ProcessManagerクラス】拡張子のフィルター機能がありますが、今回は一旦、「すべてのファイル」としておきました。
public class ProcessManager extends Application {

    public File openFileChooser(Scene scene) {
        FileChooser fileChooser = new FileChooser();
        fileChooser.getExtensionFilters().addAll(
                new ExtensionFilter("すべてのファイル", "*.*")
        );
        File selectedFile = fileChooser.showOpenDialog(scene.getWindow());
        return selectedFile;
    }
}






という事で、UTF-8ならちゃんとファイルを開くことができるプログラムができました。