Créer un outil de diaporama avec JavaFX

Aperçu

En novembre 2016, je me suis dit: «Si vous voulez faire une session JavaFX, faisons un outil de diaporama avec JavaFX», alors je viens de le faire, alors j'ai décidé de le laisser dans l'article.

Le diaporama est une combinaison de diaporama et de diaporama et semble être un seul mot. [Article Wikipedia sur la version japonaise](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%89%E3%82% Il était écrit en B7% E3% 83% A7% E3% 83% BC).

Réalisations des ancêtres

Il existe de nombreux exemples d'implémentation d'outils de diaporama (présentation) utilisant JavaFX, dont M. Sakuraba de Java Champion.

Pourquoi l'avez-vous fait vous-même sans utiliser ceux existants?

Je voulais juste l'implémenter d'une manière qui me soit facile à utiliser.


Fonctions requises pour les outils de diaporama

――Les personnages et les images peuvent être affichés en plein écran …… Mettre le volet avec étiquette dans la scène et afficher en plein écran? --Plusieurs diapositives peuvent être commutées et affichées

Comment mettre en œuvre?

Je pense qu'il y a plusieurs façons de le faire.

-Créer du contenu avec révéler.js ou Remark.js et l'afficher dans WebView …… Cela a l'air bien une fois fait avec cela, et il est facile d'organiser et de convertir en PDF --Afficher le contenu PDF --Convertir le contenu en JavaFX Pane pour l'affichage

J'ai déjà fait 1 donc j'ai décidé de tout faire en JavaFX cette fois.


Environnement d'exécution

Name version
Java SE 1.8.0_121
OS Windows 10
Eclipse 4.5
Gradle 3.0

la mise en oeuvre

L'ensemble du code source a été placé dans le référentiel GitHub ci-dessous.

Les points sont présentés ci-dessous.

Description du contenu

Autorisé les développeurs à écrire du contenu dans Markdown, qu'ils connaissent bien sur Qiita et GitHub. Le degré de liberté est faible, mais vous pouvez facilement préparer le contenu comme indiqué ci-dessous.

# Title
toastkidjp

##À propos de cette diapositive 1234567890123456789012345678901234567890
L'autre jour, java avec élan.io.J'ai remplacé le code qui utilisait File par Path and Files, je vais donc le présenter du point de vue de la réécriture du code existant. Si vous êtes déjà familier avec NIO2, vous ne remarquerez probablement rien après avoir lu cet article.

À propos, la nouvelle API liée aux fichiers de JDK7 est NIO2(New I/O 2)Il semble qu'il s'appelle, non marqué est 1.Il semble faire référence aux chaînes et aux jeux de caractères ajoutés à la 4ème ère.

##Le code peut également être placé

` ``java
(1..100)
  .collect{it % 15 == 0 
           ? "FizzBuzz" 
           :  it % 3 ==0 
               ? "Fizz" 
               : it % 5 == 0
                   ? "Buzz" 
                   : it
                   }
  .forEach{print it + ", "}
` ``

#c'est tout
Merci beaucoup.

Notez que je ne peux pas utiliser JavaCC, donc Parser est une implémentation enfantine qui lit le texte du fichier Markdown ligne par ligne ...

Implémentation de la diapositive

Afin d'afficher la barre de défilement lorsque la hauteur du contenu dépasse la hauteur de l'affichage, nous avons hérité de ScrollPane et implémenté un volet qui collecte les nœuds qui affichent des chaînes et des images dans le contenu.

Mettre toutes les diapositives dans la liste, One Draw on StackPane et seulement ceux actuels Est affiché, et les autres sont masqués.

Les caractères d'étiquette sont tronqués

Si vous utilisez l'objet Label par défaut, les chaînes qui dépassent la zone d'affichage ne seront pas affichées et seront tronquées.

ss6.png

Les paramètres suivants ont été définis pour l'objet Label.

Paramètre pour empêcher la chaîne de caractères d'être tronquée


label.setWrapText(true);
label.setMinHeight(Region.USE_PREF_SIZE);

ss6_.png

Le problème que la hauteur du contenu dépasse la hauteur de l'écran

En référence à la méthode de diapositive Qiita, le défilement vertical est possible lorsque la diapositive dépasse la hauteur d'affichage. Plus précisément, la classe Slide hérite de ScrollPane et définit les paramètres suivants dans le constructeur. Cela vous permet de désactiver le défilement horizontal et d'afficher la barre de défilement verticale uniquement lorsque vous en avez besoin.

Désactivez le défilement horizontal et n'affichez la barre de défilement vertical que si nécessaire


this.setHbarPolicy(ScrollBarPolicy.NEVER);
this.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);

ss1.png ss3.png

De plus, je pense que c'est parce que j'ai beaucoup d'objets Slide empilés, mais je ne pouvais pas déplacer la barre de défilement avec la souris, donc j'essaye de la déplacer en appelant la méthode suivante avec un raccourci clavier.

Faire défiler vers le haut


