0

I have a TableView, dataTable, that contains five columns. I want to sort the rows based on the TableColumn scoreColumn, which is of type Integer. The user is able to do this by clicking on the arrow of the scoreColumn header, but I'd like to have the data sorted in descending order by default.

The table's records are all loaded at the same time and are not updatable, so I don't have to worry about the order changing so the sort only needs to be performed once.

Here is the method that initializes dataTable with the data, as well as the TableView and TableColumn declarations:

...

@FXML
private TableView<Data> dataTable;

@FXML
private TableColumn<Data, TextFlow> foundPeptideColumn;
@FXML
private TableColumn<Data, String> targetPeptideColumn;
@FXML
private TableColumn<Data, Integer> scoreColumn;
@FXML
private TableColumn<Data, Integer> rowColumn;
@FXML
private TableColumn<Data, Integer> peptideNumColumn;

...

@FXML
private void initialize()
{
    // Initialize the data table with the five columns.
    foundPeptideColumn.setCellValueFactory(cellData -> cellData.getValue().foundPeptideProperty());
    targetPeptideColumn.setCellValueFactory(cellData -> cellData.getValue().peptideProperty());
    scoreColumn.setCellValueFactory(cellData -> cellData.getValue().scoreProperty().asObject());
    rowColumn.setCellValueFactory(cellData -> cellData.getValue().rowProperty().asObject());
    peptideNumColumn.setCellValueFactory(cellData -> cellData.getValue().peptideNumProperty().asObject());
}

...

...and here is the FXML file that has the TableView:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="700.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="app.address.view.AppOverviewController">
   <children>
      <TableView fx:id="dataTable" layoutX="556.0" layoutY="192.0" prefHeight="700.0" prefWidth="1000.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="50.0">
        <columns>
          <TableColumn fx:id="foundPeptideColumn" maxWidth="-1.0" minWidth="275.0" prefWidth="275.0" text="Found Peptide" />
          <TableColumn fx:id="targetPeptideColumn" maxWidth="-1.0" minWidth="275.0" prefWidth="275.0" text="Target Peptide" />
            <TableColumn fx:id="scoreColumn" maxWidth="-1.0" minWidth="150.0" prefWidth="150.0" sortType="DESCENDING" text="Score" />
            <TableColumn fx:id="rowColumn" maxWidth="-1.0" minWidth="150.0" prefWidth="150.0" text="Row" />
            <TableColumn fx:id="peptideNumColumn" maxWidth="-1.0" minWidth="150.0" prefWidth="150.0" text="Peptide #" />
        </columns>
         <columnResizePolicy>
            <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
         </columnResizePolicy>
      </TableView>
      <TextField fx:id="peptideField" layoutX="113.0" layoutY="14.0" />
      <Label layoutX="14.0" layoutY="19.0" text="Enter peptide:" />
      <Button layoutX="294.0" layoutY="14.0" mnemonicParsing="false" onAction="#handleSearch" text="Search" />
      <Button layoutX="370.0" layoutY="14.0" mnemonicParsing="false" onAction="#handleClearTable" text="Clear Table" />
   </children>
</AnchorPane>

Things I have tried:

@FXML
private void initialize()
{
    scoreColumn.setSortType(TableColumn.SortType.DESCENDING);
    dataTable.getSortOrder().add(scoreColumn);

    // Initialize the data table with the five columns.
    foundPeptideColumn.setCellValueFactory(cellData -> cellData.getValue().foundPeptideProperty());
    targetPeptideColumn.setCellValueFactory(cellData -> cellData.getValue().peptideProperty());
    scoreColumn.setCellValueFactory(cellData -> cellData.getValue().scoreProperty().asObject());
    rowColumn.setCellValueFactory(cellData -> cellData.getValue().rowProperty().asObject());
    peptideNumColumn.setCellValueFactory(cellData -> cellData.getValue().peptideNumProperty().asObject());

    dataTable.sort();
}

(Based on the answer from this question: Sort TableView by certain column Javafx)

@FXML
private void initialize()
{
    scoreColumn.setSortType(TableColumn.SortType.DESCENDING);;

    // Initialize the data table with the five columns.
    foundPeptideColumn.setCellValueFactory(cellData -> cellData.getValue().foundPeptideProperty());
    targetPeptideColumn.setCellValueFactory(cellData -> cellData.getValue().peptideProperty());
    scoreColumn.setCellValueFactory(cellData -> cellData.getValue().scoreProperty().asObject());
    rowColumn.setCellValueFactory(cellData -> cellData.getValue().rowProperty().asObject());
    peptideNumColumn.setCellValueFactory(cellData -> cellData.getValue().peptideNumProperty().asObject());

    dataTable.getColumns().addAll(scoreColumn);
    dataTable.getSortOrder().add(scoreColumn);
    dataTable.sort();
}

(Based on the answer from this question: JavaFX: TableView: Arrow for a column sorted by default)

I have also tried a handful of other things similar to the above examples (mostly playing with a combination of the placement/order/combination of the above attempted fixes), all to no avail.

Is there anything else I should try, either programically, in FXML, or in SceneBuilder, to automatically sort the table based on the scoreColumn?

I can update my post with an image of my application or add additional code for my controllers, if that would be helpful.

2 Answers2

0

Are you using a SortedList as the basis for the table items? https://openjfx.io/javadoc/11/javafx.base/javafx/collections/transformation/SortedList.html

See the "Sorting" section at https://openjfx.io/javadoc/11/javafx.controls/javafx/scene/control/TableView.html

swpalmer
  • 2,118
  • 17
  • 23
0

(Based on the answer from this question: JavaFX: TableView: Arrow for a column sorted by default)

I had the same problem and I used the answer of the link.

You have to insert this portion of the code after you fill the data into the table.

dataTable.getColumns().addAll(scoreColumn);
dataTable.getSortOrder().add(scoreColumn);
dataTable.sort();

It worked for me.

Pedro
  • 151
  • 2
  • 7