我是Java和JavaFX的新手,所以请原谅我的新手问题。过去几天我搜索了我正在尝试做的事情的例子,但一直未能找到任何答案。 下面是我想要做的:我正在尝试使用场景构建器创建一个简单的javafx GUI客户端套接字应用程序,该构建器将连接到服务器并发送/接收数据。很简单,但是当我尝试在Java FX中实现时,我的GUI冻结。我研究并发现,原因是套接字通信一直占用,并且javafx GUI无法更新。我的研究指出我使用任务。因此,我创建了一个创建任务的简单应用程序,连接到互联网套接字(端口80),发送命令“GET/HTTP/1.1 \ r \ n \ r \ n”,它将请求页面,然后打印出每条线都收到。问题是我想一遍又一遍地(每3秒)做一遍。任务成功运行一次,但随后停止。在下面的代码中,线程进入睡眠状态的行永远不会到达,但打印任何错误的行也不会发送到system.out。javafx,套接字编程和线程
这里是控制器代码
package clientSocketExample;
import java.io.*;
import java.net.*;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.concurrent.Task;
/**
* Controller class of the HelloWorld sample.
*/
public class ClientSocketExampleController implements Initializable
{
@FXML
Button button;
private boolean keepRunning = true;
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rsrcs)
{
if (button != null)
{
button.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent event)
{
keepRunning = false;
System.out.println("Hello World\n");
}
});
}
// Create a background task to handle the Client-Server socket
// This is needed because JavaFX is not thread safe
Task<Integer> task = new Task<Integer>()
{
@Override
protected Integer call() throws Exception
{
Socket s = new Socket();
// String host = "www.google.com";
// String host = "www.amazon.com";
String host = "www.yahoo.com";
PrintWriter s_out = null;
BufferedReader s_in = null;
int lineNums = 0;
try
{
s.connect(new InetSocketAddress(host, 80));
System.out.println("Connected\n");
// Create writer for socket
s_out = new PrintWriter(s.getOutputStream(), true);
// Create reader for socket
s_in = new BufferedReader(new InputStreamReader(s.getInputStream()));
}
catch (IOException e)
{
// Host not found, so print error
System.err.println("Don't know about host : " + host);
System.exit(1);
}
// Loop forever waiting for task to be cancelled
while (isCancelled() == false)
{
// Send message to server
String message = "GET/HTTP/1.1\r\n\r\n";
s_out.println(message);
System.out.println("Message sent\n");
// Get response from server
try
{
String response;
while ((response = s_in.readLine()) != null)
{
System.out.print("Line #: "+lineNums+" ");
System.out.println(response);
lineNums++;
}
} catch (IOException e)
{
System.err.println("Couldn't get response from host");
}
System.out.println("Thread going to sleep\n\n\n");
Thread.sleep(3000);
System.out.println("Thread waking up from sleep\n\n\n");
} // End while
return lineNums;
}
}; // End Initialize
// start the background task
Thread th = new Thread(task);
th.setDaemon(true);
System.out.println("Starting background task...");
th.start();
}
}`
的Main.java类看起来是这样的:
package clientSocketExample;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class Main extends Application
{
/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
Application.launch(Main.class, (java.lang.String[]) null);
}
@Override
public void start(Stage primaryStage)
{
try
{
AnchorPane page = (AnchorPane) FXMLLoader.load(Main.class
.getResource("ClientSocketExample.fxml"));
Scene scene = new Scene(page);
primaryStage.setScene(scene);
primaryStage.setTitle("Hello World Sample");
primaryStage.show();
} catch (Exception ex)
{
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}`
最后的FXML文件看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<AnchorPane id="AnchorPane" prefHeight="365.0" prefWidth="378.0" xmlns:fx="http://javafx.com/fxml" fx:controller="clientSocketExample.ClientSocketExampleController">
<children>
<Button fx:id="button" layoutX="147.0" layoutY="28.0" text="Connect" />
<TitledPane animated="false" layoutY="159.0" prefWidth="378.0" text="Received Data">
<content>
<AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<TextArea fx:id="textAreaField" prefHeight="180.0" prefWidth="374.0" wrapText="true" />
</children>
</AnchorPane>
</content>
</TitledPane>
</children>
</AnchorPane>
在此先感谢您的帮助 韦恩
你的输出是什么样的?换句话说,服务器第一次回应什么? – 2014-03-26 19:30:54