Faisons une application de communication dans LAN Partie 2 Afficher une fenêtre utilisant JavaFX / Attendre la réception du socket

En essayant d'améliorer le rythme de vie mais en ne tuant pas un jour, le temps de travail est également réduit.

D'ailleurs, cette fois, nous allons créer la partie UI en utilisant JavaFX. Alors faisons la partie veille pour la communication. ** Je n'ai pas le temps! (Plus ça change, plus c'est la même chose)**

Créez une interface utilisateur à l'aide de JavaFX.

Qu'est-ce que JavaFX?

En un mot, c'est une "bibliothèque de dessins GUI pour Java".

La caractéristique est que la conception est décrite en XML et CSS. De plus, c'est très simple car vous pouvez utiliser une application appelée SceneBuilder qui peut être conçue par glisser-déposer gratuitement. D'une manière ou d'une autre, il peut être utilisé sur la plate-forme RIA.

Pour l'historique et l'histoire, voir Voir ce wiki.

Faire l'écran principal

Créons la fenêtre principale en utilisant le générateur de scène ci-dessus.

Tout en respectant M. IP Messanger, cela ressemble à ceci

2018y06m13d_193810674.jpg

Lors de la sortie, un fichier au format FXML est généré. Cette fois, nous l'avons nommé Main Stage car c'est l'écran principal (Stage). Créons un répertoire de stockage et mettons-le dans la source.

2018y06m13d_215409682.jpg

Dans l'image ci-dessus, MainStage.java est également stocké, mais il s'agit d'un fichier créé séparément. Contrairement au formulaire C #, FXML est un fichier qui enregistre la structure (et les informations du gestionnaire d'événements), donc Il est nécessaire de créer la source java pour le traitement séparément.

Il semble préférable de penser que cette zone est divisée comme un modèle MVC.

Il peut être préférable de diviser les fichiers par contrôle et affichage ...

Je veux l'appeler pour le moment.

Je veux appeler le FXML créé pour le moment.

J'ai recherché diverses choses, mais je ne trouve qu'un modèle pour le projet JavaFX. Plus précisément, il décrit uniquement comment appeler l'écran tel qu'il est à partir de la méthode _main ().

Cette fois, je veux l'appeler à partir d'une autre méthode Main, j'ai donc vérifié diverses choses. Les pages ici ont été utiles

En gros, Application est la gestion principale de Stage (peut être traitée de la même manière que window). La scène dessine une scène. La scène est composée de divers nœuds stockés dans Parent. C'est comme ça?

La procédure spécifique est comme ça.

  1. Préparez une classe qui hérite de javafx.application.Application.
  2. Alimentez la méthode d'héritage Application préparée dans la méthode javafx.application.Application.launch.

Faisons-le concrètement.

1. Préparez une classe qui hérite de javafx.application.Application.

C'est facile.

MainStage.java



package kugui.owd.privateMessenger.stage;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class MainStage extends Application {
	
	@Override
	public void start(Stage stage) throws Exception{
		
		Parent root = FXMLLoader.load(getClass().getResource(
				getClass().getSimpleName() + ".fxml" )
				);
		
		Scene scene = new Scene(root);
		stage.setScene(scene);
		
		stage.show();
		
		return;
	}
	
	
}

La première chose à surveiller est de remplacer la méthode start (). Il semble que la méthode d'héritage Application passée à Application.launch () soit exécutée selon son propre cycle de vie.

Cela ressemble à ceci dans une écriture simple

Lors de l'appel
public void init()
public void start()
À la fin
public void stop()

Bien que init () ait été implémenté à l'origine, start () est déclaré comme une classe abstraite, donc il ne passera pas la construction à moins qu'il ne soit surchargé. Fondamentalement, le processus d'initialisation doit être effectué au moment de start ().

Le flux de traitement du code ci-dessus est le suivant.

  1. Générez une instance Parent (parent) à l'aide de la méthode FXMKLoader.load () basée sur le fichier fxml.
  2. Créé sur la base de l'occurrence Parent qui a créé l'occurrence Scene (scène).
  3. Envoyez l'occurrence de scène (scène) créée au paramètre de type de scène (étape) transmis par l'application.
  4. Utilisez la méthode stage.show () pour dessiner.

Il existe de nombreux exemples qui décrivent le traitement dans la même classe ici, donc il ne peut pas trébucher autant.

