How to select and retrieve column with checkbox control with javafx - java

In my Javafx2 application I have a TableView in which I want to have CheckBoxes to select one or many column.
I find many answer to make an entire column dedicated for checkbox by row, but in my case, i want to add a checkbox for each column label in order to select only the column checked when the user clic on a button for computate a row.
I see there is a javafx.scene.control.cell.CheckBoxTableCell<S,T> but i can i use it for tableview column selection ?
Is it possible ?
Update 1 :
Thanks to #amru, it's possible to add Node into header of TableColumn object.
So i have another question, what is the best way to retrieve indexes of all selected column ? As far as I'm concerned, i search also in javafx api

This code will put a checkbox in the column header.
column.setGraphic(new CheckBox());
UPDATED:
Set the checkbox's user data with the column. You can retrieve it later when user ticked the checkbox.
EventHandler<ActionEvent> handler = new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
CheckBox cb = (CheckBox) event.getSource();
TableColumn column = (TableColumn) cb.getUserData();
if (cb.isSelected()) {
lstClm.add(column);
} else {
lstClm.remove(column);
}
for (TableColumn clm : lstClm) {
System.out.println("selected column: " + clm.getText());
}
}
};
CheckBox cb = new CheckBox();
cb.setUserData(firstDataColumn);
cb.setOnAction(handler);
firstDataColumn.setGraphic(cb);
cb = new CheckBox();
cb.setUserData(secondDataColumn);
cb.setOnAction(handler);
secondDataColumn.setGraphic(cb);

Related

DefaultTableModel addRow method adds row in format: column_name = column_value instead of just column_value

I am experiencing a issue while trying to add new row in my JTable. My JTable is using DefaultTableModel, here is the code I use for adding a new row:
AddDialog diag = new AddDialog(MainWindow.getInstance(),"Add Entity",true,tab);
diag.setVisible(true);
if(diag.isSaved()) {
entity = diag.getEntity();
table = diag.getTableModel();
table.getEntities().add(entity);
if(tab instanceof TablePreview) {
tablePreview = (TablePreview)tab;
tableModel = (DefaultTableModel) (tablePreview.getTableView().getModel());
Object[] newRow = new Object[entity.getAttributes().size()];
int i=0;
for (Entry<String, Object> entry : entity.getAttributes().entrySet()) {
newRow[i++]=entry;
}
tableModel.addRow(newRow);
}else if(tab instanceof ChildTablePreview) {
System.out.println("Tab is instanceof ChildTablePreview");
}
}else {
System.out.println("Entity not saved!");
}
diag is instance of AddDialog which extends JDialog, and when I fill in the fields of the dialog and click save it creates an Entity class which I want to add to the table as a new row. The logic works fine, but when the row gets inserted into the table, for some reason table looks like this:
If anyone has any idea how I can fix this, I would really appreciate the help!
You need to use a custom cell renderer in your JTable.
How data appears is based on the class of the columns. The default renderer simply calls the .toString() function for the objects in the column. If the column contains a key value pair, its common for these to appear as key=value.
You need to set the renderer using the TableColumn method setCellRenderer. You can define this renderer to only display the value for the objects in that column.

vaadin8.1.0 Grid with Checkbox had an Issue

I am working with vaadin 8.1.0 grid. I need to insert checkbox as a column and also as column header. when I click checkbox in column header, all column checkbox should be checked. That is working fine. But the problem is if I have 100 rows, when I Check header checkbox only some column checkboxes are checked i.e, only the rows that are displayed. When I scrolldown the remaining rows checkboxes are not checked. Here is my code:
List<Person> people = new ArrayList();
for (int i = 0; i < 1000; i++) {
people.add(i, new Person("Galileo Galilei", 1564));
}
CheckBox CheckBox1 = new CheckBox("All");
CheckBox1.setValue(false);
Grid<Person> grid = new Grid<>();
grid.setItems( people);
grid.addColumn(Person::getName).setCaption("Name");
grid.addColumn(Person::getYear).setCaption("Year of birth").setId("1");
grid.addComponentColumn(Person -> {
CheckBox chk=new CheckBox("Chk 2");
CheckBox1.addValueChangeListener(e->
chk.setValue(CheckBox1.getValue())
);
return chk;
}).setCaption("ch2").setId("CH2");
grid.getHeaderRow(0).getCell("CH2").setComponent( CheckBox1);
Well, for performance reasons, not all of the checkboxes are rendered from the start, as you'll see in the GIF below (right side, items flashing in violet), just the ones currently visible. And when you scroll, new items will be replacing the old ones, and checkboxes will be drawn for them. However their initial state will be uncheked, so the simplest solution is to set its initial state to the one of the master checkbox: CheckBox chk = new CheckBox("Chk 2", CheckBox1.getValue());.
Result:
Furthermore, looking at the code you might have a minor leak. Since the checkboxes are drawn each time you scroll a larger section, the code in grid.addComponentColumn will be called each time, and value change listeners will be added to the list on and on and on... because they're never unregistered. Take a look at the image below, after a few scrolls, I ended up with over 9000 of them:
To overcome this, you can un-register the listeners when the checkboxes are detached:
grid.addComponentColumn(Person -> {
CheckBox chk = new CheckBox("Chk 2", CheckBox1.getValue());
// save the registration info to unregister at a later time
Registration listenerRegistration = CheckBox1.addValueChangeListener(e -> chk.setValue(CheckBox1.getValue()));
// when the checkbox is detached, remove the listener
chk.addDetachListener(event -> listenerRegistration.remove());
return chk;
}).setCaption("ch2").setId("CH2");
Now the list contains just those who were not yet detached:
You could also extend data model by a boolean field "selected" or wrap it into a new class and there add the "selected" field. Then set/unset that field in the ValueChangeListener added to the CheckBox.
This will also take care of selecting all grid entries and not just the one rendered. You will just have to change "selected" in all you data model instances.
Another approach would be to use the ImageRenderer. Then you wouldn't have to deal with any listeners.
This assumes that your model has an attribute to hold the value of checked/selected.
ThemeResource resourceChecked = new ThemeResource("selected.gif");
ThemeResource resourceUnchecked = new ThemeResource("deselected.gif");
grid.addColumn(person -> person.getSelected() ? resourceChecked : resourceUnchecked,
new ImageRenderer<>(event -> {
Person person = event.getItem();
person.setSelected(!person.getSelected());
grid.getDataProvider().refreshItem(person);
grid.markAsDirty();
}));

