Reputation: 231
I want to change the label data dynamically through normal java class how can i do it.
below is my .fxml file :
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="1311.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafx_lsdu.LsduFrameController">
<children>
<GridPane layoutX="14.0" layoutY="14.0" prefHeight="30.0" prefWidth="1286.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label id="PlazaName" fx:id="PlazaName" alignment="CENTER_RIGHT" prefHeight="33.0" prefWidth="257.0" text="PLAZA NAME :" />
<Label id="PlazaNameData" fx:id="PlazaNameData" prefHeight="33.0" prefWidth="257.0" GridPane.columnIndex="1" />
<Label id="LaneStatus" fx:id="LaneStatus" alignment="CENTER" prefHeight="32.0" prefWidth="257.0" text="LANE STATUS" GridPane.columnIndex="2" />
<Label id="DateTime" fx:id="DateTime" alignment="CENTER_RIGHT" prefHeight="35.0" prefWidth="256.0" text="DATE & TIME :" GridPane.columnIndex="3" />
</children>
</GridPane>
</children>
</AnchorPane>
below is my controller class:
public class LsduFrameController implements Initializable {
@FXML
public static Label PlazaNameData;
/**
* Initializes the controller class.
* @param url
* @param rb
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
new Thread(new DisplayPlazaNameLocation()).start();
// here i am calling DisplayPlazaNameLocation.java class and creating new thread
}
}
in below code I try to set the label text :-
public class DisplayPlazaNameLocation implements Runnable{
static String plazaNameLocation;
static Connection con;
@Override
public void run() {
inRun();
}
public void inRun(){
try {
Class.forName(DB_DRIVER_CLASS);
con= DriverManager.getConnection(DB_URL[0],DB_USERNAME,DB_PASSWORD);
if(con != null){
this.getPlazaNameLocation();
}
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
catch (SQLException ex) {
ex.printStackTrace();
}
}
public void getPlazaNameLocation(){
try {
PreparedStatement pst=con.prepareStatement("SELECT DISTINCT Plaza_Loc FROM lsdu_live");
ResultSet rs = pst.executeQuery();
while(rs.next()){
plazaNameLocation = rs.getString("Plaza_Loc");
}
//jLabel199.setText(plazaNameLocation);
String ar[] = plazaNameLocation.split(",");
//jLabel199.setText("<html>"+ar[0]+"<br>"+ar[1]+"</html>");
System.out.println("plazaNameLocation");
//===================================================================
LsduFrameController.PlazaNameData.setText(plazaNameLocation);//here i am trying to set the label text.
//=======================================================================
rs.close();
pst.close();
con.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
I am getting below exception:
Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
at inf_main_code.DisplayPlazaNameLocation.getPlazaNameLocation(DisplayPlazaNameLocation.java:57)
at inf_main_code.DisplayPlazaNameLocation.inRun(DisplayPlazaNameLocation.java:36)
at inf_main_code.DisplayPlazaNameLocation.run(DisplayPlazaNameLocation.java:29)
at java.lang.Thread.run(Thread.java:745)
at this line
LsduFrameController.PlazaNameData.setText(plazaNameLocation);
How can I set label text from another normal java class?
In which way I need to modify my code ?
Upvotes: 1
Views: 716
Reputation: 82461
FXMLLoader
doesn't inject to static
fields.
You could make PlazaNameData
a instance field and copy it to a static
field in the initialize
method
public class LsduFrameController implements Initializable {
@FXML
public Label PlazaNameData;
public static Label PlazaNameDataStatic;
/**
* Initializes the controller class.
* @param url
* @param rb
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
PlazaNameDataStatic = PlazaNameData;
...
}
...
Using static
is often bad design. In most cases there are better ways to pass the data.
In this case you could simply pass a reference to LsduFrameController
to the DisplayPlazaNameLocation
, e.g. in a constructor, and access the relevant instance members of the controller via that reference.
public class LsduFrameController implements Initializable {
@FXML
public Label PlazaNameData;
...
@Override
public void initialize(URL url, ResourceBundle rb) {
new Thread(new DisplayPlazaNameLocation(this)).start();
}
...
}
public class DisplayPlazaNameLocation implements Runnable {
private final LsduFrameController lsduController;
public DisplayPlazaNameLocation(LsduFrameController lsduController) {
this.lsduController = lsduController;
}
...
javafx.application.Platform.runLater( new Runnable() {
@Override
public void run() {
lsduController.PlazaNameData.setText(plazaNameLocation);
}
});
...
}
Furthermore updates from different threads than the javafx application thread should be done using Platform.runLater
.
Upvotes: 2
Reputation: 410
You can't change something in FX Thread
from other Thread
. Change this:
...
System.out.println("plazaNameLocation");
//===================================================================
LsduFrameController.PlazaNameData.setText(plazaNameLocation);//here i am trying to set the label text.
//=======================================================================
rs.close();
...
to:
Java 8:
...
System.out.println("plazaNameLocation");
javafx.application.Platform.runLater( () ->
LsduFrameController.PlazaNameData.setText(plazaNameLocation);
);
rs.close();
...
Java 7:
...
System.out.println("plazaNameLocation");
javafx.application.Platform.runLater( new Runnable() {
@Override
public void run() {
LsduFrameController.PlazaNameData.setText(plazaNameLocation);
}
});
rs.close();
...
Upvotes: 1