setVvalue(getVvalue() - 0.20d);

Défiler vers le bas


setVvalue(getVvalue() + 0.20d);

Connexion sous-menu et classe principale

Compte tenu de la facilité d'utilisation, nous avons préparé les sous-menus suivants.

ss5.png

Le sous-menu Controller et la classe Main, qui implémente des fonctions spécifiques, sont des classes distinctes. L'événement reçu dans le sous-menu doit être transmis à la classe Main pour traitement. Il existe plusieurs façons de faire cela, cette fois en utilisant une bibliothèque appelée Reactor.

Préparation de la classe de message

Préparez diverses classes de messages pour transmettre ce que vous voulez que la classe Main traite. Créez chaque classe en tant qu'implémentation de l'interface Message.

Acceptez les événements de l'interface utilisateur des utilisateurs et envoyez un message à Main

Créez un objet événement avec la méthode annotée @FXML et transmettez-le à la classe Main à l'aide de TopicProcessor. TopicProcessor crée une instance lorsque la classe de sous-menu est initialisée, passe l'objet à la classe Main via getter, s'abonne à la classe Main et se branche au traitement en fonction du type d'implémentation de l'événement dans subscribe.

Cette implémentation est basée sur un mécanisme appelé EventBus utilisé dans le développement d'applications Android.

point important

Étant donné que le thread d'exécution de la méthode appelée à partir de TopicProcessor n'est pas le thread d'application JavaFX, vous devez utiliser Platform.runLater pour effectuer le traitement lié au dessin.

L'inconvénient d'adopter ce mécanisme est que la classe Main grandit simplement. Cette fois, je fais des compromis.

Fichier PDF du diaporama

Dans la plupart des cas, vous devrez distribuer le diaporama PDF en tant que ressource. En prévision d'un tel cas, nous créons également une fonction de conversion PDF.

Convertissez toutes les diapositives en PDF à l'aide de PDFBox


try (final PDDocument doc = new PDDocument()) {
    final int width  = (int) stage.getWidth();
    final int height = (int) stage.getHeight();
    Interval.oneTo(slides.size()).each(i ->{
        moveTo(i);
        final long istart = System.currentTimeMillis();
        final PDPage page = new PDPage(new PDRectangle(width, height));
        try (final PDPageContentStream content = new PDPageContentStream(doc, page)) {
            content.drawImage(LosslessFactory.createFromImage(
                    doc, slides.get(current.get() - 1).generateImage(width, height)), 0, 0);
        } catch(final IOException ie) {
            LOGGER.error("Occurred Error!", ie);
        }
        doc.addPage(page);
        LOGGER.info("Ended page {}. {}[ms]", i, System.currentTimeMillis() - istart);
    });
    doc.save(new File(DEFAULT_PDF_FILE_NAME));
} catch(final IOException ie) {
    LOGGER.error("Occurred Error!", ie);
}

Je feuillette les diapositives une par une, prends les images capturées de chaque diapositive et combine ces images en un seul fichier PDF à l'aide d'une bibliothèque appelée PDFBox.

Lorsque je l'ai essayé, il a fallu 1 seconde pour convertir 4 diapositives en PDF.

2017-02-16 23:32:30  INFO Main Ended page 1. 334[ms]
2017-02-16 23:32:31  INFO Main Ended page 2. 269[ms]
2017-02-16 23:32:31  INFO Main Ended page 3. 181[ms]
2017-02-16 23:32:31  INFO Main Ended page 4. 169[ms]
2017-02-16 23:32:31  INFO Main Ended generating PDF. 1032[ms]

