I want to create a dynamic tableview that gets its data from a json provided by a webpage. The thing is that whenever the data from the json is out of range (for example the range should be 0.8 - 0.9, but it reads 1.1), the table automatically updates the observablelist with a "RED SQUARE" image. If the data is within range, it shows a "BLUE SQUARE" image. It's like a status indicator so that the user knows if the data is correct or not. I have this code:
public ObservableList<PumpSites> list = FXCollections.observableArrayList(
new PumpSites (blue or red square image, "Canduman"),
new PumpSites (blue or red square image, "Cubacub"),
new PumpSites (blue or red square image, "Liloan"),
new PumpSites (blue or red square image, "Talamban"),
new PumpSites (blue or red square image, "Tisa")
);
status.setCellValueFactory(new PropertyValueFactory<PumpSites, String>("status"));
ps.setCellValueFactory(new PropertyValueFactory<PumpSites, String>("ps"));
table.setItems(list);
public class PumpSites {
private final SimpleStringProperty status;
private final SimpleStringProperty ps;
public PumpSites(String status, String ps){
super();
this.status = new SimpleStringProperty(status);
this.ps = new SimpleStringProperty(ps);
}
public String getStatus() {
return status.get();
}
public String getPs() {
return ps.get();
}
}
I have no problem getting data from the json. I am planning to put the dynamic reading of data for the status indicator inside a platform.runlater so that it updates always. How can I show a blue or red square beside the pump site in the table dynamically?
Here are some ideas and code samples:
(1) Rendering a state (yes or no) for a table view's column cell - sample code:
The DataClass
can have a boolean
property defined like this:
private SimpleBooleanProperty status;
The table view's cell can be rendered with the a check box using the status's boolean property values. Here is code how the table view's column may be defined:
TableColumn<DataClass, Boolean> statusCol = new TableColumn<>("Status");
statusCol.setCellValueFactory(new PropertyValueFactory<DataClass, Boolean>("priority"));
statusCol.setCellFactory(column -> {
CheckBoxTableCell<DataClass, Boolean> cell = new CheckBoxTableCell<>();
cell.setAlignment(Pos.CENTER);
return cell;
});
As I have already suggested a colored box (using a shape class like Rectangle
from javafx.scene.shape
package) can be rendered instead of a check box.
(2) A java.util.Timer
and TimerTask
classes can be used to schedule and run a task periodically. In the main application after the gui is built the timer can be initialized as follows:
public class BuildMyAppGui {
//...
private void initiateTimer() {
Timer timer = new Timer();
long zeroDelay = 0L;
long period = 60000L; // 60 * 1000 = 1 min
// The timer runs once the first time
// and subsequently the scheduled task every one minute
timer.schedule(new DataChangedTask(), zeroDelay, period);
}
//...
}
The timer's task class sample code:
public class DataChangedTask extends TimerTask {
@Override
public void run() {
// Code checks if there is a data change and refreshes the table data.
// This also refreshes the table column with check box -
// as checked or un-checked depending on the true/false value
// in the boolean property in DataClass.
}
}
Note the DataChangedTask
class can have constructors take references to data and access other references as required by the app.