Premiers pas avec Java et création d'un éditeur Ascii Doc avec JavaFX

J'ai créé un éditeur AsciiDoc

Cliquez ici pour le produit fini AsciidocEditor ezgif.com-optimize.gif

En plus de l'aperçu en direct, certains paramètres de ascii doctor et ace editor peuvent être falsifiés à partir de l'interface graphique, et le CSS par défaut de ascii doctor et le CSS du surligneur source CodeRay sont importés localement. Si vous maîtrisez le CSS, vous pouvez utiliser votre design préféré.

Motivation

Je suis généralement un étudiant. J'ai commencé à programmer après mon entrée à l'université, et jusque-là je n'avais même pas touché à un ordinateur. La seule chose que je fais dans la pratique depuis que je suis entré à l'école est l'apprentissage d'algorithmes et l'écriture en langage C. Je pense qu'il est important et intéressant d'apprendre et de mettre en œuvre l'algorithme. Cependant, j’en suis venu à penser que ce n’est pas suffisant. J'ai donc décidé de créer une application graphique.

Du flux à l'achèvement

Premier semestre (apprentissage)

* Compétences avant de commencer à faire

Je suis habitué au langage C, mais je n'ai pas beaucoup appris sur Python car il a un modèle.

Premiers pas avec Java

Le membre du corps professoral a dit quelque chose comme "Au moins un type procédural et un type orienté objet devraient être touchés." Donc je ne suis pas très familier avec les langages de programmation, donc quand il s'agit de orienté objet, Java !! Dans cet esprit, j'ai décidé de me lancer dans Java.

Je l'ai acheté car il était recommandé à divers endroits. Il était facile à lire et à organiser en fonction de sa réputation, et j'ai pu imaginer l'orientation des objets.

Recherche préliminaire

Après avoir lu le livre d'introduction ci-dessus, j'avais envie de commencer, alors j'ai vérifié la bibliothèque Java GUI. Ce que nous avons appris à ce stade est le suivant.

Moyen terme (mi-temps)

À la suite de la recherche préliminaire, j'ai pensé que j'avais fait une sélection de langue difficile. J'ai pensé qu'il serait difficile de collecter des informations car JavaFX ne serait pas inclus dans le JDK.

Tardif (mise en œuvre)

Depuis que j'ai commencé avec beaucoup d'efforts, je vais reconsidérer ma création.

Quoi faire

Quelqu'un a implémenté l'éditeur de démarques facilement lors de la recherche préliminaire, j'ai donc pensé à ajouter l'élément d'origine à quelque chose de similaire. En recherchant diverses choses, j'ai découvert l'existence d'AsciiDoc. Faisons un éditeur Ascii Doc! Et voici la fonction de l'éditeur Ascii Doc le plus puissant auquel j'ai pensé

Si vous faites cela, ce n'est qu'un seul! !!

... ce n'était pas le cas. : innocent: AsciidocFX Je pense qu'il y a d'autres bonnes choses, mais je voulais ajouter des fonctionnalités qu'Asciidoc FX n'a pas aux fonctionnalités ci-dessus. AsciidocFX peut remplir le cadre de l'éditeur, mais pas l'écran de prévisualisation. Il s'avère que même si vous spécifiez toc: left et la position du tableau, vous ne pouvez pas le voir dans l'aperçu. (Peut-être que cela peut être fait ...)

Par conséquent, les spécifications finales sont les suivantes.

Je présenterai la partie où le développement a été retardé en raison d'un léger problème.

Fonctions de base de l'éditeur

Utilisez la classe FileChooser pour lire et enregistrer des fichiers dans JavaFX.

FileChooser fileChooser = new FileChooser();
File file = fileChooser.showOpenDialog(null);

Le problème était la valeur nulle passée à l'argument sur la deuxième ligne, et lorsque j'ai affiché l'application en plein écran, elle a cessé de répondre et j'ai dû la tuer. Au lieu de cela, passez la Stage principale comme argument. Un exemple qui hérite de la classe Application commune

public class Sample1 extends Application {
    public static void main(String[] args) {
        launch(args);
    }
    public void start(Stage primaryStage) throws Exception {
        FXMLLoader fxmlLoader = new FXMLLoader();
        Parent root = fxmlLoader.load(getClass().getResourceAsStream("/sample1.fxml")); 
        primaryStage.setTitle("sample 1");
        primaryStage.setScene(new Scene(root, 900, 600));
        primaryStage.show();
    }
}

