簡體   English   中英

從服務器套接字獲取實時數據並顯示在 javafx

[英]Get Real-time data from server socket and Display it in javafx

您好,我需要從我創建的服務器套接字中獲取一些數據並將其顯示在 javafx 應用程序 fx 應用程序中,即顯示器每 250 毫秒刷新一次數據,服務器每 2 秒發送一次數據

我的代碼/計划主要有 3 個部分
1.服務器每2秒生成數據並發送到端口
2. Clint 代碼從服務器獲取數據並更新其全局變量
3. 每 250 毫秒調度執行器訪問 clint 中的全局變量並更新文本字段
// 遺憾的是這似乎不起作用
我總是啟動服務器然后 clint 然后運行應用程序

所以我寫的代碼如下

服務器代碼

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DecimalFormat;
import java.util.concurrent.TimeUnit;
public class Server {
    public static void main(String[] args) throws IOException, InterruptedException {
        Socket socket;
        try (ServerSocket serverSocket = new ServerSocket(5555)) {
            System.out.println("A");
            socket = serverSocket.accept();
            System.out.println("B");
            if(socket.isConnected())System.out.println("Connected");
            DataOutputStream dout=new DataOutputStream(socket.getOutputStream());
            while (socket.isConnected()) {
                String T=DataStructureMaker();
                dout.writeUTF(T);
                System.out.println(T);
                TimeUnit.SECONDS.sleep(2);
                dout.flush();
            }
        }
        socket.close();
    } 
    public static String DataStructureMaker()
    {
    float RV_Phase=0,RI_Phase=0,RI_Grid=0,RV_Grid=0;String s="";
        DecimalFormat df = new DecimalFormat("#.00");
        s="";
        RV_Phase=Float.parseFloat(df.format((Math.random()*10)));
        s=s+Float.toString(RV_Phase)+"#";
        RI_Phase=Float.parseFloat(df.format((Math.random()*10)));
        s=s+Float.toString(RI_Phase)+"#";
        RI_Grid=Float.parseFloat(df.format((Math.random()*10)));
        s=s+Float.toString(RI_Grid)+"#";
        RV_Grid=Float.parseFloat(df.format((Math.random()*10)));
        s=s+Float.toString(RV_Grid)+"#";
        return s;
    }
}

克林特代碼是

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
public class Clint {
    public static String RV_Grid;
    public static String RI_Grid;
    public static String RI_Phase;
    public static String RV_Phase;
    public static void main(String[] args) throws IOException, InterruptedException {
        Socket s=new Socket("localhost",5555);
        String S;
        DataInputStream dIn=new DataInputStream(s.getInputStream());
        while (s.isConnected()) {            
            S=dIn.readUTF();
            setData(S);
        }
    }
    public static void setData(String S)  // Decryt data and set global values
    {
        char[] A=S.toCharArray();
        int HC=0;
        String R="";
        if(A.length>2)
        for(char x:A)
        {
            if(x=='#')
            {
                switch(HC)
                {
                    case 0:
                        HC++;
                        RV_Phase=R;
                        R="";
                        break;
                    case 1:
                        HC++;
                        RI_Phase=R;
                        R="";
                        break;
                    case 2:
                        HC++;
                        RI_Grid=R;
                        R="";
                        break;
                    case 3:
                        HC++;
                        RV_Grid=R;
                        R="";
                        break;
                }
            }else{
                R=R+x;
            }
        }
    }    
}

最后是我的 fxml controller

import java.util.ResourceBundle;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;
public class FXMLDocumentController implements Initializable {

    @FXML
    private TextField Text1;
    @FXML
    private TextField Text2;
    @FXML
    private TextField Text3;
    @FXML
    private TextField Text4;


    static ScheduledExecutorService scheduledExecutorService;
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO

        scheduledExecutorService =         Executors.newSingleThreadScheduledExecutor();
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            setData();

            }, 0, 250, TimeUnit.MILLISECONDS);
    }    
    public void setData()
    {
        Text1.setText(Clint.RI_Grid);
        Text2.setText(Clint.RI_Phase);
        Text3.setText(Clint.RV_Grid);
        Text4.setText(Clint.RV_Phase);
    }       
}

上面的代碼有我的程序加密、解密發送接收和顯示所需的所有無能數據

以下代碼旨在服務於兩個目的:
一個是為提出的問題展示一個mre
另一個是使用客戶端接收到的數據動態更新 GUI 的解決方案。
該代碼並非旨在展示如何正確實現客戶端和服務器。