2. Alimentez la méthode d'héritage Application préparée dans la méthode javafx.application.Application.launch.

Puisque la classe héritée d'Application a été préparée pour le moment, définissez l'appelant suivant.

J'ai ajouté un peu à ppa.java qui l'a laissé dans l'article précédent.

ppa.java


public class Ppa
{
	public static void main( String[] args) {
		System.out.println( "Good night World");
		
		Application.launch(MainStage.class, args);

		return;
	}
}

Application.launcher () semble avoir les restrictions suivantes.

Ensuite, vous devez réfléchir un peu à la façon de le mettre en œuvre.

Au fait, ce launch () est une méthode synchrone. Si vous écrivez un processus après cela, il sera exécuté après la fermeture de la fenêtre.

Quand j'arriverai ici, je vais l'afficher pour le moment.

2018y06m13d_234251791.jpg

Ouaip. Il ne semble y avoir aucun problème jusqu'à présent.

Créez un thread de veille.

Pour être honnête, je n'ai jamais construit de programme multi-thread. Au moins, je ne l'ai jamais vu comme un appareil embarqué. Parce qu'il est normal d'intégrer plusieurs processus, et qu'il y a plus de personnes qui traitent les informations avec IRQ qu'avec IPC. Oh, je ne l'ai pas vu dans le cadre.

J'ai l'impression que vous utilisez Morimori pour les jeux. C'est un gros problème, alors habituons-nous ici.

Il est naturel que les choses qui n'ont pas été faites s'améliorent. Mais si vous le faites, il n'y a rien. Le monde est fait de telles choses.

Préparer une classe à exécuter en tant que thread

Comment le faire fonctionner comme un fil?

L'utilisation des threads est approximativement résumée comme suit.

  1. Créez une classe qui prend en charge les threads.
  2. Implémentez le processus d'appel du thread.

C'est simple. Faisons-le.

1. Créez une classe qui prend en charge les threads.

Il existe deux façons de créer une "classe threadée" en Java.

Quelle est la différence? Il semble que l'opération soit la même. En raison de la spécification du langage Java qui n'autorise pas l'héritage multiple, utilisez l'interface Runnable lorsque vous souhaitez hériter d'autres classes et créer des threads! Il paraît que.

Maintenant, créez une nouvelle classe de thread de secours RxThread en héritant de la classe Java.lang.Thread. À propos, la classe Thread peut être utilisée sans importation.

RxThread.java


package kugui.owd.privateMessenger;


public class RxThread extends Thread{
	
	public void run() {
		
		int countPray = 0;
		
		try {
			while(true) {
				
				System.out.println(String.format("%2d : please let me see the good dream...", countPray));
				Thread.sleep(1000);
				
				countPray++;
			}
		}catch(InterruptedException ie ) {
			
			/* no operation */
			
		}catch(Exception ex) {
			
			ex.printStackTrace();
			
		}
		
		return;
	}
	
}

Avec traitement en boucle pour vérifier l'opération.

Il semble que Thread a aussi quelque chose comme un cycle de vie ... et la méthode void run () est appelée lorsque le thread est exécuté. Alors, implémentez la méthode run () et décrivez le processus. J'ai cherché une description qui appellerait d'autres méthodes, mais je n'ai pas pu la trouver, il semble donc nécessaire d'écrire pour appeler à partir de run () de l'initialisation au traitement de fin.

2. Implémentez le processus d'appel du thread.

