0

I have a Table View pinTable in FXMLand two Table Columns i.e. latColumn, longColumn. I have followed the following method to populate the table :

https://docs.oracle.com/javafx/2/ui_controls/table-view.htm

Snippets are as follows:

FXML Controller Class:

@FXML
public TableView pinTable;
@FXML
public TableColumn latColumn, longColumn;

public final ObservableList<PinList> dataSource = new FXMLCollections.observableArrayList();

@Override
public void initialize(URL url, ResourceBundle rb)
{
    initTable();
}

private void initTable()
{
    latColumn.setCellValueFactory(new PropertyValueFactory<PinList,String>("latPin"));
    longColumn.setCellValueFactory(new PropertyValueFactory<PinList,String>("longPin"));

    pinTable.setItems(dataSource);
}

@FXML
private void addButtonClicked(MouseEvent event)
{
    if(latText.getText().equals(""))
    {
        System.out.println("Lat Empty");
    }
    else if(longText.getText().equals(""))
    {
        System.out.println("Long Empty");
    }
    else
    {
        latVal = Double.parseDouble(latText.getText());
        longVal = Double.parseDouble(longText.getText());

        dataSource.add(new PinList(latText.getText(),longText.getText(),descriptionText.getText()));

        pinTable.getItems().clear();
        pinTable.getItems().addAll(dataSource);

        for(PinList p: dataSource)
        {
            System.out.print(p.getLatPin() + " " + p.getLongPin() + " " + p.getDescriptionPin() + "\n");
        }
    }
}

I have a PinList class which is as follows:

public class PinList 
{
    private final SimpleStringProperty latPin;
    private final SimpleStringProperty longPin;
    private String descriptionPin;

    public PinList(String _latPin, String _longPin, String _descriptionPin)
    {
        this.latPin = new SimpleStringProperty(_latPin);
        this.longPin = new SimpleStringProperty(_longPin);
        this.descriptionPin = _descriptionPin;
    }

    public String getLatPin()
    {
        return latPin.getValue();
    }
    public StringProperty latPinProperty()
    {
        return latPin;
    }


    public String getLongPin()
    {
        return longPin.getValue();
    }
    public StringProperty longPinProperty()
    {
        return longPin;
    }


    public String getDescriptionPin()
    {
        return descriptionPin;
    }
}

All these seem to be fine. But, when I click Add button, nothing happens. No row is created in the table and the println inside the addButtonClicked event handler doesn't execute, or it is executed with no data in the dataSource whatsoever. Any help will be appreciated.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Ishrak
  • 509
  • 1
  • 9
  • 17
  • Are pinTable, latColumn, and longColumn variables in your main class? What is datasource? – TangledUpInBlue Jan 05 '16 at 21:50
  • Why do you have @FXML annotations in your `Application` class? – James_D Jan 05 '16 at 22:11
  • @TangledUpInBlue, `pinTable`, `latColumn` and `longColumn` are FXML components and `dataSource` is an ObservableList. I have edited the question. @James_D, I know that it doesn't make sense. But, I tried putting in the initTable() method everywhere else. But, either I get an exception or nothing happens when I click add button. Only, putting it in the start method seemed to have worked. Hence, Application class. – Ishrak Jan 06 '16 at 06:09
  • 1
    You need to edit the question so the code is complete: no-one can really tell which class is the application class you are executing and which class is the controller. Include enough to demonstrate the problem and reproduce it. – James_D Jan 06 '16 at 14:02
  • @James_D, I have performed the necessary changes according to the answer provided by Uluk Biy. I have also added a heading that shows that this is the FXML Controller Class. – Ishrak Jan 06 '16 at 14:16
  • This is not a [MCVE] though. So I don't really see how you can expect people to be able to help you. No-one here is clairvoyant. There are plenty of strange things in your code (e.g. reloading the entire list instead of just adding an element to it, having a `MouseEvent` as the parameter to a button handler, etc), but without a complete example it's impossible to tell why your code doesn't work. What is the effect of the changes you made? Is the `addButtonClicked` method getting invoked? Do you have any exceptions? – James_D Jan 06 '16 at 14:23
  • @James_D, I am absolutely sorry if my question was of an inappropriate structure. Thank you for the guidance. Please, refer to the answer provided by Uluk Biy in this link: http://stackoverflow.com/questions/11065140/javafx-2-1-tableview-refresh-items . This shows the reloading issue. As for any other strange occurrences, please do let me clarify. And, I would have mentioned if there were any exceptions. – Ishrak Jan 06 '16 at 15:20
  • That question is completely different though, it's about changing the state of existing items in the table, not adding new ones. Is your `addButtonClicked` method getting called? – James_D Jan 06 '16 at 15:25
  • Can you please take the trouble to clarify the difference? Because, from the perspective I viewed it from, adding a new item will technically be the same as changing the state of existing items (i.e. increasing the count and displaying the new item). If this is wrong, please show the correct way. – Ishrak Jan 06 '16 at 15:28
  • Uh, wait. Actually, that code is the problem. – James_D Jan 06 '16 at 15:32

2 Answers2

2

The problem is you confused the Application class with your FXML controller class. Even though this FXML class extends Application the overridden start() method is not being invoked anywhere in your code. Put some printlns to verify this. The FXML controller class can optionally have a initialize() (and additionally can implement Initializable but not mandatory). This method will be invoked by FXMLLoader after the fxml file is loaded by it. So the correct code should be:

public void initialize( URL url, ResourceBundle rb ) {
    initTable();
}

and delete start() method and remove extending from Application.

Uluk Biy
  • 48,655
  • 13
  • 146
  • 153
  • I have tried exactly that but to no avail. Previously, when I had `initTable()` inside the start method, there would be an empty row created after clicking the add button. But, now as I have inserted `initTable()` inside the initialize method, nothing happens when I click the add button, not even the println that I did inside the `addButtonClicked` event handler. I had previously tried this and got the same result. – Ishrak Jan 06 '16 at 13:39
1

In your initTable() method you do

pinTable.setItems(dataSource);

So now the list held internally by pinTable in its items property is the very same list as dataSource (they are the identical by reference).

Now in your event handler method you do

dataSource.add(new PinList(...));

which adds a new item to dataSource (which is the same list as the table's items)

and then

pinTable.getItems().clear();

which removes all elements from the table's items list. So the table's items list is now empty (has no elements). Of course, since this is the very same list as dataSource, you have also removed all items from dataSource: it is the same (now empty) list as pinTable.getItems().

and now you do

pinTable.getItems().addAll(dataSource);

which copies all the items in dataSource (there are none) into pinTable.getItems() (which is the same list). So this actually duplicates all items in the list, but since you emptied the list, you still have an empty list.

Just remove the lines

pinTable.getItems().clear();
pinTable.getItems().addAll(dataSource);

All you want here is:

@FXML
private void addButtonClicked(MouseEvent event) 
{
    if(latText.getText().equals(""))
    {
        System.out.println("Lat Empty");
    }
    else if(longText.getText().equals(""))
    {
        System.out.println("Long Empty");
    }
    else
    {
        latVal = Double.parseDouble(latText.getText());
        longVal = Double.parseDouble(longText.getText());

        dataSource.add(new PinList(latText.getText(),longText.getText(),descriptionText.getText()));

        for(PinList p: dataSource)
        {
            System.out.print(p.getLatPin() + " " + p.getLongPin() + " " + p.getDescriptionPin() + "\n");
        }
    }
}
James_D
  • 201,275
  • 16
  • 291
  • 322