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.
Related
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);
}
}
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();
});
}
Not only have I lost 5 hours but also almost my mind because of this problem.
I load a String from a Txt File and want to set it to the label sourceURL. Before I check it in System.out.println("Firstline is : " + brTest.readLine()); and it shows the String correctli. But then the UI pops up and the label is empty.
It looks like it couldnt load it and needs to refresh. Do you know anything here?
DashBoardController
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.text.Font;
import javafx.stage.DirectoryChooser;
public class DashboardController {
#FXML
private Label userFeedback;
#FXML
private Font x1;
#FXML
private Label sourceURL;
#FXML
private Label targetURL;
#FXML
public void initialize(){
BufferedReader brTest;
try {
brTest = new BufferedReader(new FileReader(new File("settings/sourceurl.txt")));
System.out.println("Firstline is : " + brTest.readLine());
String temp = brTest.readLine();
sourceURL.setText(brTest.readLine());
sourceURL.setText(temp);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#FXML
void convert(ActionEvent event) {
}
#FXML
void openFolder(ActionEvent event) {
}
#FXML
void selectSource(ActionEvent event) throws FileNotFoundException {
//DirectoryChooser initialisieren
DirectoryChooser directoryChooser = new DirectoryChooser();
directoryChooser.setTitle("Quellordner wählen");
//URL speichern
File selectedDirectory = directoryChooser.showDialog(null);
sourceURL.setText(selectedDirectory.getAbsolutePath());
//Ordner erstellen
File settings = new File("settings");
settings.mkdir();
//Datei erstellen und URL abspeichern
PrintWriter printWriter = new PrintWriter("settings/sourceurl.txt");
printWriter.println(selectedDirectory.getAbsolutePath());
printWriter.close();
}
#FXML
void selectTarget(ActionEvent event) {
sourceURL.setText("sdfkjasdöfl");
}
#FXML
void showInfo(ActionEvent event) {
}
#FXML
void showSupport(ActionEvent event) {
}
}
Dashboard
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class Dashboard extends Application {
public static void main(String[] args) {
// TODO Auto-generated method stub
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
// TODO Auto-generated method stub
//Pane laden
Pane pane = (Pane) FXMLLoader.load(Dashboard.class.getResource("Dashboard.fxml"));
//Stage einrichten
stage.setScene(new Scene(pane));
stage.setTitle("");
stage.setResizable(false);
stage.show();
}
}
If you want to set the text of a TextField during loading, you have to get the ID by using the lookup() function(in JavaFX):
initialize(){
scene = Pane.getScene();
TextField sourceURL= (TextField) scene .lookup("#sourceURL");
sourceURL.setText("your text");
}
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 have a ListView with a TextField above it. If a user enters in a search query into the textfield, the listview will update and filter itself to show relevant results.
The ListView shows items from a FilteredList, which is filled with Employee objects. Each Employee has a first and last name.
package application.ctrl;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.transformation.FilteredList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
import javafx.geometry.Side;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.CustomMenuItem;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import application.Main;
import application.objects.Employee;
import application.objects.EmployeeDatabase;
public class EmployeePickerWidget extends VBox implements Initializable {
#FXML
private TextField textField;
#FXML
private Button addNewEmployee;
#FXML
private ListView<Employee> employeeList;
private FilteredList<Employee> filteredList;
private ContextMenu cm;
private CustomMenuItem item;
private ClickedEmployeeInterface parent;
public EmployeePickerWidget(ClickedEmployeeInterface parent) {
FXMLLoader loader = new FXMLLoader(this.getClass().getResource(
Main.EMPLOYEE_PICKER));
loader.setRoot(this);
loader.setController(this);
try {
loader.load();
} catch (IOException e) {
e.printStackTrace();
}
this.parent = parent;
}
#Override
public void initialize(URL location, ResourceBundle resources) {
setupEmployeeListView();
setupTextField();
}
private void setupEmployeeListView() {
filteredList = new FilteredList<Employee>(EmployeeDatabase.getInstance()
.getObservableList());
employeeList = new ListView<Employee>();
employeeList.setItems(filteredList);
employeeList.setOnMouseClicked(arg0 -> {
if (employeeList.getSelectionModel().getSelectedItem() != null) {
cm.hide();
parent.handleClickedEmployee();
}
});
}
private void setupTextField() {
textField.textProperty().addListener(
(observable, oldValue, newValue) -> {
filteredList.setPredicate(employee -> {
return filterHelper(employee, newValue);
});
});
textField.setText(" ");
textField.setText("");
textField.setOnMouseClicked(event -> cm
.show(textField, Side.BOTTOM, 0, 0));
cm = new ContextMenu();
item = new CustomMenuItem();
VBox container = new VBox();
container.setAlignment(Pos.CENTER_RIGHT);
container.getChildren().add(employeeList);
Button defineEmployeeBtn = new Button("Define New Employee");
defineEmployeeBtn.setOnAction(event -> {
FXMLLoader loader = new FXMLLoader(getClass().getResource(
Main.DEFINE_NEW_EMPLOYEE));
Parent root = null;
try {
root = loader.load();
} catch (IOException e) {
e.printStackTrace();
}
Scene newScene = new Scene(root);
Stage newStage = new Stage();
newStage.setScene(newScene);
newStage.show();
});
container.getChildren().add(defineEmployeeBtn);
item.setContent(container);
cm.getItems().add(item);
}
private boolean filterHelper(Employee employee, String query) {
String first = employee.getFirst().toLowerCase(), last = employee
.getLast().toLowerCase();
String[] querySplit = query.replace(",", "\\s").split("\\s+");
int length = querySplit.length;
for (int i = 0; i < length; i++)
querySplit[i] = querySplit[i].toLowerCase();
if (length == 1) {
if (first.contains(querySplit[0]) || last.contains(querySplit[0]))
return true;
else
return false;
} else if (length == 2) {
if (first.contains(querySplit[0]) || last.contains(querySplit[0]))
if (first.contains(querySplit[1]) || last.contains(querySplit[1]))
return true;
return false;
} else if (length == 3) {
return false;
}
return false;
}
public Employee getEmployee() {
return employeeList.getSelectionModel().getSelectedItem();
}
#FXML
public void addNewEmployee() {
}
}
interface ClickedEmployeeInterface {
void handleClickedEmployee();
}
If there were 3 employees named "Donald Trump", "Donald Smith", and "Donald Jackson" in the database, then the following needs to happen:
Typing up to the word "Donald" will show all 3 results.
Typing a space after Donald (resulting in "Donald ") will still show 3 results.
Typing a T after the previous query (resulting in "Donald T") should only show 1 result.
The problem is, after I enter in a space, the ListView breaks, and all of my Employees disappear from the ListView. When I click outside of the textfield and click back in again, it triggers this:
textField.setOnMouseClicked(event -> cm
.show(textField, Side.BOTTOM, 0, 0));
And my ListView suddenly works again, showing that one Employee.
How do I make the ListView filter properly without having to click out and back in?
I do not have the FXML file, so I wasn't able to replicate your problem. There are multiple problems with your code and this is the not the optimum solution, still, I have edited your answer to give you hints and help you understand the areas where you might have committed logical errors
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Side;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class DemoList extends Application {
#Override
public void start(Stage stage) throws Exception {
GridPane gridPane = new GridPane();
Label label = new Label("Name");
final TextField textField = new TextField();
textField.setFocusTraversable(false);
textField.setPromptText("Please Type Here");
final ContextMenu cm = new ContextMenu();
final ObservableList<String> employeeList = FXCollections
.observableArrayList();
employeeList.addAll("Donald Duck", "Donald Mouse", "Donald Goofy");
textField.textProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> arg0,
String arg1, String arg2) {
// To clear the Context Menu so that same items are not added
// multiple times
cm.getItems().clear();
for (String employee : employeeList) {
if (filterHelper(employee, arg2)) {
cm.getItems().add(new MenuItem(employee));
}
}
}
});
textField.setOnMouseClicked(new EventHandler<Event>() {
#Override
public void handle(Event arg0) {
// To clear the Context Menu so that same items are not added
// multiple times
cm.getItems().clear();
//Adding the data for initial click
for (String employee : employeeList) {
if (filterHelper(employee, textField.getText())) {
cm.getItems().add(new MenuItem(employee));
}
}
cm.show(textField, Side.BOTTOM, 0, 0);
}
});
gridPane.add(label, 0, 0);
gridPane.add(textField, 0, 1);
Scene scene = new Scene(gridPane, 300, 300);
stage.setScene(scene);
stage.show();
}
private boolean filterHelper(String employee, String query) {
//Splitting Employee name to fetch first and last name
String first = employee.split(" ")[0].toLowerCase(), last = employee
.split(" ")[1].toLowerCase();
String[] querySplit = query.replace(",", "\\s").split("\\s+");
int length = querySplit.length;
for (int i = 0; i < length; i++)
querySplit[i] = querySplit[i].toLowerCase();
/**
* Avoid adding unnecessary return statement
* I have removed all the 'return false' statements
* The last return will take care of all the 'return false'
*/
//only single word
if (length == 1) {
if (first.startsWith(querySplit[0])
|| last.startsWith(querySplit[0]))
return true;
}
//two words, considering first word is first name
//and second word is last name
else if (length == 2) {
if (first.startsWith(querySplit[0])
&& last.startsWith(querySplit[1]))
return true;
}
return false;
}
public static void main(String[] args) {
launch(args);
}
}