I'm trying to push my data that I'm getting from a RethinkDB into a JavaFx TableView, however, the changes do not appear in the tableview and I can't figure out why.
I'm pretty new to JavaFx so I hope you can help me.
Here are my classes : (I didn't include my memory classes where I save the data from the DB)
RethinkDBConnect class
public class RethinkDBConnect {
public static final RethinkDB r = RethinkDB.r;
GsonConverter con = new GsonConverter();
JiraTicketBody body = new JiraTicketBody();
ViewController viewcon = new ViewController();
TicketDataProperty tickprop = new TicketDataProperty(null, null, null, null, null, null);
public void Connection(){
viewcon.list.add(newTicketDataProperty
("test","test","test","test","test","test"));
}
}
TicketDataProperty class
public class TicketDataProperty {
private final SimpleStringProperty key;
private final SimpleStringProperty prioritaet;
private final SimpleStringProperty erstellt;
private final SimpleStringProperty status;
private final SimpleStringProperty zustand;
private final SimpleStringProperty beschreibung;
public TicketDataProperty(String key, String prioritaet, String erstellt,
String status, String zustand, String beschreibung)
{
this.key = new SimpleStringProperty(key);
this.prioritaet = new SimpleStringProperty(prioritaet);
this.erstellt = new SimpleStringProperty(erstellt);
this.status = new SimpleStringProperty(status);
this.zustand = new SimpleStringProperty(zustand);
this.beschreibung = new SimpleStringProperty(beschreibung);
}
public String getKey() {
return key.get();
}
public void setKey(String value) {
key.set(value);
}
public String getPrioritaet() {
return prioritaet.get();
}
public void setPrioritaet(String value) {
prioritaet.set(value);
}
public String getErstellt() {
return erstellt.get();
}
public void setErstellt(String value) {
erstellt.set(value);
}
public String getStatus() {
return status.get();
}
public void setStatus(String value) {
status.set(value);
}
public String getZustand() {
return zustand.get();
}
public void setZustand(String value) {
zustand.set(value);
}
public String getBeschreibung() {
return beschreibung.get();
}
public void setBeschreibung(String value) {
beschreibung.set(value);
}
}
ViewController class
public class ViewController implements Initializable {
TicketDataProperty tickdat = new TicketDataProperty(null, null, null, null, null, null);
#FXML private TableView <TicketDataProperty> table;
#FXML private TableColumn <TicketDataProperty,String> key;
#FXML private TableColumn <TicketDataProperty,String> prioritaet;
#FXML private TableColumn <TicketDataProperty,String> erstellt;
#FXML private TableColumn <TicketDataProperty,String> status;
#FXML private TableColumn <TicketDataProperty,String> zustand;
#FXML private TableColumn <TicketDataProperty,String> beschreibung;
public ObservableList<TicketDataProperty> list = FXCollections.observableArrayList(
new TicketDataProperty("example","example","example","example","example","example")
);
#Override
public void initialize(URL location, ResourceBundle resources) {
key.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("key"));
prioritaet.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("prioritaet"));
erstellt.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("erstellt"));
status.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("status"));
zustand.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("zustand"));
beschreibung.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("beschreibung"));
table.setItems(list);
}
}
GsonConverter class
public class GsonConverter {
public JiraTicketBody gson(String json)
{
Gson gson = new Gson();
JiraTicketBody BodyObj = gson.fromJson(json,JiraTicketBody.class);
return BodyObj;
}
}
Main class
public class Main extends Application
{
//ViewXML
#Override
public void start(Stage primaryStage) throws IOException
{
Parent root = FXMLLoader.load(getClass().getResource("/view/ViewXML.fxml"));
Scene scene = new Scene(root);
primaryStage.setTitle("Ticket System Application");
primaryStage.setScene(scene);
primaryStage.sizeToScene();
primaryStage.show();
}
public static void main(String[] args)
{
try {
//ViewXML
launch(args);
RethinkDBConnect obj = new RethinkDBConnect();
obj.Connection();
} catch(Exception e) {
}
}
}
There are two issues with the code you have posted.
As stated in the documentation, Application.launch() blocks until the application exits. So you don't even create the RethinkDBConnection class until the application is in the process of closing. You should consider the start() method to be the entry point to the application, and should have no code other than launch() in the main(...) method. Anything you do in a JavaFX application should be done in the start(...) or init(...) methods, or in methods invoked from there, etc.
In this case, since you don't seem to need RethinkDBConnection from outside the controller, I see no reason not to create RethinkDBConnect from the controller itself.
You need to update the list that belongs to the controller. Instead, you are creating a new object that happens to be the same class as the controller, and updating the list that belongs to that object. Obviously, that list has nothing at all to do with the table. You need to pass a reference to the actual list that is used as the backing list for the table to the RethinkDBController instance.
So your code should look like:
public class RethinkDBConnection {
// public static final RethinkDB r = RethinkDB.r;
// GsonConverter con = new GsonConverter();
// JiraTicketBody body = new JiraTicketBody();
private final ObservableList<TicketDataProperty> dataList ;
public RethinkDBConnection(ObservableList<TicketDataProperty> dataList) {
this.dataList = dataList ;
}
public void connect(){
dataList.add(new TicketDataProperty
("test","test","test","test","test","test"));
}
}
Then in the controller you can do:
public class ViewController implements Initializable {
#FXML private TableView <TicketDataProperty> table;
#FXML private TableColumn <TicketDataProperty,String> key;
#FXML private TableColumn <TicketDataProperty,String> prioritaet;
#FXML private TableColumn <TicketDataProperty,String> erstellt;
#FXML private TableColumn <TicketDataProperty,String> status;
#FXML private TableColumn <TicketDataProperty,String> zustand;
#FXML private TableColumn <TicketDataProperty,String> beschreibung;
private ObservableList<TicketDataProperty> list = FXCollections.observableArrayList(
new TicketDataProperty("example","example","example","example","example","example")
);
#Override
public void initialize(URL location, ResourceBundle resources) {
key.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("key"));
prioritaet.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("prioritaet"));
erstellt.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("erstellt"));
status.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("status"));
zustand.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("zustand"));
beschreibung.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("beschreibung"));
table.setItems(list);
RethinkDBConnection connection = new RethinkDBConnection(list);
connection.connect();
}
}
And your Main class should just be:
public class Main extends Application
{
//ViewXML
#Override
public void start(Stage primaryStage) throws IOException
{
Parent root = FXMLLoader.load(getClass().getResource("/view/ViewXML.fxml"));
Scene scene = new Scene(root);
primaryStage.setTitle("Ticket System Application");
primaryStage.setScene(scene);
primaryStage.sizeToScene();
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
If you really do need access to your RethinkDBConnection instance outside the controller, then modify the controller as follows:
public class ViewController implements Initializable {
#FXML private TableView <TicketDataProperty> table;
#FXML private TableColumn <TicketDataProperty,String> key;
#FXML private TableColumn <TicketDataProperty,String> prioritaet;
#FXML private TableColumn <TicketDataProperty,String> erstellt;
#FXML private TableColumn <TicketDataProperty,String> status;
#FXML private TableColumn <TicketDataProperty,String> zustand;
#FXML private TableColumn <TicketDataProperty,String> beschreibung;
private ObservableList<TicketDataProperty> list = FXCollections.observableArrayList(
new TicketDataProperty("example","example","example","example","example","example")
);
#Override
public void initialize(URL location, ResourceBundle resources) {
key.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("key"));
prioritaet.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("prioritaet"));
erstellt.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("erstellt"));
status.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("status"));
zustand.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("zustand"));
beschreibung.setCellValueFactory(new PropertyValueFactory<TicketDataProperty,String>("beschreibung"));
table.setItems(list);
}
public ObservableList<TicketDataProperty> getDataList() {
return list ;
}
}
and use this version of Main:
public class Main extends Application
{
//ViewXML
#Override
public void start(Stage primaryStage) throws IOException
{
FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/ViewXML.fxml"));
Parent root = loader.load();
ViewController controller = loader.getController();
RethinkDBConnection connection = new RethinkDBConnection(controller.getDataList());
connection.connect();
Scene scene = new Scene(root);
primaryStage.setTitle("Ticket System Application");
primaryStage.setScene(scene);
primaryStage.sizeToScene();
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Note that I renamed some classes and methods to adhere to standard naming conventions.
Related
I have many FXML with different Controller and I want to access all Controller Instance in one class using static methods. The reason I am doing this because I want to change the UI of different FXML from different controller. I'm not sure if there is any better way to do it. My problem is in my SceenViews class because I don't know what datatype to use to hold FXML Controller Instance in my controllerMap variable.
Inside my Package: Main.java, ScreenViews.java, Frame.FXML, FrameController.java, Login.FXML, LoginController.java, Dashboard.FXML, DashboardController.java, Journal.FXML, and JournalController.java
Main.java
public class Main extends Application {
#Override
public void start(Stage stage) throws Exception {
ScreenViews.loadFXML("Frame", "Frame.fxml");
ScreenViews.loadFXML("Login", "Login.fxml");
ScreenViews.loadFXML("Dashboard", "Dashboard.fxml");
ScreenViews.loadFXML("Journal", "Journal.fxml");
Scene scene = new Scene((Parent) ScreenViews.getView("Frame"));
scene.setFill(Color.TRANSPARENT);
stage.initStyle(StageStyle.TRANSPARENT);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
In my ScreenViews.java what datatype can I use to hold different controller instance in my controllerMap variable?
public class ScreenViews {
private static HashMap<String, Node> viewMap = new HashMap<>();
//HASHMAP FOR CONTROLLER INSTANCE
private static HashMap<String, datatype? > controllerMap = new HashMap<>();
public static void addView(String name, Node screen) {
viewMap.put(name, screen);
}
public static Node getView(String name) {
return viewMap.get(name);
}
public static void addController(String name, datatype? controller) {
controllerMap.put(name, controller);
}
public static datatype? getController(String name) {
return controllerMap.get(name);
}
public static boolean loadFXML(String name, String resource) {
try {
FXMLLoader fxLoader = new
FXMLLoader(ScreenViews.class.getResource(resource));
Parent loadedFXML = (Parent) fxLoader.load();
addView(name, loadedFXML);
addController(name, fxLoader.getController());
return true;
} catch (IOException e) {
System.out.println(e.getMessage());
return false;
}
}
}
Sample LoginController.java code
public class LoginController implements Initializable {
#Override
public void initialize(URL url, ResourceBundle rb) {
}
#FXML
public void frameSetUI(ActionEvent event) {
ScreenViews.getController("Frame").getFramePane().getChildren().add(ScreenViews.get("Dashboard"));
}
}
Sample FrameController.java code
public class FrameController implements Initializable {
#FXML private StackPane rootPane;
#FXML private AnchorPane titleBar;
#FXML private AnchorPane framePane;
#FXML private Button toDashboard;
#FXML private AnchorPane mainPane;
public void initialize(URL url, ResourceBundle rb) {
}
public AnchorPane getFramePane(){
return framePane;
}
}
I have below code. the tableview does not display record on GUI,is empty.
How I can Pass value from the ServerHandler thread to JAVAFX UI thread.
Can you please suggest?
Thanks
UPDATE
The Main class
public class Main extends Application {
private static Stage stage;
#Override
public void start(Stage primaryStage){
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("mainpane.fxml"));
fxmlLoader.load();
setStage(primaryStage);
Parent root = fxmlLoader.getRoot();
Scene scene = new Scene(root,800,800);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
new Thread(() -> launch(Main.class, args)).start();
new MyServer().startDownload();
}
The Controller
public class SampleController {
private ObservableList<Model> tableData = FXCollections.observableArrayList();
#FXML
private TableView<Model> table;
#FXML
private TableColumn<Model, String> firstCol;
#FXML
private TableColumn<Model, String> secondCol;
#FXML
public void initialize() {
table.setEditable(false);
firstCol.setCellValueFactory(cellData -> cellData.getValue().getName());
secondCol.setCellValueFactory(cellData -> cellData.getValue().getCurrent());
table.setItems(tableData);
}
public void addModel(ChannelFuture sendFileFeture,Model model){
table.getItems().add(Model);
System.out.println("row model= "+model.getName().get());// it works fine;
sendFileFeture.addListener(model);
}
The Server class with Netty 4
public class ServerHandler extends SimpleChannelInboundHandler<FullHttpRequest>{
#Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
//some codes
Model model=new Model(file.getName(),fileLength+"");
SampleController sc=new SampleController();
sc.addModel(sendFileFeture, model);
}
The Model class with ChannelProgressiveFutureListener of Netty
public class Model implements ChannelProgressiveFutureListener{
private SimpleStringProperty name=null;
private SimpleStringProperty current=null;
public Model(String name,String current){
this.name=new SimpleStringProperty(name);
this.current=new SimpleStringProperty(current);
}
#Override
public void operationProgressed(ChannelProgressiveFuture future, long progress, long total) throws Exception {
System.out.println("current: "+current+",progress: "+progress); //it works fine
current.set(progress+""); // can not update the TableView
}
#Override
public void operationComplete(ChannelProgressiveFuture future) throws Exception {
}
public void setName(String name) {
this.name.set(name);
}
public SimpleStringProperty getName() {
return name;
}
public void setCurrent(String current) {
this.current.set(current);
}
public SimpleStringProperty getCurrent() {
return current;
}
UPDATE
the tableview not updating with right size,the image i loaded is 2,407,257 bytes.you can find the errors in the images below.
image1
image2
secondCol.setCellValueFactory(cellData -> cellData.getValue().getCurrent());
secondCol.setCellFactory(column -> {return new TableCell<Model, String>() {
#Override
protected void updateItem(String item, boolean empty) {
System.out.println(item); //UPDATING NOT CURRECT
super.updateItem(item, empty);
setText(empty ? "" : getItem().toString());
}
};
The UI is not displaying anything because you are populating a different table to the one you are displaying, not because of threading (though you have threading issues too, or will do once you fix the initial problem).
In your start() method, you load the FXML, which creates a TableView and its columns, and creates a controller instance. Your ServerHandler class creates a new instance of the controller, which in turn creates a new instance of TableView (it is always a mistake to initialize variables that are annotated #FXML). That TableView instance is never displayed. So when your ServerHandler populates the table, it is populating a table that is not actually part of the UI, and you don't see anything.
Move the creation of the MyServer to the start() method, and pass it the existing controller instance:
public class Main extends Application {
private Stage stage;
#Override
public void start(Stage primaryStage){
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("mainpane.fxml"));
fxmlLoader.load();
setStage(primaryStage);
Parent root = fxmlLoader.getRoot();
Scene scene = new Scene(root,800,800);
primaryStage.setScene(scene);
primaryStage.show();
SampleController controller = loader.getController();
new Thread(() -> new MyServer(controller).startDownload()).start();
}
public static void main(String[] args) {
launch(args);
}
}
Your MyServer class should in turn pass the controller to the ServerHandler instance(s). Since the ServerHandler methods are being invoked on a background thread, they need to use Platform.runLater(...) to update the UI:
public class ServerHandler extends SimpleChannelInboundHandler<FullHttpRequest>{
private final SampleController sc ;
public ServerHandler(SampleController sc) {
this.sc = sc ;
}
#Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
//some codes
Model model=new Model(file.getName(),fileLength+"");
Platform.runLater(() -> {
sc.addModel(sendFileFeture, model);
sc.addRowModel(sendFileFeture, rowModel);
});
}
}
Finally, don't initialize fields that are supposed to be initialized by the FXMLLoader. This will only have the effect of suppressing any NullPointerExceptions that indicate your controller-FXML bindings are not properly set up:
public class SampleController {
private ObservableList<Model> tableData = FXCollections.observableArrayList();
#FXML
private TableView<RowModel> table ;
#FXML
private TableColumn<Model, String> firstCol ;
#FXML
private TableColumn<Model, String> secondCol ;
#FXML
public void initialize() {
table.setEditable(false);
firstCol.setCellValueFactory(cellData -> cellData.getValue().getName());
secondCol.setCellValueFactory(cellData -> cellData.getValue().getProgress());
table.setItems(tableData);
}
public void addModel(ChannelFuture sendFileFeture,Model model){
table.getItems().add(model);
System.out.println("row model= "+model.getName().get());// it works fine;
sendFileFeture.addListener(rowModel);
}
}
This question already has answers here:
Javafx tableview not showing data in all columns
(3 answers)
Closed 6 years ago.
I develop an JavaFX application with TableView, where I want to show data from MySQL database. When I click the button to show all the data, in the table view show only one column with id of the row in MySQL, and other columns still empty.
The controller:
public class FXMLDocumentController implements Initializable {
private Label label;
#FXML
private TableView table;
#FXML
private TextField uname;
#FXML
private PasswordField pass;
#FXML
private Button add;
#FXML
private Button del;
#FXML
private TableColumn tc1;
#FXML
private TableColumn tc2;
#FXML
private TableColumn tc3;
private ObservableList<ShowData>data;
private Connection1 c;
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
label.setText("Hello World!");
}
#Override
public void initialize(URL url, ResourceBundle rb) {
c= new Connection1();
}
private void onClick(ActionEvent event) throws IOException {
Stage stage=new Stage();
Parent root = FXMLLoader.load(getClass().getResource("/Box/FXML.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
#FXML
private void onAdd(ActionEvent event) {
}
#FXML
private void onDelete(ActionEvent event) {
}
#FXML
private void onOpen(ActionEvent event) {
try {
Connection conn=c.Connect();
data=FXCollections.observableArrayList();
ResultSet rs=conn.createStatement().executeQuery("SELECT * FROM logs");
while (rs.next()) {
data.add(new ShowData(rs.getString(1), rs.getString(2), rs.getString(3)));
}
} catch (SQLException ex) {
System.err.println("Error"+ex);
}
tc1.setCellValueFactory(new PropertyValueFactory("id"));
tc2.setCellValueFactory(new PropertyValueFactory("username"));
tc3.setCellValueFactory(new PropertyValueFactory("msg"));
table.setItems(null);
table.setItems(data);
}
}
I don't get any errors. When I change for example to this:
data.add(new ShowData(rs.getString(2), rs.getString(1), rs.getString(3)));
In first column is show the username and in the other two columns nothing.
What is wrong with my code ?
And this is ShowData class-
package javafxapplication7;
public class ShowData {
private final StringProperty id;
private final StringProperty username;
private final StringProperty msg;
public ShowData(String id, String username, String msg) {
this.id = new SimpleStringProperty(id);
this.username = new SimpleStringProperty(username);
this.msg = new SimpleStringProperty(msg);
}
public String getId() {
return id.get();
}
public String getuname() {
return username.get();
}
public String getpass() {
return msg.get();
}
public void setId(String value) {
id.setValue(value);
}
public void setUname(String value) {
username.setValue(value);
}
public void setPass(String value) {
msg.setValue(value);
}
public StringProperty idproper(){
return id;
}
public StringProperty unameproper(){
return username;
}
public StringProperty passproper(){
return msg;
}
}
The methods in the ShowData class do not meet the naming conventions as required by PropertyValueFactory.
Getters include the name of the property with a uppercase first letter.
property methods are named <property>Property(), i.e. in your case:
public String getUname() {
return username.get();
}
public String getPass() {
return msg.get();
}
public StringProperty idProperty(){
return id;
}
public StringProperty unameProperty(){
return username;
}
public StringProperty passProperty(){
return msg;
}
This is why PropertyValueFactory cannot identify the correct methods to use and this is why the cells remain empty.
I'm new to JavaFX and I've been at this code for about 8 hours now and I've become a bit delusional with the code. My two main problems are:
Can't add new items to the TableView using my popUp box display().
Feels messy and unorganized. Any tips for better communication between FXML and Controllers? (Again I'm new so it could be that I've stared too long at it)
My main class
public class Main extends Application {
public static Stage primaryStage;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage window) throws Exception {
try {
primaryStage = new Stage();
window = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("Fissto.fxml"));
Scene scene = new Scene(root);
window.setTitle("Fissto - the File Storage App!");
window.setScene(scene);
window.show();
}catch(Exception e){
e.printStackTrace();
}
// C.setLibraryStage();
}
}
My main Controller class (I have two sub ones that connect in the Fissto.fxml)
public class Controller implements Initializable{
Main main;
#FXML LibraryController libraryController = new LibraryController();
#FXML MergePageController mergePageController = new MergePageController();
private AddImageController addImageController = new AddImageController();
#FXML public void initialize(URL location, ResourceBundle resources){
System.out.println("View is now loaded!");
main = new Main();
libraryController.init(this);
mergePageController.init(this);
addImageController.init(this);
}
//Interface Initialization
public void setMergeStage() throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("Controllers/MergePage.fxml"));
Scene scene = new Scene(root);
main.primaryStage.setScene(scene);
}
public void setLibraryStage() throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("Controllers/LibraryPage.fxml"));
Scene scene = new Scene(root);
main.primaryStage.setScene(scene);
}
//Closing a window
public void closeWindow(){
main.primaryStage.close();
}
}
And finally the controller for the page that holds the TableView
public class LibraryController {
private Controller main;
//Library TableView Controllers
#FXML public TableView<Image> library;
#FXML private TableColumn<Image, String> NameColumn = new TableColumn<>();
#FXML private TableColumn<Image, ArrayList<String>> TagsColumn = new TableColumn<>();
#FXML private TableColumn<Image, String> CommentsColumn = new TableColumn<>();
#FXML private TableColumn<Image, String> FileLocationColumn = new TableColumn<>();
#FXML private TableColumn<Image, Integer> PointsColumn = new TableColumn<>();
public void init(Controller main){
System.out.println("LibraryPage Loading");
this.main = main;
addDataToColumns();
library = new TableView<>();
library.getItems().setAll(getImages());
System.out.println("LibraryPage Loaded");
}
//Initializes the column titles
private void addDataToColumns(){
NameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
TagsColumn.setCellValueFactory(new PropertyValueFactory<>("tags")); //TODO Convert to String format
CommentsColumn.setCellValueFactory(new PropertyValueFactory<>("comments"));
FileLocationColumn.setCellValueFactory(new PropertyValueFactory<>("filelocation"));
PointsColumn.setCellValueFactory(new PropertyValueFactory<>("points"));
}
//Gets all of the images
private ObservableList<Image> getImages() {
//TODO: Add where to actually get the data from
ObservableList<Image> images = FXCollections.observableArrayList();
String s = "Dog, Cat, Jumping Jack,";
ArrayList<String> list = Image.getTagOrganizer(',', s);
images.add(new Image("Test", list, "Comment", "No File Location, yet!", 10));
String k = "Calculus, Complex Numbers, Hard dude,";
ArrayList<String> list2 = Image.getTagOrganizer(',', k);
images.add(new Image("Number2", list2, "I love MathClub", "No File Location, yet!", -10));
return images;
}
This last class is the popup menu that takes in input to put in the GridPane
public class AddImageController {
private Controller main;
public void init(Controller main){
System.out.println("ImagePage Loaded");
this.main = main;
}
//Submitting an image to the library from the AddImagePage
public TextField nameInput;
public TextField tagsInput;
public TextField commentInput;
public TextField pointsInput;
public Label errorMessage;
/** TODO: Make it so that it writes to file then theoretically, the main controller should read from file every so often
* Main functionality for adding the information from the form to the database */
public void submitImage(){
if(!(nameInput.getText().trim().isEmpty()) && !(tagsInput.getText().trim().isEmpty()) && !(pointsInput.getText().trim().isEmpty())) {
if (isInt(pointsInput)) {
// System.out.print("Sent to database, *whoosh!*");
LibraryController c = new LibraryController();
ArrayList<String> s = Image.getTagOrganizer(',', tagsInput.getText());
Image image = new Image(nameInput.getText(), s, commentInput.getText(),"Location Needed", Integer.parseInt(pointsInput.getText()));
c.library.getItems().add(image);
clearInputs();
}
}else {
errorMessage.setText("Fill every field");
}
}
//Clears the input fields in the AddImagePage
public void clearInputs(){
nameInput.clear();
tagsInput.clear();
commentInput.clear();
pointsInput.clear();
errorMessage.setText("");
}
//Submission format verifiers
private boolean isInt(TextField input){
try{
int i = Integer.parseInt(input.getText());
errorMessage.setText("");
return true;
}catch (NumberFormatException e){
System.out.println("Oh no: " + input.getText() + " is not an integer");
errorMessage.setText("Points must be a number");
return false;
}
}
//Image Selection Handler
public void imageSelectionHandler(){
}
}
I understand it may be hard to read, so any feedback on how to make it easier to read in the future is much appreciated.
I have a TableView with three TableColumns. There is an ObservableList named "sensorDataList " in MainApp.java that stores the objects to be shown in the TableView. With the following code, only the first TableColumn named "idColumn" doesn't show the values from the observable list, however, the other two TableColumns works fine.
MainApp.java (this has an "ObservableList" of Sensor objects (see Sensor.java). Also this class has the method named "showSensorDialog()" which loads the .fxml file that has the TableView in question. FYI, this method is invoked by a button in other controller.)
public class MainApp extends Application {
private Stage primaryStage;
private Stage sensorDialogStage;
private ObservableList<sensor> sensorDataList = FXCollections.observableArrayList();
public MainApp(){
sensorDataList.add(new sensor("testText","1 1 0.7", "0 0 1"));
}
public ObservableList<Sensor> getSensorDataList(){return sensorDataList;}
public void showSensorDialog() {
try {
FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("/view/SensorDialog.fxml"));
Object object = loader.load();
sensorDialogStage = new Stage();
Scene scene = new Scene((Parent) object);
sensorDialogStage.setScene(scene);
SensorDialogController controller = loader.getController();
controller.setSensorDialogStage(sensorDialogStage);
controller.setMainApp(this); // this line connects the ObservableList to the TableView.
sensorDialogStage.showAndWait();
} catch (IOException e) {}
}
}
SensorDialogController.java
public class SensorDialogController implements Initializable {
#FXML
private TableView<Sensor> sensorTable;
#FXML
private TableColumn<Sensor, String> idColumn;
#FXML
private TableColumn<Sensor, String> locationColumn;
#FXML
private TableColumn<Sensor, String> directionColumn;
private MainApp mainApp;
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;
sensorTable.setItems(mainApp.getSensorDataList()); // ObservableList and TableView gets connected.
}
#Override
public void initialize(URL url, ResourceBundle rb){
idColumn.setCellValueFactory(new PropertyValueFactory<Sensor, String>("id"));
locationColumn.setCellValueFactory(new PropertyValueFactory<Sensor, String>("location"));
directionColumn.setCellValueFactory(new PropertyValueFactory<Sensor, String>("direction"));
}
}
Sensor.java
public class Sensor{
private SimpleStringProperty id;
private SimpleStringProperty location;
private SimpleStringProperty direction;
public Sensor(String i, String loc, String dir){
this.id = new SimpleStringProperty(i);
this.location = new SimpleStringProperty(loc);
this.direction = new SimpleStringProperty(dir);
}
}