Mais ça

public class Sample2 extends Application {

    static Stage stage;

    public static void main(String[] args) {
        launch(args);
    }
    public void start(Stage primaryStage) throws Exception {
        FXMLLoader fxmlLoader = new FXMLLoader();
        stage = primaryStage;
        Parent root = fxmlLoader.load(getClass().getResourceAsStream("/sample2.fxml")); 
        stage.setTitle("sample 2");
        stage.setScene(new Scene(root, 900, 600));
        stage.show();
    }
}

Passez à FileChooser comme

FileChooser fileChooser = new FileChooser();
File file = fileChooser.showOpenDialog(Sample2.stage);

De cette façon, même si vous déplacez la fenêtre principale, la fenêtre File Chooser sera jointe. Pour la classe Dialog

Dialog<ButtonType> dialog = new Dialog<>();
dialog.initOwner(Sample2.stage);

Vous pouvez faire la même chose avec.

Aperçu en direct (AsciiDoc-> HTML)

Bibliothèque utilisée

asciidoctorj rend la bibliothèque Ruby asciidoctor disponible en Java. La chaîne générée à partir de cela est versée dans la «WebView» de JavaFX. Je n'ai pas trouvé beaucoup d'exemples d'utilisation de asciidoctorj-diagram, donc je vais l'écrire pour référence.

Asciidoctor asciidoctor = org.asciidoctor.Asciidoctor.Factory.create();

Après avoir créé une instance avec

asciidoctor.requireLibrary("asciidoctor-diagram");

Ensuite, vous pourrez utiliser des fonctions telles que plantuml.

Problème 1: l'image locale ne s'affiche pas

JavaFX WebView peut être chargé et affiché par la méthode load ou la méthode loadContent de WebEngine. Cette fois, nous chargerons le HTML brut en tant que String au lieu de l'URL, nous utiliserons donc la méthode loadContent. Cependant, lorsque je charge du HTML avec cette méthode, il n'affiche pas l'image locale dans le chemin de l'attribut src. Tout ce dont j'avais besoin était d'avoir le protocole de fichier file: // à l'esprit. J'ai utilisé jsoup pour résoudre ce problème.

ArrayList<Element> src = document.getElementsByAttribute("src");
for (Element e : src) {
            String attributeValue = e.attr("src");
            if (!attributeValue.contains("data:") &&
                !attributeValue.contains("https:") &&
                !attributeValue.contains("file:")
            ) {
                attributeValue = Paths.get(attributeValue).toUri().toString();
                e.attr("src", attributeValue);
            }
        }

Le protocole de fichier est attaché par la méthode toUri.

Problème 2: problème lié au lien

Lorsque je clique sur le lien affiché dans la WebView de JavaFX, il est chargé par cette WebView, donc je ne peux pas voir l'aperçu d'AsciiDoc que je regardais à l'origine, bien que temporairement. Pour résoudre ce problème, je l'ai ouvert dans le navigateur par défaut.

