java从服务器socket获取实时数据并在javafx中显示
您好,我需要从我创建的服务器socket中获取一些数据,并将其显示在javafx应用程序中 fx应用程序ie显示屏每250ms刷新一次数据,服务器每2秒发送一次数据
我的代码/计划主要有三部分
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控制器
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);
}
}
上面的代码包含了我的程序加密、解密、发送、接收和显示所需的所有重要数据
# 1 楼答案
以下代码旨在实现两个目的:
一个是为所问的问题演示一个mre
另一个是使用客户端接收的数据动态更新GUI的解决方案
这段代码的目的不是展示如何正确实现客户机和服务器
关于MRE,有几点需要注意:
1.它不应该代表你的具体应用,而应该代表你关注的具体问题 我们正在努力解决这个问题
2.应该是M:去掉所有不必要的东西。最低限度
3.应该是R:重现问题
4.应该是完整的。独立于数据库、文件或其他不可用资源
5.它应该易于使用(复制过去)
为了用客户机接收到的数据动态更新GUI,我使用了一个共享模型,该模型由客户机更新
通过使用绑定在GUI中反映的模型ifs中的任何更改
为了简单易用,我把控制器、模型、服务器和客户机都放在一个文件中
FXMLDocumentController.java
:该控制器由FXMLDocument使用。fxml:
用以下方法进行测试: