I'm developing a small game that has a highscore list displayed by a javafx TableView. I've created a subclass HighscoreTableView extends TableView which is a TableView node that automatically creates the TableColumns I need and fills them with data on construction.
I want that table to be sorted by a default column on initialisation. I've added the following code lines:
duration.setSortType(TableColumn.SortType.DESCENDING);
this.getSortOrder().add(duration);
duration.setSortable(true);
this.sort();
where duration is the TableColumn that should define the sorting. Of course, it's added to the TableView. But when I create a new instance of that HighscoreTableView, it remains unsorted by default, until the user clicks on one of the column headers. This is unexpected, since this question, this question and this question say it should work that way. Any ideas?
Further information for reproduction:
The HighscoreTableView class is used by a HighscoreStage extends Stage class, which contains a TabPane with four Tabs. Each Tab contains a HighscoreTableView with different data taken from a static Data object. The data model is a class HighscoreEntry, an ObservableList of them gets added to the HighscoreTableViews. My full code is available here.
You are calling sort() before any data is loaded. Instead you should call it each time after adding/changing data to the table view.
Also you can use SortedList with appropriate comparator to wrap your original backing list. Than all changes will be automatically propagated to view.
Related
I defined a paste method in a controller class, based on the solution given here: How to copy/paste table cells in a TableView. Everything went well, except for one detail: some cells where data is pasted have events that should be triggered but are not.
For example:
public class MyController {
private TableColumn<MyBean, String> valueColumn;
...
valueColumn.setOnEditCommit(e -> doSomeStuff(e));
private void doSomeStuff(CellEditEvent<MyBean, String> event) {
...
}
In this example, after user hits ENTER, the doSomeStuff method is called, which is expected behavior.
The problem with the paste method I implemented is that it does not affect the cell, only its content (its ObservableValue). This means of course that after data is pasted, no event is triggered.
My question : is there a way to trigger the same event, or a similar one that will call my doSomeStuff method after pasting data?
Table View doesn't work as you think. If you want to have a fully customizable structure, use a grid pane. It is hard to create one, but after you make it look like a table, you have many more options to customize.
I did that I a recent project where I was needed to insert a table inside a cell. It was much more easier with a gridpane and textfields.
I have a JTable. One column in the JTable is assigned an extended TableCellEditor that displays an extended JComboBox.
There is a fixed list of 100 String objects that populates the comboboxes.
The challenge:
Design the JComboBoxes so that any selection is unique relative to other boxes? That is, if "A" is slected from the combobox in the first row, it is automatically removed from the list of each other combobox.
When a new room is added to the table, the combobox it contains should auto-populate to the first available list item.
The problem:
My comboboxes work beautifully. I can select items at will. I even have made some progress in eliminating already used items from the lists. But I can't figure out how to correctly auto-populate.
I am very confused because it appears that my combobox constructor is only called once when the table is created, not once for each row.
Is this the case? Is the constructor for a TableCellEditor only called once ever? If so, how do I modify the behavior of each combobox as it come into existence?
Thanks for your help!
If you would like specific code, please let me know. I don't know if you want me to paste in the whole classes.
When a new room is added to the table, the combobox it contains should auto-populate to the first available list item.
When you add a new row of data to the TableModel you must add the values of all columns in the row. This should not be a function of the editor. The editor allows you to change values in the cell.
I was able to get around my problem by creating an abstract superclass for my combobox that can be accessed from the tablemodel extension when it sets up its data.
I have a list of items that are pulled from a database, it combines the various fields with a rs.getString method to create a longer string of items, this is done in an action button method.
I would like to be able to click on an item in this list and have one of the fields display as text in a textbox, so this needs to be done through the list selection event method where I instruct the program to set the text to my desired value.
My problem is, I am not sure of the logic to follow in order to specify how to retrieve that fields information that will be corresponding to the item that is selected in the list, can you give me any ideas?
Rather the combining the fields into a single String, create a POJO (Plain Old Java Object), which provides getters (and possible setters) for the fields you want and these objects to the ListModel
Use a ListCellRenderer to customise the way which the JList renders the POJO the way you want to. See Writing a Custom Cell Renderer for more details.
When the user selects an item from the list, use JList#getSelectedValue and cast to the same class as your POJO. You can now use the POJO's getters to extract the properties you want to display.
The idea is to generate a self contained unit of work, which, based on what you want to do, you can customise how the object is displayed.
This concept is a corner stone to the separation of data (model) and the UI (view) behind the Model-View-Controller paradigm and OOP generally...
I'm trying to convert a drop down box widget into a SuggestionBox because the current drop down menu has 100+ choices. It seems like you can only add String suggestions to a SuggestOracle though. I need to be able to add a custom object that contains both a description and an ID that matches the record to the database though. Would I have to extend the SuggestOracle class?
Yes as i know you can not use pair of values i.e Id and Value. You have to add your strings in suggestion box perhaps you can use different solution other then suggestion box i.e. Create a List of values popup. And add as many fields as you like. display your data in flex table with pagination. update your form with the selected row by using selecition handler. for reference how to use FlexTable and handle events please see able Single Row Click Event
SuggestOracle is the parent class of MultiWordSuggestOracle which you are already yousing.
public class MultiWordSuggestOracle extends SuggestOracle
see MultiWordSuggestOracle
I have a JTable that I want to use to display some data (a String and a Boolean in each row). The data is maintained by my own class. Is there some way to bind the data model to the JTable, so that when I add to the model, the JTable is dynamically updated and when I remove something from the model, the row is removed from the JTable?
I have previously worked with Flex and Actionscript, and this is very easy to do there with data binding, so I'm just wondering how it's done in Java.
Thanks.
You will need to have your dataset implement the TableModel interface. if you do that then you can apply it to the JTable. If you extend AbstractTableModel you will inherit some event firing methods that your table will handle and will update the view. see this tutorial. Note that the default implementation of JTable will renderer your data for you, and if a Boolean is found, it will show up as a check box.
You'll probably find both the Java JTable tutorial and the JTable API documentation helpful in understanding how JTable works, but otherwise here's a quick rundown.
The premise of a JTable is that it is paired with an object that implements the TableModel interface, which by default is an instance of DefaultTableModel. The table model object is made up of a list of columns, each of which has its own data type (String and Boolean in your case), and a list of rows containing the actual data for the table.
Whenever the JTable is drawn by the swing drawing code, it repeatedly calls the method:
public Object getValueAt(int row, int col)
Thus, when you add data to the table model, it is always rendered as you expect in the next screen refresh (dynamically).
The only thing you really need to worry about, then, is getting the data from your object into the table model and back out again. Other than that, JTable takes care off all the heavy lifting.
While implementing TableModel is easy enough for simple cases, you might want to consider a true binding approach (my favorite is Glazed Lists - watch the 30 second video on how easy this is and you'll be won over). Beans Binding (now Better Beans Binding) also has an implementation of observable lists that might be useful (although I much prefer the Glazed Lists approach)