//viewer est le composant fxml de WebView pour l'aperçu
viewer.getEngine().getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue == Worker.State.SCHEDULED) {
                String urlLocation = viewer.getEngine().getLocation();
                if (urlLocation.contains("http:") || urlLocation.contains("https:")) {
                    viewer.getEngine().getLoadWorker().cancel();
                    try {
                        Desktop.getDesktop().browse(new URI(urlLocation));
                    } catch (URISyntaxException | IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

Un autre problème était l'incapacité de sauter dans la page pour la balise a. Cette fois

viewer.getEngine().setJavaScriptEnabled(true);

Ce faisant, j'ai rendu JavaScript exécutable, ajouté une balise de script avec jsoup et chargé le script pour le lien d'ancrage.

String anchorLinkScript =
                "function anchorlink(id_name) {" +
                    "obj = document.getElementById(id_name);" +
                    "obj.scrollIntoView(true);" +
                "}";

        Element body = document.body();
        body.appendElement("script").append(anchorLinkScript);

        ArrayList<Element> elements = document.getElementsByTag("a");
        for (Element e : elements) {
            if (!(
                e.attr("href").contains("http:") ||
                e.attr("href").contains("https:")
            )) {
                String idName = e.attr("href").substring(1);
                e.attr("onclick", "anchorlink(\'" + idName + "\')");
            }
        }

* IM japonais pour Ace et Mac (déjà présenté dans l'article précédent)

J'ai résolu le problème car JapaneseIM sur Mac était bogué lorsque j'ai intégré Ace dans JavaFX

J'ai pu implémenter certaines fonctions comme celle-ci.

Des choses qui n'ont pas encore été faites

Aspect fonctionnel

Cette fois, il est converti à chaque fois que vous tapez un caractère, donc si vous utilisez la fonction asciidoctor-diagram, un fichier .png sera généré chaque fois que vous tapez un caractère. De plus, j'ai essayé de donner un nom de fichier pour l'empêcher

[plantuml, "sample"]
----
Bob->Alice: Hello
----

Si vous entrez dans l'ordre à partir du haut, sample.png lui-même changera fermement chaque fois que vous le saisissez, mais WebView n'affichera que le premier sample.png généré (re-app Il sera affiché au démarrage et le HTML exporté sera chargé sans aucun problème). Je suis inquiet parce que je n'en ai aucune idée.

Une autre fonctionnalité que je voulais inclure dans la sortie PDF.

Côté distribution

Fondamentalement, j'avais une image forte selon laquelle les applications peuvent être démarrées en double-cliquant sur l'icône, donc je visais également cela. Plus précisément, je voulais distribuer des applications multiplateformes en utilisant pleinement jlink, install4j et badass-runtime-plugin. Cependant, je sentais que je ne pourrais jamais publier les livrables en public à moins de les publier tels quels, alors j'ai abandonné et les ai publiés. À partir de Java 13, il peut y avoir jpackage, donc j'ai hâte d'y être!

Regarder en arrière

C'est dur de faire tout seul

Je l'ai fait moi-même sans le dire à personne, mais au final, il m'a fallu quatre mois pour le publier après avoir créé le référentiel sur GitHub. J'ai créé le référentiel après avoir pensé à créer l'éditeur AsciiDoc, donc cela fait environ 8 mois que j'ai commencé Java. La raison possible est

est. J'ai toujours pensé que le codage prendrait beaucoup de temps avant de le créer, mais il m'a fallu plusieurs fois plus de temps pour rechercher quelque chose que je ne comprenais pas et l'avaler. De plus, c'était douloureux que personne ne puisse me dire à quel point le codage était habituel à Java, comment c'était des spaghettis ou quelque chose que je ne remarquerais pas. De toute évidence, maintenir la motivation est très important. Cette fois, il y a eu une période de relâchement et je ne suis pas allé comme prévu, mais j'ai trouvé que même de petites choses peuvent me motiver. J'étais heureux chaque fois que je pensais à de petites fonctionnalités qu'AsciidocFX n'avait pas, et comme c'était ma première interface graphique, chacune fonctionnait comme prévu.

Il est important de lire la référence officielle

D'une manière ou d'une autre, quand je faisais toujours des recherches liées à la programmation, j'avais l'habitude de venir d'abord à Qiita. Qiita est facile car vous pouvez obtenir rapidement les informations que vous souhaitez connaître. Cependant, si vous souhaitez créer quelque chose à partir de zéro, il peut être important de consulter d'abord la documentation officielle. Puisque JavaFX 11 n'est plus inclus dans le JDK, je savais au début qu'il y avait un document Getting Started with JavaFX 11 pour cela. pas. C'était très facile à comprendre (petite sensation moyenne). Si nous avions réalisé la grandeur de la référence officielle un peu plus tôt, nous aurions pu raccourcir la période de développement. Après l'avoir remarqué, j'ai essayé de regarder la documentation API des bibliothèques que j'utilise, y compris Java. Si vous avez des dizaines d'onglets Firefox ouverts uniquement dans la documentation officielle de l'API, vous programmez! !! J'étais excité de ressentir cela. Je pense que cela a également aidé à maintenir la motivation.

Résumé

J'ai défié la première interface graphique dans la langue que j'ai touchée pour la première fois. J'ai écrit que c'est difficile à faire seul, mais il y a un bon sentiment d'accomplissement (je pense que si vous n'êtes pas seul, vous pouvez partager le sentiment d'accomplissement, donc je ne sais pas lequel).

Si vous débutez dans la programmation comme moi qui lisez ceci, je vous recommande de faire quelques recherches préliminaires avant de vous lancer dans les langages de programmation (ce qui peut être évident ...). Dès le début de la mise en œuvre, je pense que vous coderez tout en recherchant, mais ce sera sûrement amusant car vous constaterez que la technologie sera bien meilleure que la lecture du livre d'introduction et l'écriture d'exemples. Éliminez la résistance à l'anglais et lisez la documentation officielle, Stackoverflow, etc. (car il y a parfois des gens forts dans Stackoverflow qui sont comme de la merde).

Et pour le programmeur senior qui l'a vu jusqu'à la fin, je n'ai peut-être rien écrit qui serait utile. Si vous êtes gentil, je vous serais reconnaissant si vous pouviez jeter un coup d'œil à GitHub et m'encourager à dire: "Ce code source est Akan !!" De plus, un tel langage et une telle bibliothèque sont intéressants! Ou, j'aurais aimé avoir lu ceci avant de commencer le développement ... J'espère que vous pourrez me raconter un article comme celui-là (mendiant).

Quand je l'ai relu, ça ressemble à "Quel nombre décoction et Nen", mais merci d'avoir lu jusqu'au bout.

Recommended Posts

Premiers pas avec Java et création d'un éditeur Ascii Doc avec JavaFX
Premiers pas avec Java Collection
Premiers pas avec les bases de Java
Premiers pas avec Ruby pour les ingénieurs Java
Introduction à Java à partir de 0 Partie 1
Premiers pas avec la création d'ensembles de ressources avec ListResoueceBundle
Premiers pas avec Java_Chapter 8_A propos des "Instances" et des "Classes"
Liens et mémos pour démarrer avec Java (pour moi-même)
Premiers pas avec Java 1 Assembler des éléments similaires
Premiers pas avec Kotlin à envoyer aux développeurs Java
Premiers pas avec DBUnit
Premiers pas avec Ruby
Premiers pas avec Swift
Premiers pas avec Doma-Transactions
Prise en main des programmes Java à l'aide de Visual Studio Code
Préparer l'environnement pour java11 et javaFx avec Ubuntu 18.4
Premiers pas avec les anciens ingénieurs Java (Stream + Lambda)
Revenir au début et démarrer avec Java ① Types de données et modificateurs d'accès
Créer un contrôleur radio Ev3 avec JavaFx et leJOS [Partie 2]
Premiers pas avec le traitement Doma-Annotation
Premiers pas avec Reactive Streams et l'API JDK 9 Flow
Premiers pas avec JSP et servlet
Premiers pas avec Spring Boot
Créer un contrôleur radio Ev3 avec JavaFx et leJOS [Partie 1]
Premiers pas avec les modules Ruby
Utiliser java avec MSYS et Cygwin
Traçage distribué avec OpenCensus et Java
Installez Java et Tomcat avec Ansible
Mémo d'apprentissage Java (création d'un tableau)
Premiers pas avec Java_Chapitre 5_Exercices pratiques 5_4
À propos de la création d'applications avec Springboot
Utilisez JDBC avec Java et Scala.
Bonjour tout le monde avec Kotlin et JavaFX
[Java] Déclarer et initialiser un tableau
[Google Cloud] Premiers pas avec Docker
Sortie PDF et TIFF avec Java 8
Faites glisser et déposez des fichiers avec JavaFX
Premiers pas avec Docker avec VS Code
Exécuter des applications écrites en Java8 en Java6
Crypter avec Java et décrypter avec C #
Premiers pas avec Micronaut 2.x ~ Construction native et déploiement sur AWS Lambda ~
Comment créer une application avec un mécanisme de plug-in [C # et Java]
Premiers pas avec le Machine Learning avec Spark "Price Estimate" # 1 Chargement des ensembles de données avec Apache Spark (Java)
Premiers pas avec Gradle (jusqu'à ce que vous créiez un projet Java et combiniez des bibliothèques externes en un seul JAR exécutable)
Premiers pas avec Maven (jusqu'à ce que vous créiez un projet Java et combiniez des bibliothèques externes en un seul JAR exécutable)
Premiers pas avec Doma-Criteria API Cheet Sheet
[Java] Créer un module exécutable avec Gradle
Surveillez les applications Java avec jolokia et hawtio
Lier le code Java et C ++ avec SWIG
Essayons WebSocket avec Java et javascript!
Premiers pas avec Docker pour Mac (installation)
[Java] Lecture et écriture de fichiers avec OpenCSV
Introduction au test de paramétrage dans JUnit
Agrandir / réduire et mouvement parallèle avec JavaFX Canvas (Revenge)
Premiers pas avec Ratpack (4) - Routage et contenu statique
Démarrez avec le fonctionnement de JVM GC
Premiers pas avec Language Server Protocol avec LSP4J