MRE有幾點需要注意:
1. 它不應該代表您的特定應用程序,而是您要解決的重點特定問題。
2.應該是M:去掉所有不重要的。 最低限度。
3.應該是R:重現問題。
4. 應該是完整的。獨立於數據庫、文件或其他不可用的資源。
5.它應該易於使用(復制過去)。

為了使用客戶端接收到的數據動態更新 GUI,我使用了共享的 model,它由客戶端更新。
如果使用綁定在 GUI 中反映 model 中的任何更改。

為了簡單和易於使用,我將 controller、model、服務器和客戶端都放在一個文件FXMLDocumentController.java

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.ResourceBundle;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;

public class FXMLDocumentController implements Initializable {

    private static int PORT_NUMBER = 5555;
    @FXML
    private TextField text1;
    @FXML
    Button stopButton, startButton;

    private ScheduledExecutorService scheduledExecutorService;
    private Model model;
    private Client client;
    private Server server;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        startButton.setDisable(false);
        stopButton.setDisable(true);
        scheduledExecutorService = Executors.newScheduledThreadPool(2);
        model = new Model();
        text1.textProperty().bind(model.getTextProperty());
    }

    private void startServer(){

        try {
            server = new Server(PORT_NUMBER);
            server.start();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    private void startClient(){

        try {
            client = new Client(PORT_NUMBER, model);
            client.start();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void start(){

        scheduledExecutorService.submit(() -> startServer());
        scheduledExecutorService.submit(() -> startClient());

        startButton.setDisable(true);
        stopButton.setDisable(false);
    }

    public void stop(){

        client.stop();
        server.stop();

        scheduledExecutorService.shutdown();
        stopButton.setDisable(true);
    }
}

class Model {

    private final ReadOnlyStringWrapper textProperty;

    Model() {
        textProperty = new ReadOnlyStringWrapper();
    }

    synchronized void setText(String s){
        Platform.runLater(()->textProperty.set(s));
    }

    ReadOnlyStringWrapper getTextProperty(){
        return textProperty;
    }
}

class Server {

    private final int portNumber;
    private volatile boolean stop = false;
    private static long REFRESH_TIME = 2;

    Server(int portNumber) {
        this.portNumber = portNumber;
    }

    void start() throws IOException {

        Socket socket;
        try (ServerSocket serverSocket = new ServerSocket(portNumber)) {
            socket = serverSocket.accept();
            DataOutputStream dout=new DataOutputStream(socket.getOutputStream());
            while (socket.isConnected() && ! stop) {
                dout.writeUTF(randomText());
                try {
                    TimeUnit.SECONDS.sleep(REFRESH_TIME);
                } catch (InterruptedException ex) {
                    break;
                }
                dout.flush();
            }
        }
    }

    private String randomText()
    {
        DecimalFormat df = new DecimalFormat("#.00");
        StringBuilder sb = new StringBuilder(df.format(Math.random()*10));
        sb.append("#")
        .append(df.format(Math.random()*10)) ;
        return sb.toString();
    }

    void stop(){
        stop = true;
    }
}

class Client {

    private final int portNumber;
    private final Model model;
    private volatile boolean stop = false;

    Client(int portNumber,  Model model) {
        this.portNumber = portNumber;
        this.model = model;
    }

    void start() throws IOException {
        Socket socket = new Socket("localhost",portNumber);
        DataInputStream dIn=new DataInputStream(socket.getInputStream());
        while (socket.isConnected() && ! stop) {
            model.setText(dIn.readUTF());
        }
        socket.close();
    }

    void stop(){
        stop = true;
    }
}

FXMLDocument.fxml 使用 controller:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.VBox?>

<VBox alignment="CENTER" prefHeight="113.0" prefWidth="232.0" spacing="10" xmlns="http://javafx.com/javafx/10.0.1" 
xmlns:fx="http://javafx.com/fxml/1" fx:controller="fx_tests.FXMLDocumentController">

     <TextField fx:id="text1" alignment="CENTER" promptText="Press START " />
     <GridPane>
         <Button fx:id="startButton" maxWidth="Infinity" onAction="#start" text="START" GridPane.columnIndex="0" />
         <Button fx:id="stopButton" maxWidth="Infinity" onAction="#stop" text="STOP" GridPane.columnIndex="2" />
     </GridPane>
</VBox>

測試它:

import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class FxmlTest extends Application {

    @Override
    public void start(Stage primaryStage) throws IOException {

        Pane root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(null);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM