Faisons une application de communication in-LAN Partie 3 Créer un gestionnaire d'événements JavaFX / Créer une fonction de transmission / réception de message par communication socket

Hier, j'ai créé une fonction de réception Socket à l'aide d'une bibliothèque Java. (Pour l'instant, je cherche juste à voir si la prise sur le port spécifié a reçu les données)

Je souhaite terminer la fonction d'envoi / réception aujourd'hui.

Associer un gestionnaire d'événements à un contrôle JavaFX

Le traitement requis pour lier le gestionnaire d'événements est effectué dans les étapes suivantes.

  1. Créez une classe de contrôleur à lier à FXML.
  2. Associez FXML à la classe de contrôleur.
  3. Associez les événements de contrôle FXML aux méthodes de classe de contrôleur.

Référence: Oracle --JavaFX: Guide de démarrage JavaFX 6 Création d'une interface utilisateur à l'aide de FXML (Japonais)

Créez une classe de contrôleur à lier à FXML.

Cela semble illimité. Il semble que n'importe quelle classe puisse être définie, donc pour le moment Définissons la fenêtre de l'expéditeur sur la classe cible de MainStage.java créée dans Faisons une application de communication dans LAN Partie 2.

Pour être honnête, cette implémentation semble subtile. Le processus d'affichage de l'écran et le processus de définition du fonctionnement de l'écran doivent être séparés.

Associez FXML à la classe de contrôleur.

Contrairement à Form, JavaFX enregistre les informations de mise en page / de contrôle de l'écran sous forme de XML, de sorte qu'il ne peut pas être lié aux opérations en l'état. La solution est simple, il suffit d'écrire une classe qui associe l'action à FXML. Voilà pourquoi.

Il semble qu'il y ait deux façons de le faire, alors décrivez-les.

Comment utiliser SceneBuilder

C'est super facile.

  1. Démarrez SceneBuilder et ouvrez le fichier FXML que vous souhaitez associer.
  2. Cliquez sur l'onglet [Contrôleur] en bas de l'accordéon [Document] en bas à gauche de l'écran pour l'afficher. 03_01_ScrnrBuilder_01.jpg
  3. Entrez la classe à laquelle vous souhaitez vous associer dans la zone de texte [Classe de contrôleur]. (Si vous appuyez sur le bouton [▼], les classes candidates seront affichées.) 03_01_ScrnrBuilder_02.jpg

Comment modifier directement le fichier FXML

C'est également facile.

  1. Ajoutez simplement le paramètre fx: controller indiquant la classe de contrôle au conteneur racine (GridPane cette fois). En particulier fx: controller = "Nom de classe de la classe de contrôle que vous souhaitez associer (y compris le nom du package)"

Plus précisément, cela ressemble à ceci

MainStage.fxml


<GridPane minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="kugui.owd.privateMessenger.stage.MainStage">

Associez les événements de contrôle FXML aux méthodes de classe de contrôleur.

Après avoir lié les classes, liez les différents événements de contrôle et les méthodes de classe de contrôleur. Cela semble avoir les restrictions suivantes sur la méthode.

Cette fois, j'ai préparé une telle méthode.

MainStage.java


	@FXML
	private void btnSend_Click(ActionEvent event) {
		
		System.out.println( "btnSend is clicked!");
		
		return;
	}

Ceci décrit également deux méthodes de réglage.

Comment utiliser SceneBuilder

C'est aussi simple.

  1. Démarrez SceneBuilder et ouvrez le fichier FXML que vous souhaitez associer.

  2. Sélectionnez le contrôleur auquel vous souhaitez associer l'événement (cette fois, bouton [Envoyer]) 03_01_ScrnrBuilder_03.jpg

  3. Cliquez sur l'onglet [Code] de l'accordéon Inspector sur le côté droit de l'écran. 03_01_ScrnrBuilder_04.jpg

  4. Entrez la méthode que vous souhaitez associer dans la zone de texte de l'événement associé (cette fois l'événement OnAction, qui correspond à l'événement Click) (Si vous appuyez sur le bouton [▼], les méthodes candidates seront affichées.)

03_01_ScrnrBuilder_05.jpg

Comment modifier directement le fichier FXML

C'est aussi mince p (ry

  1. Ajoutez << nom d'événement applicable (onAction cette fois) >> = "# << nom de méthode à associer (classe, parenthèses non requises, # obligatoire) >>" au contrôle correspondant.

Plus précisément, cela ressemble à ceci

MainStage.fxml



      <Button mnemonicParsing="false" onAction="#btnSend_Click" text="Send" GridPane.halignment="CENTER" GridPane.rowIndex="2" GridPane.valignment="CENTER" />

Confirmation du résultat de l'implémentation du gestionnaire d'événements

Si vous pouvez le faire jusqu'à présent, vérifiez si vous pouvez le lier.

2018y06m15d_065842800.jpg

Obtenir le contenu de la zone de texte

Après cela, si vous prenez le contenu du message et les informations de la destination et envoyez la prise, la fonction d'envoi est OK. Récupérons donc le contenu de la zone de texte GUI créée par JavaFX.

La procédure est la suivante

  1. Définissez l'id sur le contrôle JavaFx que vous souhaitez toucher.
  2. Déclarez un objet de la classe qui a le même type et le même nom que le contrôle pour lequel l'ID est défini. (Si ce n'est pas public. Ajoutez une annotation @FXML)

Définissez l'id sur le contrôle JavaFx que vous souhaitez toucher.

L'identifiant doit être défini pour assurer la cohérence entre les sources FXML et java.

Il existe deux façons de définir l'identifiant.

Lors de la définition de l'ID depuis SceneBuilder

Shin (ry)

  1. Démarrez SceneBuilder et ouvrez le fichier FXML que vous souhaitez associer.
  2. Sélectionnez le contrôleur auquel vous souhaitez associer l'événement (cette fois le champ de texte SendTo)
  3. Cliquez sur [Inspector Accordion] - [Code Tab]
  4. Entrez id (nom de l'objet) dans la zone de texte fx: id de l'élément [Identity]. 2018y06m15d_092733431.jpg

Presque identique à la partie gestionnaire d'événements ci-dessus, la photo est donc omise.

Lors de la réécriture directe du fichier FXML

  1. Ajoutez la description de l'attribut fx: id au contrôle correspondant et ajoutez la valeur comme nom de variable.

Plus précisément, cela ressemble à ceci

MainStage.fxml


      <TextArea fx:id="txaMessage" prefHeight="200.0" prefWidth="200.0" promptText="Input send message..." GridPane.rowIndex="1" />

Déclarez un objet de la classe qui a le même type et le même nom que le contrôle pour lequel l'ID est défini.

Je viens de le déclarer dans la classe, mais en particulier, il ressemble à ceci.

MainStage.java



Importation ajoutée: import javafx.scene.control.*;

public class MainStage extends Application {
	
	@FXML private TextArea txaMessage;
	@FXML private TextField txfSendTo;

(Omis)

Confirmation du résultat d'acquisition

Utilisez println pour afficher les résultats d'acquisition de TextField: txfSendTo (javafx.control.TextField) pour saisir l'adresse IP de destination et TextArea: txaMessage (javafx.control.TextArea) pour saisir le message.

Modifiez le gestionnaire d'événements lorsque vous appuyez sur le bouton comme ceci

MainStage.java



	@FXML
	private void btnSend_Click(ActionEvent event) {
		
		System.out.println( "btnSend is clicked!");
		System.out.println( String.format("SendTo : %s ", txfSendTo.getText() ));
		System.out.println( String.format("Message : %s ", txaMessage.getText() ));
		
		return;
	}

Le résultat ci-dessous.

2018y06m15d_094621205.jpg

Les informations de l'interface graphique sont maintenant OK.

Allons-y ensuite.

Créer une fonction d'envoi / réception de message par communication socket

Faisons-le de la même manière que l'article précédent. Cette fois, le port d'envoi n'est pas spécifié. Je ne suis pas particulier à ce sujet.

Alors créons rapidement une nouvelle classe d'envoi.

Classe d'envoi implémentée.

Le flux de traitement ressemble à ceci

1.Faites une prise 2. Établissez une connexion TCP avec la destination (dans clientSocket.connect ()) 3. Envoyez un message au port d'envoi via DataOutputStream (cette fois, la chaîne "TestMessage") 4. Fermez le socket.

Définissez targetIP à définir avec la méthode setTargetIP.

TxThread.java



package kugui.owd.privateMessenger;

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

public class TxThread extends Thread {
	
	private String targetIP;
	
	
	public void run() {
		
		int port = 80;
		int timeout = 10000;
		
		Socket clientSocket = new Socket();
		
		try {
			
			clientSocket.connect(new InetSocketAddress(targetIP, port), timeout);
			
			DataOutputStream dos = new DataOutputStream(clientSocket.getOutputStream());
			dos.writeUTF("TestMessage");
			dos.close();
			
		}catch(IOException ie) {
			
			ie.printStackTrace();
			
		}
		
		try {
			
			clientSocket.close();
			
		}catch(IOException ie) {
			
			ie.printStackTrace();
			
		}
		
		return;
	}
	
	public void setTargetIP(String pIP) {
		targetIP = pIP;
		return;
	}
	
}

Il peut être déplacé, mais il peut s'agir d'un détournement de RxThread.java créé dans l'article précédent.

Contrôle de fonctionnement

Voyons si les données sont réellement retardées vers l'adresse IP spécifiée. Dans l'état précédent, je voyais uniquement "Avez-vous accédé au port spécifié?" J'ai ajouté un petit traitement de réception.

Les fonctions suivantes ont été ajoutées.

RxThread.java


package kugui.owd.privateMessenger;

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

public class RxThread extends Thread {

	public void run() {

		int port = 80; //Pour test.
		int timeout = 1000;
		ServerSocket sSocket;

		try {

			sSocket = new ServerSocket(port);
			sSocket.setSoTimeout(timeout);
			
			System.out.println(String.format("start listening port %d", port));

			while (true) {

				try {
					int length = 0;
					
					DataInputStream dis = new DataInputStream(sSocket.accept().getInputStream());
					
					System.out.println(String.format("IP %d port %d : socket accept", sSocket.getInetAddress().toString() ,port));

					
					while(true) {
						
						byte[] buffer = new byte[1024];
						length = dis.read(buffer);
						if( length > 0 ) {
							
							System.out.print(new String(buffer));
							
						}else {
							break;
						}
						
					}
					
					
					dis.close();

				} catch (SocketTimeoutException se) {

					if (interrupted() == true) {

						break;

					} else {

						/* no operation */

					}
				}
			}

		} catch (IOException ioE) {

			ioE.printStackTrace();

		}

		System.out.println("finished");

		return;
	}

}

Si vous vous connectez à localhost à partir du navigateur dans cet état, cela ressemblera à ceci.

03_01_HTTP_REQUEST.jpg

J'ai pu confirmer que le contenu de la requête HTTP était correctement affiché.

Ensuite, entrez localhost dans le champ de texte SendTo et appuyez sur le bouton d'envoi pour obtenir ce résultat. 2018y06m15d_115147834.jpg

Il semble que le message a été reçu.

__ Cependant, il y a un problème en ce que le message est parfois interrompu. __ ~~ Eh bien, si vous ne pouvez pas extraire des informations de la prise de réception dans la situation actuelle, vous pouvez terminer la lecture sans poser de questions. ~~

Donc, après une courte pause, le reste du travail

Je le ferai. Brisons-le une fois. Le temps de travail était cette fois-ci de 05:20:20.

Recommended Posts

Faisons une application de communication in-LAN Partie 3 Créer un gestionnaire d'événements JavaFX / Créer une fonction de transmission / réception de message par communication socket
Faisons une application de communication dans LAN Partie 2 Afficher une fenêtre utilisant JavaFX / Attendre la réception du socket
Faisons une application de communication dans LAN Partie 4 Définir les informations dans le contrôle JavaFX / Appeler l'écran JavaFX à partir du thread
J'ai essayé de créer une fonction de message de l'extension Rails Tutorial (Partie 1): Créer un modèle
J'ai essayé de créer une fonction de message pour l'extension Rails Tutorial (Partie 2): Créer un écran à afficher
Faisons une application de communication en LAN Partie 1 Nouvelle création de projet à l'aide de Maven et du point d'entrée Java
Créons une application TODO en Java 4 Implémentation de la fonction de publication
Créons une application Web de gestion de livres avec Spring Boot part1
Créons une application Web de gestion de livres avec Spring Boot part3
Créons une application TODO en Java 6 Implémentation de la fonction de recherche
Créons une application TODO en Java 8 Implémentation des fonctions d'édition
Créons une application Web de gestion de livres avec Spring Boot part2