Ajoutez le traitement suivant à la méthode main () de ppa.java

  1. Créez une instance de la classe threadée que vous avez créée.
  2. Générez en alimentant la classe thread qui a généré la classe Thread.
  3. Appelez la méthode thread.start () pour démarrer le thread.
  4. Envoyez une file d'attente d'interruption au thread (après avoir effacé la fenêtre d'envoi).

ppa.java


	public static void main( String[] args) {
		
		RxThread rxThread = new RxThread();
		Thread thread = new Thread(rxThread);
		
		System.out.println( "Good night World");
		
		thread.start();
		Application.launch(MainStage.class, args);
		thread.interrupt();
		
		System.out.println( "r u still awake?");
		
		return;
                }

Quand je vérifie l'opération, ça ressemble à ça.

2018y06m14d_012812748.jpg

_ ↓ fenêtre Il ressemble à ceci lorsqu'il est fermé _

2018y06m14d_012833983.jpg

Je vais ajouter un peu ci-dessous sur ce que je suis resté bloqué dans le filetage jusqu'à présent.

Que se passe-t-il si le thread principal se termine alors que le thread exécute une boucle infinie?

Pour être honnête, j'ai pensé: "Si le thread parent disparaît, le thread enfant disparaîtra également." Oui, "L'enfant vit même si le parent meurt", ça se sent un peu fort à l'écrit.

Quand j'essaye de le déplacer, ça ressemble à ça.

2018y06m14d_013214000.jpg

Si vous y réfléchissez bien, c'est comme "les parents sont morts et les enfants sont des zombies", donc c'est normal d'être complètement noir. Par conséquent, il est nécessaire de s'assurer que le processus enfant est terminé avant que le processus parent soit terminé.

C'est pourquoi je l'ai recherché. Comment terminer un thread. Ensuite, j'ai trouvé qu'une méthode appelée Thread.stop () était implémentée.

Quand j'écris ceci, Eclipse est malade cette fois.

Même la ligne d'annulation est sortie comme thread. ~~ stop ~~ (). Pourquoi? Si vous pensez que cette méthode, méthode obsolète. Détails: Oracle --Documentation Class Thread (Japanese) --Voir la section stop ()

Pour annuler l'attente, utilisez la méthode Thread.interrupt () et laissez le thread terminer le thread lui-même. En passant, suspend () qui suspend l'opération Thread et resume () qui la reprend sont également obsolètes. La raison en est "il est facile de provoquer un blocage mortel!" Fondamentalement, il semble que l'interférence avec d'autres threads soit limitée à la file d'attente d'interruption utilisant thread.interrupt ().

Eh bien, si vous rendez le système de contrôle disjoint, vous pourrez vous étrangler plus tard.

Dois-je créer une instance de Thread pour hériter de Thread?

J'ai essayé ceci et cela fonctionne très bien. Si c'est une classe de modèle qui implémente l'interface Runnable, vous devrez le faire ici. (méthode start () ou)

Créer un processus de veille

Puisque ce temps est la communication Socket, la communication utilisant webSocket.

Hmmm, comment expliquez-vous la communication Socket de manière facile à comprendre? Puisqu'il existe une zone de stockage de données qui est également utilisée comme port utilisé pour envoyer et recevoir des données, Une image de spécification du port à utiliser pendant la veille et de sa surveillance.

Quand je l'ai recherché, il semble que la communication par socket Java soit très facile à faire.

Pratiquez immédiatement.

Supprimez le processus de RxThread.run () qui a été malaxé ci-dessus une fois et changez-le en processus de veille

RxThrea.java


package kugui.owd.privateMessenger;

import java.io.IOException;
import java.net.*;

public class RxThread extends Thread{
	
	public void run() {
		
		int port = 80; //Pour test.
		ServerSocket sSocket;
		
		try {
			
			sSocket = new ServerSocket(port);
			sSocket.accept();
			
			System.out.println( String.format("port %d : socket accept", port));
			
		}catch(IOException ioE) {
			
			ioE.printStackTrace();
			
		}
		
		if( sSocket != null ){
			sSocket.Close();
		}

		System.out.println( "finished");
		
		return;
	}
}

Commencez immédiatement après l'assemblage. 2018y06m14d_025627764.jpg

Accédez à localhost avec un navigateur pour envoyer des données au port 80.

Qu'est-ce que localhost? Le nom que vous utilisez pour accéder à vous-même. Plus précisément, le nom de domaine pour accéder à l'adresse IP de 127.0.0.1.
Pourquoi un navigateur? Le nombre de ports est fini (65536), et le port fréquemment utilisé est connu comme un port bien connu. Puisque "le port 80 est un port accessible par HTTP", vous pouvez envoyer une demande d'acquisition d'informations au port 80 simplement en spécifiant localhost dans le navigateur. Si vous souhaitez accéder à d'autres ports avec un navigateur, indiquez: << numéro de port >> après l'adresse / le nom de domaine. C'est généralement repoussé.

Le résultat est le suivant. 2018y06m14d_030827575.jpg


J'ai pu rester sans aucun problème, alors c'est tout pour aujourd'hui. L'opération d'aujourd'hui est ... J'ai été confus en redémarrant Windows en cours de route, mais en supposant environ 2 heures ... 06:45:53.

Recommended Posts