繁体   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