JTable change view but not change row selection after filter data

When data filtered table row was change view according to result but when I select row then table select always first row of column not filtered row but I want both things filter row and same row selection please solve me problem.
jTextField2.addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent ke){
trs.setRowFilter(RowFilter.regexFilter("(?i)"+jTextField2.getText(),0));
}
});
tm = (TableModel)table.getModel();
trs = new TableRowSorter(tm);
table.setRowSorter(trs);
Thanks!
ANSWER IS FOR FORMATTED CODE PURPOSE
int modelRow = table.convertRowIndexToModel(table.getSelectedRow());
DefaultTableModel model = (DefaultTableModel) table.getModel();
name=model.getValueAt(index,0).toString();
sale.setVisible(true);
sale.pack();
sale.setLocationRelativeTo(null);
sale.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
sale.jTextField5.setText(name);
dispose();
so this code is not working for you in your mouse event? does the mouse event get triggered? could you edit your question and add more code (if possible all)?

How to delete row from table column javafx

These are my table columns Course and Description. If one clicks on a row (the row becomes 'active'/highlighted), and they press the Delete button it should remove that row, how do I do this?
The code for my Course column: (and what event listener do I add to my delete button?)
#SuppressWarnings("rawtypes")
TableColumn courseCol = new TableColumn("Course");
courseCol.setMinWidth(300);
courseCol.setCellValueFactory(new PropertyValueFactory<Courses, String>("firstName"));
final Button deleteButton = new Button("Delete");
deleteButton.setOnAction(.....
Just remove the selected item from the table view's items list. If you have
TableView<MyDataType> table = new TableView<>();
then you do
deleteButton.setOnAction(e -> {
MyDataType selectedItem = table.getSelectionModel().getSelectedItem();
table.getItems().remove(selectedItem);
});
If someone want to remove multiple rows at once, there is similar solution to accepted:
First we need to change SelectionMethod in our table to allow multiple selection:
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
After this, we need to set action with such code for button:
ObservableList<SomeField> selectedRows = table.getSelectionModel().getSelectedItems();
// we don't want to iterate on same collection on with we remove items
ArrayList<SomeField> rows = new ArrayList<>(selectedRows);
rows.forEach(row -> table.getItems().remove(row));
We could call removeAll method instead of remove(also without creating new collection), but such solution will remove not only selected items, but also their duplicates if they exists and were not selected. If you don't allow duplicates in table, you can simply call removeAll with selectedRows as parameter.

JavaFX: Get the selected row cell's text

I need your help.
I am developing JavaFX project that deals with table view and forms.
My Problem is I can't get the text of the selected row in the table view.
I want to get the row cell's text using the row index or the selected row one.
Here is my code:
myTableView.getSelectionModel().selectedItemProperty().addListener( new ChangeListener() {
#Override
public void changed(ObservableValue ov, Object t, Object t1) {
TableView.TableViewSelectionModel selectionModel = myTableView.getSelectionModel();
ObservableList selectedCells = selectionModel.getSelectedCells();
TablePosition tablePosition = (TablePosition) selectedCells.get(0);
int rowIndex = tablePosition.getRow(); // yields the row that the currently selected cell is in
// I Want to get the cell's text in the row using the row_index or the selected row one
}
});
Any solution is appreciated. Thank you!
If you only care about which row is selected, assuming you have a TableView<SomeObject>, you can simply use:
List<SomeObject> selected = selectionModel.getSelectedItems();
or if your table only allows single row selection:
SomeObject selected = selectionModel.getSelectedItem();

Categories