Hello I need to get Some data from a server socket i created and display it in a javafx application
fx application ie the display refresh the data every 250ms, and server sends data every 2 seconds
My code/plan have mainly 3 Parts
1. The server generates the data and sends it to the port every 2 sec
2. The Clint code gets the data from the server and updates its global variables
3. Every 250ms Schedule executioner reach out to the global varibles in clint and update the text fields
// Sadly this doesn't seems to work
i always starts server then clint then runs the application
so the Codes i written are as follows
Server Code
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;
}
}
The clint code is
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;
}
}
}
}
and Finally my 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);
}
}
The Above code have All impotent data needed for my program Encryption, Decryption Send Receive and Display
The code following is aimed to serve two purposes:
The one is to demonstrate an mre for the question asked.
The other being a solution for dynamic update the GUI with data received by the client.
The code is not aimed to show how to correctly implement the client and server.
There are a few things to note about MRE:
1. It should not represent your specific application but a focused specific problem you
are trying to solve.
2. It should be M: remove all what is not essential. Bare minimum.
3. It should be R: reproduce the problem.
4. It should be complete.Independent on data-base, files or other unavailable resources.
5. It should be easy to use (copy-past).
To dynamically update the GUI with data received by the client, I used a shared model, that it is updated by the client.
Any change in the model ifs reflected in the GUI by using binding.
For simplicity and ease of use I have the controller, the model, the server and the client all in one file 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;
}
}
The controller is used by FXMLDocument.fxml:
<?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>
Test it with :
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);
}
}
Related
So I've got a method called 'popup' in a javaFX controller class which opens a small popup window on top of the actual application window. This method runs without problem if it's assigned to a button in fxml and the button is clicked, but this is not the way I want to use it.
I've got an other class called 'Timer' with a new task (new thread) which is counting down from a certain number, and at a point it will open a popup window with a message. My purpose is to call and run the 'popup' method from this 'Timer' class. When I call the 'popup' method from here, it starts executing, but the popup window doesn't appear at all. (The method call happens as I get the message "in popup" on console from 'popup' method. )
So why does it work when a button click calls 'popup' method from the fxml file and why not when I call it from an other class? Thanks.
Please see the controller class with 'popup' method and the Timer class below (using Gradle in project):
"SceneController" controller class:
package GradleFX;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
//import java.awt.event.ActionEvent;
public class SceneController implements Initializable {
public static String password = "";
protected static int timercount = 20;
#FXML
private Label PWLabel;
#FXML
private Label bottomLabel;
#FXML
private PasswordField PWField;
#FXML
private Label showPWLabel;
protected static Label myBottomLabel;
private static PasswordField myPWField;
private static Label myShowPWLabel;
private static int tries;
#Override
public void initialize(URL location, ResourceBundle resources) {
Timer timerTask = new Timer();
myBottomLabel = bottomLabel;
myPWField = PWField;
myShowPWLabel = showPWLabel;
new Thread(timerTask).start();
}
**/***********************************************************************
/*This method runs if button is pressed in main application,
but can't make it work by calling it from Timer Class */
public void popup() {
System.out.println("in popup");
Stage dialogStage = new Stage();
dialogStage.initModality(Modality.WINDOW_MODAL);
VBox vbox = new VBox(new Text("Hi"), new Button("Ok."));
vbox.setAlignment(Pos.CENTER);
vbox.setPadding(new Insets(15));
dialogStage.setScene(new Scene(vbox));
dialogStage.show();
}
//****************************************************************************
public void showPW() {
myShowPWLabel.setText(myPWField.getText());
}
public void hidePW() {
myShowPWLabel.setText("");
}
public void exit() {
System.exit(0);
}
public void write() {
PWLabel.setText("Mukodik");
}
public void writeInput(String in) {
password = in;
System.out.println("final password text text: " + password);
writeFinally();
}
public void writeFinally() {
System.out.println("This is 'password' : " + password);
//bottomLabel.setText(password);
}
public void bottomLabelWrite() {
bottomLabel.setText(myPWField.getText());
}
public static void setLabel() throws InterruptedException {
myBottomLabel.setText("");
myBottomLabel.setText("Database has been permanently erased.");
//Thread.sleep(3000);
//System.exit(0);
}
public static void noKeyEnteredNote() {
myBottomLabel.setTextFill(Color.BLACK);
myBottomLabel.setText("No key entered. Type Main Key.");
}
public static void rightKey() {
myBottomLabel.setText("Yes, this is the right key.");
}
public static void wrongKey() throws InterruptedException {
tries = MasterKey.numOfTryLeft;
if (tries > 0) {
myBottomLabel.setTextFill(Color.RED);
myBottomLabel.setText("!!!Wrong key!!! You've got " + tries + " tries left!");
}
}
public void simpleTest(String in) {
System.out.println("in simpleTest and in is: " + in);
}
public void getMainKey() throws IOException, InterruptedException {
MasterKey masterKey = new MasterKey();
System.out.println("Inside SceneController");
masterKey.requestKey(myPWField.getText());
}
public void changeScreen(ActionEvent event) throws IOException, InterruptedException {
getMainKey();
if (MasterKey.isRightKey) {
Parent tableViewParent = FXMLLoader.load(getClass().getResource("Menu.fxml"));
Scene tableViewScene = new Scene(tableViewParent);
Stage window = (Stage) ((Node) event.getSource()).getScene().getWindow();
window.setScene(tableViewScene);
window.show();
}
}
}
This is Timer class:
package GradleFX;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
public class Timer extends Task {
private ActionEvent actionEvent;
#Override
protected Integer call() throws Exception {
boolean notCalled = true;
while (SceneController.timercount > 0) {
SceneController sceneController = new SceneController();
System.out.println(SceneController.timercount);
Thread.sleep(1000);
SceneController.timercount--;
if (SceneController.timercount < 19) {
System.out.println("Less than 5");
if(notCalled) {
sceneController.popup();
notCalled = false;
}
}
}
System.exit(0);
return null;
}
}
Add this to your code:
#Override
public void initialize(URL location, ResourceBundle resources) {
Timer timerTask = new Timer();
myBottomLabel = bottomLabel;
myPWField = PWField;
myShowPWLabel = showPWLabel;
new Thread(timerTask).start();
timerTask.setOnFinished(e->{
popup();
});
}
I want to constantly display the current mileage of the car without clicking on any button, etc.
Thread class
package threads;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import static controller.GameWindowController.*;
public class MileageThread implements Runnable {
#FXML
Label mileageLabel;
#Override
public void run() {
{
double time = 1;
while (true) {
try {
Thread.sleep(1000);
} catch (NullPointerException | InterruptedException e) {
e.printStackTrace();
}
getCar().setDistancePerSec((time * getCar().getCurrentCarSpeed()) / 3600);
getCar().setCarMileage(getCar().getCarMileage() + getCar().getDistancePerSec());
System.out.format("dziala %.3f km przebiegu %n", getCar().getCarMileage());
mileageLabel.setText(String.valueOf(getCar().getCarMileage()));
}
}
}
}
With this record I receive:
Exception in thread "Thread-5" java.lang.NullPointerException
at threads.MileageThread.run(MileageThread.java:27)
and here is the class in which I make the thread:
package controller;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.image.ImageView;
import model.VehicleStatus;
import threads.MileageThread;
import vehicles.Car;
import java.net.URL;
import java.util.ResourceBundle;
public class GameWindowController extends Thread implements Initializable, Runnable {
#FXML
ImageView smoke;
#FXML
private Label speedLabel, mileageLabel;
static Car car;
static {
car = new Car() {
};
}
public void accelerationButtonPushed(ActionEvent event) throws InterruptedException {
car.accelerate();
speedLabel.setText(String.valueOf(car.getCurrentCarSpeed()));
smoke.setFitHeight(smoke.getX() + car.getCurrentCarSpeed());
smoke.setFitWidth(smoke.getY() + car.getCurrentCarSpeed());
System.out.println(car.getCurrentCarSpeed());
System.out.println(car.getCarMileage());
System.out.println(car.getFuel());
System.out.println(car.getStatus());
}
public void stopCarButtonPushed(ActionEvent event) throws InterruptedException {
if (car.getCurrentCarSpeed() == 0) {
System.out.println("Silnik zgasl!");
}
car.stop();
speedLabel.setText(String.valueOf(car.getCurrentCarSpeed()));
smoke.setFitHeight(smoke.getX() + car.getCurrentCarSpeed());
smoke.setFitWidth(smoke.getY() + car.getCurrentCarSpeed());
System.out.println(car.getCurrentCarSpeed());
System.out.println(car.getCarMileage());
System.out.println(car.getFuel());
System.out.println(car.getStatus());
}
public void startButtonPushed(ActionEvent event) throws InterruptedException {
if (car.getStatus() != VehicleStatus.MOVING) {
car.start();
} else System.out.println("Samochod juz jest na chodzie!");
System.out.println("Status pojazdu: " + car.getStatus());
}
#FXML
public void initialize(URL location, ResourceBundle resources) {
smoke.setFitHeight(1);
smoke.setFitWidth(1);
MileageThread mileageThread = new MileageThread();
Thread mt = new Thread(mileageThread);
mt.start();
}
public static Car getCar() {
return car;
}
}
I apologize if you find here some basic mistakes or if I misunderstood you.
I'm using a scene builder and I just want to put the text in one of the labels using MileageThread.
If you want to modify the user interface from a thread other than the JavaFX Application thread you must wrap it in a call to Platform.runLater()
Platform.runLater(() -> {
userInterfaceControl.setText("New Text");
});
JavaFX nodes/controls/etc. can only be modified from the JavaFX Application thread.
The solution that worked for me:
#FXML
public void initialize(URL location, ResourceBundle resources) {
PauseTransition wait = new PauseTransition(Duration.seconds(1));
wait.setOnFinished((e) -> {
mileageLabel.setText(String.valueOf(getCar().getCarMileage()));
wait.playFromStart();
});
wait.play();
}
I hope that someone will help :)
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I used to work on Swing but now saw that it's pretty obsolete and JX8 is the future for Java applications so I started from YouTube tutorials on FXML GUI from ScreenBuilder. And integrated my RDT 3.0 TCP Server-Client code into FXML GUI.
But I have a lot of errors; I tried solving most of them but every time I get nullPointerException and I know it's because memory is not allocated. How can I get rid of them, and how to get my application running?
Here is the code:
ClientFXMLController.java:
package rdt_app;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import static java.lang.Thread.sleep;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.*;
/**
* FXML Controller class
*
* #author Dell
*/
public class ClientFXMLController implements Initializable {
ToggleGroup group = new ToggleGroup();
#FXML
RadioButton case1;
#FXML
RadioButton case2;
#FXML
RadioButton case3;
#FXML
RadioButton case4;
#FXML
RadioButton case5;
boolean buttonPressed=false;
String str=null;
#FXML
TextArea msg_rcv;
#FXML
Button send_button;
Socket s;
DataInputStream in;
// DataInputStream inn;
PrintStream ps;
String pre = "";
#FXML
private void handleButtonAction(ActionEvent event) {
// buttonPressed=true;
if(s!=null){
if(case1.isSelected())
str= "1";
else if(case2.isSelected())
str= "2";
else if(case3.isSelected())
str= "3";
else if(case4.isSelected())
str= "4";
else if(case5.isSelected())
str= "5";
}
else{
// Alert alert = new Alert(Alert.AlertType.ERROR); //AlertType.WARNING
// alert.setTitle("Error!");
// alert.setHeaderText("Message Cannot be send at this moment!");
// alert.setContentText("Please wait for response from Client or timeout and then proceed");
//
// alert.showAndWait();
}
}
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
try {
sleep(200);
} catch (InterruptedException ex) {
Logger.getLogger(ClientFXMLController.class.getName()).log(Level.SEVERE, null, ex);
}
try {
// TODO
case1.setToggleGroup(group);
case1.setSelected(true);
case2.setToggleGroup(group);
case3.setToggleGroup(group);
case4.setToggleGroup(group);
case5.setToggleGroup(group);
msg_rcv.appendText("Key:\n1:Operation with no Loss\n2:Lost Packet\n3:Lost ACK\n4:Premature Timeout\nNull:No Response\n");
s = new Socket("localHost",8100);
in = new DataInputStream(s.getInputStream());
// inn = new DataInputStream(System.in);
ps = new PrintStream(s.getOutputStream());
pre = "";
while (true)
{
str = in.readLine();
if (!str.equalsIgnoreCase("fin") && str!=null)
{
msg_rcv.appendText("Sender just sended a Message: "+str+"\n");
if (pre.equalsIgnoreCase("3") || pre.equalsIgnoreCase("null"))
{
msg_rcv.appendText("Duplicate Detected!\n");
}
msg_rcv.appendText("Enter a Response: \n");
if(str.equalsIgnoreCase("1") || str.equalsIgnoreCase("2") || str.equalsIgnoreCase("3") || str.equalsIgnoreCase("4") ||
str.equalsIgnoreCase("5")){
pre=str;
ps.println(str);
// buttonPressed=false;
}
// str = inn.readLine();
}
else if(str==null){
// do nothing carry on with loop
}
else
{
s.close();
break;
}
}
} catch (IOException ex) {
Logger.getLogger(ClientFXMLController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
FXMLDocumentController (Server):
package rdt_app;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.*;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import static java.lang.Thread.sleep;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
/**
*
* #author Dell
*/
public class FXMLDocumentController implements Initializable {
#FXML
private Label info_label;
#FXML
private Label waitingLabel;
#FXML
private Button send_button;
#FXML
private TextField msg_send;
#FXML
private TextArea msg_rcv;
#FXML
private ProgressBar pbar;
String str =null;
ServerSocket ss;
int correct = 0;
Socket s;
DataInputStream in;
DataInputStream inn;
PrintStream ps;
#FXML
private AnchorPane rootPane;
#FXML
private void handleButtonAction(ActionEvent event) {
if(ss!=null && msg_send.getText()!=null){
if(correct==0)
str= msg_send.getText();
else{
Alert alert = new Alert(AlertType.ERROR); //AlertType.WARNING
alert.setTitle("Error!");
alert.setHeaderText("Message Cannot be send at this moment!");
alert.setContentText("Please wait for response from Client or timeout and then proceed");
alert.showAndWait();
}
}
}
#Override
public void initialize(URL url, ResourceBundle rb) {
try {
// TODO
// AnchorPane pane = FXMLLoader.load(getClass().getResource("clientFXML.fxml"));
// rootPane.getChildren().setAll(pane);
pbar.setProgress(0.0);
send_button.setVisible(false);
info_label.setVisible(false);
msg_send.setVisible(false);
msg_rcv.setVisible(false);
for(int i=0;i<100;i++){
pbar.setProgress(i/100.0);
sleep(20);
}
pbar.setProgress(0.0);
send_button.setVisible(true);
info_label.setVisible(true);
msg_send.setVisible(true);
msg_rcv.setVisible(true);
pbar.setVisible(false);
waitingLabel.setVisible(false);
ss=new ServerSocket(8100);
s=ss.accept();
int ack = 0;
in = new DataInputStream(System.in);
inn = new DataInputStream(s.getInputStream());
ps = new PrintStream(s.getOutputStream());
while (true)
{
// if (correct==0)
// {
// System.out.println("Enter a Message: ");
// str = in.readLine();
// }
if (str.equalsIgnoreCase("fin"))
{
ss.close();
break;
}
if(correct ==0 && str!=null){
ack = ack % 2;
ps.println(str);
str=null;
}
String str2 = inn.readLine();
int reply=0;
if (str2.equalsIgnoreCase("1") || str2.equalsIgnoreCase("2") || str2.equalsIgnoreCase("3") || str2.equalsIgnoreCase("4"))
{
reply = Integer.parseInt(str2);
}
if (!str2.equalsIgnoreCase("fin"))
{
if (reply==1) //operation with no loss
{
// System.out.println("Sender received a valid ACK for "+ack+" , send next message!");
msg_rcv.appendText("Sender received a valid ACK for "+ack+" , send next message!\n");
ack++;
correct=0;
}
if (reply==2) //Lost Packet
{
// System.out.println("Sender didn't recieve a ACK!");
msg_rcv.appendText("Sender didn't recieve a ACK!\n");
for (int i=0;i<5;i++)
{
msg_rcv.appendText("Waiting\n");
}
msg_rcv.appendText("Timeout! Sending Message Again\n");
correct++;
}
if (reply==3) //Lost ACK
{
msg_rcv.appendText("Sender received a corrupted ack (ACK is lost), keep waiting!\n");
for (int i=0;i<5;i++)
{
msg_rcv.appendText("Waiting\n");
}
msg_rcv.appendText("Timeout! Sending Message Again\n");
correct++;
}
if (reply==0 || reply==4) //Premature Timeout
{
if (reply==0)
{
msg_rcv.appendText("Sender didn't recieve a ACK because of Timeout!\n");
for (int i=0;i<5;i++)
{
msg_rcv.appendText("Waiting\n");
}
msg_rcv.appendText("Timeout! Sending Message Again\n");
correct++;
}
else if (reply==4)
{
msg_rcv.appendText("Sender received a valid ACK for "+ack+" , send next message!\n");
msg_rcv.appendText("Sender recieved a Duplicate ACK for "+ack+" , ACK ignored\n");
correct=0;
ack++;
}
}
}
else
{
ss.close();
break;
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Now for running them i use this code:
Rdt_App.java:
package rdt_app;
import static java.lang.Thread.sleep;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* #author Dell
*/
public class Rdt_App extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
The errors i get :
Apr 14, 2018 3:59:54 PM javafx.fxml.FXMLLoader$ValueElement processValue
WARNING: Loading FXML document with JavaFX API of version 9.0.1 by JavaFX runtime of version 8.0.101
java.lang.NullPointerException
at rdt_app.FXMLDocumentController.initialize(FXMLDocumentController.java:114)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
at rdt_app.Rdt_App.start(Rdt_App.java:24)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
Did you set your controller in your FXML document? If you don't set controller class for an FXML, FXML components never gets initialized and hence you get a NullPointerException. Besides you don't need to implement Initializable interface. Change #Override to #FXML for intialize () function.
I am not sure if this is a dumb question but I need help with this program I was creating. I wanted to make a login screen to this instant messenger app, which I already have created but I made it in javaFX. The problem is that since this instant messenger app is old, I created it with swing. Since there are no scenes in swing and there are in javafx, then when I hit login I would normally change the scene and that's it. That is why I am changing this program to javafx from swing but I am getting a couple of errors, if anyone is kind enough to tell me what I did wrong I would be grateful. Thanks and sorry for being so redundant, remember i'm just a beginner in 9th grade.
The exact error is in the line 56
The method ActionListener(new ActionListener(){}) is undefined for the type TextField
package messengerClient;
import java.io.*;
import java.net.*;
import java.awt.event.*;
import javax.swing.*;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.*;
import javafx.stage.*;
import javafx.stage.Stage;
import javax.swing.JFrame;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import java.awt.*;
import java.awt.event.ActionEvent;
public class ClientFX extends Application {
private TextField userText;
private TextArea chatWindow;
private ObjectOutputStream output;
private ObjectInputStream input;
private String message = "";
private String serverIP;
private Socket connection;
Stage window;
Scene scene1,scene2;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
window = primaryStage;
window.setTitle("Client - Instant Messenger!");
ClientFX juan = new ClientFX("127.0.0.1");
juan.startRunning();
}
//CONSTRUCTOR
public ClientFX(String host){
serverIP = host;
ScrollPane sp = new ScrollPane();
sp.setContent(chatWindow);
userText = new TextField();
userText.setEditable(false);
userText.ActionListener(
new ActionListener(){
#Override
public void actionPerformed(ActionEvent event){
sendMessage(event.getActionCommand());
userText.setText("");
}
}
);
BorderPane layout1 = new BorderPane();
layout1.setTop(userText);
layout1.setCenter(chatWindow);
chatWindow = new TextArea();
scene2 = new Scene(layout1,500,300);
window.setScene(scene2);
window.show();
}
//CONNECT TO SERVER
public void startRunning(){
try{
connectToServer();
setupStreams();
whileChatting();
}catch(EOFException eofException){
showMessage("\n Client terminated connection");
}catch(IOException ioException){
ioException.printStackTrace();
}finally{
closeCrap();
}
}
//CONNECT TO SERVER
private void connectToServer() throws IOException{
showMessage("Attempting connection... \n");
connection = new Socket(InetAddress.getByName(serverIP), 6789);
showMessage("You have succesfully connected to: " + connection.getInetAddress().getHostName());
}
//SET UP STREAMS TO SEND AND RECIVE MESSAGES
private void setupStreams() throws IOException{
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
showMessage("\nYour streams are now ready to go! \n");
}
//WHILE CHATTING WITH THE SERVER
private void whileChatting() throws IOException{
ableToType(true);
do{
try{
message = (String) input.readObject();
showMessage("\n" + message);
}catch(ClassNotFoundException classnotfoundException){
showMessage("\nI do not know that object type");
}
}while(!message.equals("Server - END"));
}
//CLOSE THE STREAMS AND THE SOCKETS
private void closeCrap(){
showMessage("\nClosing streams and the sockets down...");
ableToType(false);
try{
output.close();
input.close();
connection.close();
}catch(IOException ioException){
ioException.printStackTrace();
}
}
//SEND MESSAGES TO THE SERVER
private void sendMessage(String message){
try{
output.writeObject("CLIENT - " + message);
output.flush();
showMessage("\nCLIENT - " + message);
}catch(IOException ioException){
chatWindow.appendText("\nThat data type cannot be sent, sorry!");
}
}
//UPDATE CHAT WINDOW
private void showMessage(final String m){
SwingUtilities.invokeLater(
new Runnable(){
public void run(){
chatWindow.appendText(m);
}
}
);
}
//GIVES USER PERMISION TO TYPE INTO THE TEXT BOX
private void ableToType(final boolean tof){
SwingUtilities.invokeLater(
new Runnable(){
public void run(){
userText.setEditable(tof);
}
}
);
}
}
The problem is you are mixing swing and javafx. You are importing both:
import java.awt.event.*;
import javax.swing.*;
import javafx.application.Application;
...
import javafx.scene.Scene;
import javafx.scene.control.Button;
For example in the ClientFX constructor you are trying to add a javax.swing.JTextField (a swing component) to a javafx.scene.BorderPane (a javafx component). The JTextField does not extend javafx.scene.Node, therefore it cannot be given to BorderPane.setTop(Node).
Basically for any swing component (often start with J, JTextField, JTextArea etc.) find the javafx equivalent (for example javafx.scene.control.TextField, javafx.scene.control.TextArea) and learn how to use them (they will have a different api).
In the end you should not have an import statement for java.awt or javax.swing.
Update
As already said you need to learn how to use the new fx apis. Not only the package names, classes and methods change, but also maybe programming concepts.
To port your JTextField behaviour you use a TextField and call the setOnAction method with an EventHandler implementation (very similar to the swing concept):
userText.setOnAction(new EventHandler<javafx.event.ActionEvent>()
{
#Override
public void handle(javafx.event.ActionEvent event)
{
//
}
});
I wrote a little Clock in JavaFX8. On my GUI, I have 2 Buttons. One button should start the timer and the other button should pause the timer. But whenever I press start, nothing is happening. When I delete the whole if() clause, I am able to start the timer via thread.start and it's updating my GUI. I think my call if(isRunning) isn't working how I want.
I appreciate any kind of help!
My Window.java (Main Application)
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package gui;
import java.util.Observable;
import java.util.Observer;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import logic.Clock;
import logic.ClockObserver;
/**
*
* #author
*/
public class Window extends Application implements Observer {
private Button b_start = new Button("Start");
private Button b_stop = new Button("Stop");
private Label l_time = new Label("gdfgdf");
private HBox buttonbox = new HBox();
private Clock clock = new Clock();
private Thread thread = new Thread(clock);
#Override
public void start(Stage primaryStage) throws Exception {
thread.start();
buttonbox.setSpacing(5.0);
clock.addObserver(this);
buttonbox.setAlignment(Pos.CENTER);
buttonbox.getChildren().addAll(b_start, b_stop);
BorderPane bp = new BorderPane();
bp.setPadding(new Insets(10.0));
bp.setCenter(l_time);
bp.setBottom(buttonbox);
Scene scene = new Scene(bp);
primaryStage.setMinHeight(150);
primaryStage.setMinWidth(250);
primaryStage.setScene(scene);
primaryStage.setTitle("Uhr");
primaryStage.show();
b_start.setOnAction((ActionEvent e) ->{
clock.setRunning(true);
});
b_stop.setOnAction((ActionEvent e) ->{
clock.setRunning(false);
});
}
public static void main(String args[]) {
launch(args);
}
#Override
public void update(Observable o, Object o1) {
Platform.runLater(new Runnable(){
#Override
public void run() {
l_time.setText(clock.getZeit());
}
});
}
}
My Clock.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package logic;
import gui.Window;
import java.util.Observable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
/**
*
* #author
*/
public class Clock extends Observable implements Runnable {
private String zeit = "";
private int sek;
private boolean isRunning = false;
public Clock() {
}
public void setZeit() {
zeit = "" + sek;
}
public String getZeit() {
return zeit;
}
public void setRunning(boolean running){
this.isRunning = running;
}
public boolean isRunning(){
return isRunning;
}
public int getSek() {
return sek;
}
#Override
public void run() {
while (true) {
if (isRunning()) {
try {
sek++;
setZeit();
System.out.println(zeit);
this.setChanged();
this.notifyObservers();
Thread.sleep(1000);
} catch (InterruptedException ex) {
//TODO
}
}
}
}
}
Thanks in advance!