2
votes

I'm new in JavaFX and have the following issue:

I have a tableview inside a BorderPane. I want it to focus on the last row/1st column when it's loaded. I have tried the following:

  • requestfocus()
  • scrollTo()
  • focusModel.focus()
  • selectionModel.select()

What happens is that the cell I want is indeed blue (as if it was selected) but the first cell has a blue border. So, when I try to use the arrow keys, the selected cell moves to the first row.

BTW, I'm using TornadoFX.

Any ideas?

Thanks in advance!

class CashflowTab : View() {
    override val root: HBox by fxml()
    private val mController : CashflowController by inject()
    private val mainView : MainView by inject()

    // Get the buttons
    private val buttonCashflow : Button by fxid("btnCashflow")

    init {
        // Setup the buttons
        buttonCashflow.action {
            setupCashflowTable()
        }
    }

    /** Displays the TableView for the Cashflow */
    private fun setupCashflowTable() {
        var initialFocus = true
        // List of entries for the category ComboBox
        val categoryList = mController.getCashFlowCategoryList()


        // Create the table
        val cashTable = tableview<CashEntry>(mController.getCashEntryList()) {
            isEditable = true
            column(Constants.COL_COUNT, CashEntry::countProperty)
            column(Constants.COL_DATE, CashEntry::dateProperty).makeEditable(LocaleDateConverter())
            column(Constants.COL_INCOME, CashEntry::incomeProperty).makeEditable(CurrencyConverter())
            column(Constants.COL_EXPENSES, CashEntry::expensesProperty).makeEditable(CurrencyConverter())
            column(Constants.COL_PROFIT, CashEntry::profitProperty).converter(CurrencyConverter())
            column(Constants.COL_TOTAL_PROFIT, CashEntry::totalProfitProperty).converter(CurrencyConverter())
            column(Constants.COL_COMMENTS, CashEntry::commentsProperty).makeEditable()
            column(Constants.COL_CATEGORY, CashEntry::categoryProperty).useComboBox(categoryList)

            // Scroll to and focus on the last cell on startup
            if (initialFocus) {
                val lastRow = mController.getCashEntryList().size - 1
                requestFocus()
                scrollTo(lastRow)
                focusModel.focus(lastRow)
                selectionModel.select(lastRow)
                initialFocus = false
            }

            onEditCommit {entry ->
                // Update the list
                mController.updateCashEntryList(entry)

                // Move to the next cell
                requestFocus()
                focusModel.focusRightCell()
                @Suppress("UNCHECKED_CAST")
                selectionModel.select(focusModel.focusedCell.row, focusModel.focusedCell.tableColumn as TableColumn<CashEntry, *>)
            }
            enableCellEditing()

            // Enable edit on key typed
            addEventHandler(KeyEvent.KEY_PRESSED) {keyEvent ->
                if (keyEvent.code.isDigitKey || keyEvent.code.isLetterKey) {
                    if (editingCell == null) {
                        val currentSelectedCell = selectedCell
                        if (currentSelectedCell != null && currentSelectedCell.tableColumn.isEditable) {
                            edit(currentSelectedCell.row, currentSelectedCell.tableColumn)
                        }
                    }
                }
            }
        }

        // Add the table to the view
        mainView.root.center = cashTable
        cashTable.tableMenuButtonVisibleProperty()

        // Ensure no other node can get focus
        cashTable.focusedProperty().onChange {
            val focusOwner = currentStage?.scene?.focusOwnerProperty()?.value

            // Check if the focus owner is the table or a cell
            if (focusOwner !is TableView<*> && focusOwner !is TextField) {
                cashTable.requestFocus()
            }
        }
    }
}
1
Why don't you use EditText instead whenever you don't need cursor on it you can simply add android:focusabe=false - Sai Jayant
This is not on android. If it was, I would have gone for an EditText in a RecyclerView. It's for a windows app. Thanks though - John Magdalinos

1 Answers

0
votes

You should use

Platform.runLater(() -> {
    requestFocus();
    scrollTo(lastRow);
    ...
});

to update the GUI.