À propos, Interval est [Eclipse Collections](https: // www) .eclipse.org / collections / ja /) classe.

Le fichier PDF préparé pour la présentation proprement dite a été téléchargé sur Speaker Deck. https://speakerdeck.com/toastkidjp/jjug-ccc-2016-fall-number-ccc-l5

Exemple d'affichage de code

Il semble que le code source soit souvent affiché dans la présentation du développeur. Il est difficile de voir le code tel qu'il est dans Label, j'ai donc utilisé une bibliothèque (CodeArea) appelée RichTextFX qui est une implémentation de TextArea qui peut être mise en évidence.

Par exemple, le FizzBuzz de Groovy peut être affiché avec la coloration syntaxique comme indiqué ci-dessous.

ss4.png

Tâche

JVM se bloque lors de la sortie de l'application directement à partir du plein écran

Je ne connais pas bien la cause ... Au fait, dans le cas de `` gradle run '', un message d'erreur similaire s'affiche, mais il se termine normalement.

Message de la console


#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000000737b584a, pid=15116, tid=0x000000000000246c
#
# JRE version: Java(TM) SE Runtime Environment (8.0_102-b14) (build 1.8.0_102-b14)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.102-b14 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [glass.dll+0x2584a]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# /path/to/slide_show/hs_err_pid15116.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#

Texte intégral

https://gist.github.com/toastkidjp/1d216a9ad98a65dd0bc42552dfe99791

Affichage réduit lorsque la taille d'affichage change

Je pense que c'est parce que la zone d'affichage est variable, mais ... Les outils existants qui fonctionnent bien dans ce domaine sont merveilleux. Je me demande si je peux appliquer la méthode d'acquisition de la taille d'affichage utilisée par M. Takahashi dans JJUG CCC 2016 Fall et changer dynamiquement la taille de la police, mais je ne l'ai pas encore essayée.

Lorsque j'ai utilisé cet outil auparavant, j'avais une pause de 30 minutes, alors j'ai soigneusement vérifié la réduction de l'affichage.


Résumé

Jusqu'à présent, j'ai présenté l'une des façons de créer un diaporama à l'aide de JavaFX. Eh bien, il est plus facile, plus sûr et plus puissant d'utiliser normalement PowerPoint ou LibreOffice. S'il s'agit d'une diapositive Qiita, vous pouvez la publier en tant qu'article tel quel et il est facile à partager. À ce stade, il manque trop de fonctionnalités et l'auto-satisfaction explique en grande partie la raison de son utilisation.

Cependant, il semble que JavaFX puisse être utilisé non seulement pour Java mais aussi pour les langages qui fonctionnent sur JVM, j'espère donc que cet article sera utile pour ceux qui veulent donner une présentation légèrement différente.

Lien

Bibliothèque utilisée

Bibliothèque référencée

Dépôt

Recommended Posts

Créer un outil de diaporama avec JavaFX
Créez un labyrinthe de fouilles avec Ruby2D
Faire un rappel de garbage avec line-bot-sdk-java
Créer une carte de liste avec LazyMap
Faites un jeu de frappe avec ruby
Faisons une carte de Noël avec Processing!
Faites une liste de choses à faire en famille avec Sinatra
Créez quand même une fonction de connexion avec Rails
[docker] [nginx] Créer un ALB simple avec nginx
Création de JavaFX et d'outils avec un package autonome (distribution)
Création d'outils avec JavaFX et packages autonomes (édition JavaFX)
HelloFX avec JavaFX
Création d'un outil d'automatisation de navigateur avec Ruby + Selenium
Faisons une fonction de recherche avec Rails (ransack)
Rendre System.out Mock avec Spock Test Framework
Un simple jeu de ciseaux-papier-pierre avec JavaFX et SceneBuilder
J'ai essayé de faire un jeu simple avec Javafx ① "Trouvons le jeu du bonheur" (inachevé)
Exécutez Scala avec GraalVM et créez-en une image native
Joyeux Noël avec JavaFX !!
J'ai essayé de faire un jeu simple avec Javafx ① "Trouvons le jeu du bonheur" (version inachevée ②)
Rendre les gadgets de calendrier créés avec JavaFX compatibles avec Java SE 9
Faisons un Bot LINE avec Ruby + Sinatra - Partie 2
[Bases de Java] Créons un triangle avec une instruction for
[Mémo de travail de l'application personnelle] Créez un calendrier avec simple_calendar
Rendre JavaFX / TableView modifiable
Créer un utilitaire de réflexion ②
Créer un utilitaire de réflexion ③
Faisons un Bot LINE avec Ruby + Sinatra - Partie 1
Créer un utilitaire de réflexion ①
Créer un contrôleur radio Ev3 avec JavaFx et leJOS [Partie 2]
[Débutant] Essayez de créer un jeu RPG simple avec Java ①
Je veux faire une liste avec kotlin et java!
Je veux créer une fonction avec kotlin et java!
Créez un CRUD simple avec SpringBoot + JPA + Thymeleaf ① ~ Hello World ~
Apprendre Ruby avec AtCoder 13 Comment créer un tableau à deux dimensions
Faisons une API simple avec EC2 + RDS + Spring boot ①
Créer un contrôleur radio Ev3 avec JavaFx et leJOS [Partie 1]
Créez un CRUD simple avec SpringBoot + JPA + Thymeleaf ⑤ ~ Modèle commun ~
Les microservices avec DevOps apportent des modifications
Créez un terrain de jeu avec Xcode 12
[Note] Transition de scène avec JavaFX
[Java] Rendez-le constant
[Rails] Faites une liste de miettes de pain
Faire un diamant en utilisant Java
Une histoire bloquée avec NotSerializableException
Créons une application Web de gestion de livres avec Spring Boot part1
Je veux créer un bouton avec un saut de ligne avec link_to [Note]
Un outil pour générer des images Retina pour iOS à utiliser avec Xcode
Comment créer un fichier jar sans dépendances dans Maven
Créons une application Web de gestion de livres avec Spring Boot part3
Faisons une application multiplateforme avec JRuby (génération de fichier jar)
Créons une application Web de gestion de livres avec Spring Boot part2
Créer un compilateur C à utiliser avec Rust x CLion avec Docker
Je voulais faciliter la programmation JavaFX avec Spring Framework
J'ai essayé de créer une fonction de groupe (babillard) avec Rails