- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在创建一个聊天程序,其中包含我在新版本的 JavaFx 场景构建器中创建的 GUI。我有一个扩展应用程序的主要方法,我的 GUI 中有一个 simpleController(控制所有按钮、标签、anchorPanes 等)。
除此之外,我还有一个可以接收和发送消息的服务器应用程序。为此,我创建了以下简单协议(protocol):
命令/描述:
使用这个简单的逻辑,让用户连接、聊天和断开连接对我来说应该相当容易。然而,事实证明,这本应该是一项简单的任务却变成了我最糟糕的噩梦。
到目前为止,我的用户连接到程序没有问题,更多用户可以同时连接。
当我想在服务器和客户端之间发送和接收消息时,事情开始变得棘手。
我不知道如何在使用线程时更新我的 GUI。我试图阅读 Task 类,但我看不出是否应该使用它来代替线程,或者线程是否应该将它作为参数。
我应该创建一个新类来监听输入并使该类扩展线程吗? 或
线程应该在我的 simpleController 类中运行吗?
主要
public class Main extends Application{
public static void main(String[] args) throws IOException{
Application.launch(Main.class, (java.lang.String[]) null);
}
@Override
public void start(Stage primaryStage) throws Exception {
try {
AnchorPane page = (AnchorPane) FXMLLoader.load(Main.class.getResource("testingBackground.fxml"));
Scene scene = new Scene(page);
primaryStage.setScene(scene);
primaryStage.setTitle("Chatten");
primaryStage.show();
} catch (Exception ex) {
java.util.logging.Logger.getLogger(Main.class.getName()).log(
java.util.logging.Level.SEVERE, null, ex);
}
}
}
简单 Controller
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Scanner;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import com.sun.glass.ui.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.text.Text;
/*
* evt ret array listen med commands da jeg selv kan styre hvilke commands der kommer ind og ud! og brugeren faktisk
* aldrig selv kan vælge!
*/
public class SimpleController extends Thread implements Initializable{
public Button btn_Connect;
public AnchorPane pictureFrame;
public Socket socket = new Socket();
public PrintWriter pw;
public Scanner input;
public int clientId = 1;
public Client client = new Client(socket, pw, input, clientId);
// options!
public TextField txt_userName;
public TextField textField_chat;
// send button
public Button Send;
/*
* current client that the user i connected with, this client is used to send commands and tell other clients who is connected on
* what "ingame chat persons"
*/
public static int currentClientId;
// chatperson username
public Label lbl_userName2;
public Label lbl_userName3;
public Label lbl_chatPerson2;
public Label lbl_Chatperson1_userName;
//Pictures of chat person
public Label chatPerson3;
public Label chatPerson1;
// chat persons textfield
public TextArea txt_ChatPerson1;
//public TextField txt_ChatPerson1;
public TextField txt_ChatPerson2;
public TextField txt_ChatPerson3;
@Override
public void initialize(URL location, ResourceBundle resources) throws NullPointerException {
try {
client.connect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
pictureFrame.setMaxSize(409, 373);
txt_ChatPerson1.setMinWidth(50);
txt_ChatPerson1.setPrefWidth(50);
txt_ChatPerson1.setMaxWidth(300);
txt_ChatPerson1.setText(" ");
btn_Connect.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) throws NullPointerException {
connectMeWithOthers(1);
}
});
Send.setOnAction(new EventHandler<ActionEvent>() {
// WORK IN PROGReSS!!
@Override
public void handle(ActionEvent event) {
/*
* new line code:
*/
String x = textField_chat.getText();
txt_ChatPerson1.setText(x);
txt_ChatPerson1.setVisible(true);
System.out.println("x" +x);
txt_ChatPerson1.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(
ObservableValue<? extends String> observable,
String oldValue, String newValue) {
// txt_ChatPerson1.setPrefRowCount(5);
txt_ChatPerson1.setPrefWidth(txt_ChatPerson1.getText().length()*7);
//txt_ChatPerson1.setPrefHeight(txt_ChatPerson1.getText().length()*3);
}
});
txt_ChatPerson1.autosize();
client.SendChat(x);
}
});
}
/**
* this method connect the client to the other clients who are online on the server!
* the method calls it self after the user has established connection in order to load the other chat persons online
* if the client is the online user online then it will only load the user
* @param id
*/
protected void connectMeWithOthers(int id) {
try {
int responseId = client.sendCommando(id);
System.out.println(" response id "+responseId);
// finds whom is connected and tries to connect to a spot that is avalibul!
//Response is the ID of the chat persons
switch (responseId) {
case 1:
currentClientId = client.reciveCommando();
client.setClientId(currentClientId);
client.sendString(txt_userName.getText());
connectMeWithOthers(5);
break;
case 5:
int times = client.reciveCommando();
int o = 0;
System.out.println("times: "+times);
while (o != times) {
int j = client.reciveCommando();
System.out.println("j"+ j);
String name = client.reciveString();
System.out.println("Name " +name);
createUser(j, name);
o++;
}
start();
break;
case 10:
System.out.println("Connection fail chat room is full! Please try again later!");
case 8:
start();
break;
default:
break;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void createUser(int j, String reciveChat) {
if (j == 1) {
chatPerson1.setVisible(true);
lbl_Chatperson1_userName.setVisible(true);
lbl_Chatperson1_userName.setText(reciveChat);
}else if (j == 2) {
lbl_chatPerson2.setVisible(true);
lbl_userName2.setVisible(true);
lbl_userName2.setText(reciveChat);
}else if (j == 3){
chatPerson3.setVisible(true);
lbl_userName3.setVisible(true);
lbl_userName3.setText(reciveChat);
}else {
Image img = new Image(getClass().getResourceAsStream("Figur.png"));
Label test2 = new Label("", new ImageView(img));
test2.setLayoutX(50);
test2.setLayoutY(30);
test2.setPrefSize(1000, 1000);
pictureFrame.getChildren().addAll(test2);
test2.setVisible(true);
}
}
/*
* denne metode er en rewrite af run metoden.
*/
public void StartClient(){
ClientListner cl = new ClientListner(client);
Task task = new Task<String>() {
@Override
protected String call() throws Exception {
// TODO Auto-generated method stub
return null;
}
};
Thread t = new Thread(task);
cl.start();
while (true) {
if (cl.recived) {
}
}
}
/*
* Run metoden er brugt til at recive data fra andre users og update GUI'en skal muligvis rewrites!?
*
*/
public void run(){
System.out.println("Thread started");
System.out.println(client.getSocket().isConnected());
ClientListner cl = new ClientListner(client);
while (client.getSocket().isConnected()) {
int key = 10;
if (cl.recived) {
try {
key = client.reciveCommando();
System.out.println("jeg er her");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Key "+key);
switch (key) {
// case 2 er recive chat:
case 2:
// først find ud af hvilket ID der har sendt chatten:
int y = 0;
try {
y = client.reciveCommando();
System.out.println("y" + y);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// derefter få beskeden og send den så ud til resten.
String says = client.reciveChat().toString();
if (y == 1) {
txt_ChatPerson1.setText(client.reciveChat());
}else if (y == 2) {
}else {
chatPerson3.setVisible(true);
txt_ChatPerson3.setVisible(true);
txt_ChatPerson3.setText(client.reciveChat());
}
break;
default:
break;
}
}
}
}
客户端
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;
public class Client {
// disse var static
public final static int portNumber = 6040;
public Socket socket;
private PrintWriter pw;
private Scanner input;
private int clientId;
/**
* @param args
* @throws IOException
*/
public Client(Socket socket, PrintWriter pw, Scanner input, int clientId){
this.socket = socket;
this.pw = pw;
this.input = input;
this.clientId = clientId;
}
public void connect() throws IOException{
// du kan vælge at bruge inetadressen til at connecte i socketet.
InetAddress adr = InetAddress.getByName("localhost");
socket = new Socket("localhost", portNumber);
input=new Scanner(socket.getInputStream());
pw = new PrintWriter(socket.getOutputStream());
}
/**
* This method sends the message (that the client(chat person) writes to the user)
* @param x
* @throws NullPointerException
* @throws IOException
*/
public void SendChat(String x) throws NullPointerException{
pw.println(2);
pw.flush();
pw.println(SimpleController.currentClientId);
pw.flush();
pw.println(x);
pw.flush();
}
public int sendCommando(int id) throws IOException{
System.out.println("Jeg sender"+ id);
pw.println(id);
pw.flush();
/*
* this part of the program sends a command to the server if the command is 1 then 1 is = Connect.
* the program then ask the server is the server is full or is it ok to connect?
* if the response is not 10 then the program will allow a connection to happen the return type will be the Id of which
* the chat person becomes!
*/
// should the method return 0 the Application will do NOTHING!
switch (id) {
case 1:
int k = reciveCommando();
if (k== 10) {
return 10;
}else if (k < 3) {
System.out.println("returned k" + k);
return k;
}else {
return 10;
}
/*
* Closes the connection with the server!
*/
case 3:
socket.close();
return 0;
case 5:
int y = reciveCommando();
return y;
default:
return 0;
}
}
/*
* this method recives a command from the server! the comands can be found in the ChatCommands.txt
* returns the command as an integer!
*/
public int reciveCommando() throws IOException{
Integer i = input.nextInt();
return i;
}
/**
* Gets a String response from the server. This method i used to create other users and give them the correct username.
*
* @param i
* @return
* @throws IOException
*/
public String getStringResponse(int i) throws IOException {
pw.print(i);
pw.flush();
String x = input.nextLine();
return x;
}
/*
* Work in progress - client getter og setter methoder!
*/
public Socket getSocket(){
return socket;
}
public Scanner getInput(){
return input;
}
public PrintWriter getPw(){
return pw;
}
public int getClientId(){
return clientId;
}
public void setClientId(int i ){
clientId = i;
}
public String reciveChat(){
String x = getInput().next();
return x;
}
public String reciveString(){
String x =input.next();
return x;
}
public void sendString(String x){
pw.println(x);
pw.flush();
}
}*
我真的很抱歉代码有点乱。简单 Controller 中的 run() 方法试图创建一个简单 Controller 的线程。但是,这并没有像我预期的那样工作。 :(
这样做的主要目的基本上是保证聊天室里的两个人可以一起聊天。因此,它所要做的就是更新 1 或 2 个文本区域。
最佳答案
如果您还没有这样做,请检查一下
关于java - 使用线程和/或任务更新 JavaFx Gui,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12860896/
我查看了网站上的一些问题,但还没有完全弄清楚我做错了什么。我有一些这样的代码: var mongoose = require('mongoose'), db = mongoose.connect('m
基本上,根据 this bl.ocks,我试图在开始新序列之前让所有 block 都变为 0。我认为我需要的是以下顺序: 更新为0 退出到0 更新随机数 输入新号码 我尝试通过添加以下代码块来遵循上述
我试图通过使用随机数在循环中设置 JSlider 位置来模拟“赛马”的投注结果。我的问题是,当然,我无法在线程执行时更新 GUI,因此我的 JSlider 似乎没有在竞赛,它们从头到尾都在运行。我尝试
该功能非常简单: 变量:$table是正在更新的表$fields 是表中的字段,$values 从帖子生成并放入 $values 数组中而$where是表的索引字段的id值$indxfldnm 是索引
让我们想象一个环境:有一个数据库客户端和一个数据库服务器。数据库客户端可以是 Java 程序或其他程序等;数据库服务器可以是mysql、oracle等。 需求是在数据库服务器上的一个表中插入大量记录。
在我当前的应用程序中,我正在制作一个菜单结构,它可以递归地创建自己的子菜单。然而,由于这个原因,我发现很难也允许某种重新排序方法。大多数应用程序可能只是通过“排序”列进行排序,但是在这种情况下,尽管这
Provisioning Profile 有 key , key 链依赖于它。我想知道 key 什么时候会改变。 Key will change after renew Provisioning Pr
截至目前,我在\server\publications.js 中有我的 MongoDB“选择”,例如: Meteor.publish("jobLocations", function () { r
我读到 UI 应该始终在主线程上更新。但是,当谈到实现这些更新的首选方法时,我有点困惑。 我有各种函数可以执行一些条件检查,然后使用结果来确定如何更新 UI。我的问题是整个函数应该在主线程上运行吗?应
我在代理后面,我无法构建 Docker 镜像。 我试过 FROM ubuntu , FROM centos和 FROM alpine ,但是 apt-get update/yum update/apk
我构建了一个 Java 应用程序,它向外部授权客户端公开网络服务。 Web 服务使用带有证书身份验证的 WS-security。基本上我们充当自定义证书颁发机构 - 我们在我们的服务器上维护一个 ja
因此,我有时会在上传新版本时使用 app_offline.htm 使应用程序离线。 但是,当我上传较大的 dll 时,我收到黄色错误屏幕,指出无法加载 dll。 这似乎与我对 app_offline.
我刚刚下载了 VS Apache Cordova Tools Update 5,但遇到了 Node 和 NPM 的问题。我使用默认的空白 cordova 项目进行测试。 版本 如果我在 VS 项目中对
所以我有一个使用传单库实例化的 map 对象。 map 实例在单独的模板中创建并以这种方式路由:- var app = angular.module('myApp', ['ui', 'ngResour
我使用较早的 Java 6 u 3 获得的帧速率是新版本的两倍。很奇怪。谁能解释一下? 在 Core 2 Duo 1.83ghz 上,集成视频(仅使用一个内核)- 1500(较旧的 java)与 70
我正在使用 angular 1.2 ng-repeat 创建的 div 也包含 ng-click 点击时 ng-click 更新 $scope $scope 中的变化反射(reflect)在使用 $a
这些方法有什么区别 public final void moveCamera(CameraUpdate更新)和public final void animateCamera (CameraUpdate
我尝试了另一篇文章中某人评论中关于如何将树更改为列表的建议。但是,我在某处(或某物)有未声明的变量,所以我列表中的值是 [_G667, _G673, _G679],而不是 [5, 2, 6],这是正确
实现以下场景的最佳方法是什么? 我需要从java应用程序调用/查询包含数百万条记录的数据库表。然后,对于表中的每条记录,我的应用程序应该调用第三方 API 并获取状态字段作为响应。然后我的应用程序应该
只是在编写一些与 java 图形相关的代码,这是我今天的讲座中的非常简单的示例。不管怎样,互联网似乎说更新不会被系统触发器调用,例如调整框架大小等。在这个例子中,更新是由这样的触发器调用的(因此当我只
我是一名优秀的程序员,十分优秀!