This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information

How to tableview multselect

General questions regarding the development with JavaFX UI for JVx.

How to tableview multselect

Postby wellspinto » Tue Nov 28, 2017 4:11 pm

Hi!

How to make tableview multselect to select rows using ctrl.

I'm using UIInternalFrame with the code and not work.
If i use with Scene and Stage work fine.

Any idea?

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package .tableviewdataselection;

/**
*
* @author Narayan G. Maharjan <me@ngopal.com.np>
*/
public enum Gender {
MALE, FEMALE, OTHER;
}

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package tableviewdataselection;

import javafx.beans.property.*;

/**
*
* @author Narayan G. Maharjan <me@ngopal.com.np>
*/
public class Person {
private final IntegerProperty sn = new SimpleIntegerProperty();

private final StringProperty address = new SimpleStringProperty();

private final StringProperty name = new SimpleStringProperty();

private final StringProperty phone = new SimpleStringProperty();

private final ObjectProperty<Gender> gender = new SimpleObjectProperty<Gender>(Gender.OTHER);

public int getSn() {
return sn.get();
}

public void setSn(int value) {
sn.set(value);
}

public IntegerProperty snProperty() {
return sn;
}

public Gender getGender() {
return gender.get();
}

public void setGender(Gender value) {
gender.set(value);
}

public ObjectProperty genderProperty() {
return gender;
}

public String getPhone() {
return phone.get();
}

public void setPhone(String value) {
phone.set(value);
}

public StringProperty phoneProperty() {
return phone;
}

public String getAddress() {
return address.get();
}

public void setAddress(String value) {
address.set(value);
}

public StringProperty addressProperty() {
return address;
}

public String getName() {
return name.get();
}

public void setName(String value) {
name.set(value);
}

public StringProperty nameProperty() {
return name;
}
}

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package tableviewdataselection;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.*;
import javafx.util.Callback;
import javafx.util.StringConverter;

import java.net.URL;
import java.util.ResourceBundle;

/**
* FXML Controller class
*
* @author Narayan G. Maharjan <me@ngopal.com.np>
*/
public class TableViewDataDemoController {
/**
* For the data transformation
*/
public static DataFormat dataFormat = new DataFormat("mydata");

@FXML
private ToggleGroup selectionGrp;

@FXML
private ComboBox<TableColumn<Person, ?>> colSelect;

@FXML
private RadioButton cellRadio, rowRadio;

@FXML
private ResourceBundle resources;

@FXML
private URL location;

@FXML
private ListView<Integer> listView;

@FXML
private TableColumn<?, String> addressCol;

@FXML
private TableColumn<?, Gender> genderCol;

@FXML
private TableColumn<?, String> nameCol;

@FXML
private TableColumn<?, String> phoneCol;

@FXML
private TableColumn<?, String> snCol;

@FXML
private TableView<Person> tableView;

ObservableList<Integer> selectedIndexes = FXCollections.observableArrayList();

@FXML
void initialize() {
assert addressCol != null : "fx:id=\"addressCol\" was not injected: check your FXML file 'TableViewDataFXML.fxml'.";
assert genderCol != null : "fx:id=\"genderCol\" was not injected: check your FXML file 'TableViewDataFXML.fxml'.";
assert nameCol != null : "fx:id=\"nameCol\" was not injected: check your FXML file 'TableViewDataFXML.fxml'.";
assert phoneCol != null : "fx:id=\"phoneCol\" was not injected: check your FXML file 'TableViewDataFXML.fxml'.";
assert snCol != null : "fx:id=\"snCol\" was not injected: check your FXML file 'TableViewDataFXML.fxml'.";
assert tableView != null : "fx:id=\"tableView\" was not injected: check your FXML file 'TableViewDataFXML.fxml'.";

// changed to multiple selection mode
tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
// set cell value factories
setCellValueFactories();

//set Dummy Data for the TableView
tableView.setItems(getData());

//ListView items bound with selection index property of tableview
listView.setItems(selectedIndexes);

//change listview observable list
tableView.getSelectionModel().getSelectedIndices().addListener(new ListChangeListener<Integer>() {
@Override
public void onChanged(Change<? extends Integer> change) {
selectedIndexes.setAll(change.getList());
}
});

//Setting the items for columns selection
colSelect.setItems(tableView.getColumns());
for (TableColumn c : colSelect.getItems()) {
setCellColumnSelection(c);
}

//add listener and update of selection type
colSelect.valueProperty().addListener(new ChangeListener<TableColumn<Person, ?>>() {
@Override
public void changed(
ObservableValue<? extends TableColumn<Person, ?>> ov,
TableColumn<Person, ?> t,
final TableColumn<Person, ?> t1) {
if (t1 != null) {
if (cellRadio.isSelected()) {
setCellSelection();
}
}

}
});


//For showing the column name properly
colSelect.setConverter(new StringConverter<TableColumn<Person, ?>>() {
@Override
public String toString(TableColumn<Person, ?> t) {
return t.getText();
}

@Override
public TableColumn<Person, ?> fromString(String string) {
for (TableColumn<Person, ?> t : colSelect.getItems()) {
if (t.getText().equals(string)) {
return t;
}
}
return null;
}
});

//the radio buttons change property listener [Row/Cell] selection
selectionGrp.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
@Override
public void changed(
ObservableValue<? extends Toggle> ov, Toggle t, Toggle t1) {
if (t1 == cellRadio) {
setCellSelection();
} else {
setRowSelection();
}

}
});
//Stricting the Column selection
colSelect.disableProperty().bind(cellRadio.selectedProperty().not());

//set the Row Factory of the table
setRowFactory();

//Set row selection as default
setRowSelection();
}

private void setCellValueFactories() {
snCol.setCellValueFactory(new PropertyValueFactory("sn"));
nameCol.setCellValueFactory(new PropertyValueFactory("name"));
genderCol.setCellValueFactory(new PropertyValueFactory("gender"));
phoneCol.setCellValueFactory(new PropertyValueFactory("phone"));
addressCol.setCellValueFactory(new PropertyValueFactory("address"));
}

/**
* Change the cell selection boolean value of TableView
*/
public void setRowSelection() {
tableView.getSelectionModel().clearSelection();
tableView.getSelectionModel().setCellSelectionEnabled(false);
}

/**
* Change the cell selection boolean value of TableView
*/
public void setCellSelection() {
tableView.getSelectionModel().clearSelection();
tableView.getSelectionModel().setCellSelectionEnabled(true);

}

/**
* Set Row Factory for the TableView
*/
public void setRowFactory() {
tableView.setRowFactory(new Callback<TableView<Person>, TableRow<Person>>() {
@Override
public TableRow<Person> call(TableView<Person> p) {
final TableRow<Person> row = new TableRow<Person>();

row.setOnDragEntered(new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent t) {
setSelection(row);
}
});

row.setOnDragDetected(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
if (rowRadio.isSelected()) {
Dragboard db = row.getTableView().startDragAndDrop(TransferMode.COPY);
ClipboardContent content = new ClipboardContent();
content.put(dataFormat, "XData");
db.setContent(content);
setSelection(row);
t.consume();
}
}
});
return row;
}
});
}

/**
* This function helps to make the Cell Factory for specific TableColumn
*
* @param col
*/
public void setCellColumnSelection(final TableColumn col) {
col.setCellFactory(new Callback<TableColumn<Person, ?>, TableCell<Person, ?>>() {
@Override
public TableCell<Person, ?> call(
TableColumn<Person, ?> p) {
final TableCell cell = new TableCell() {
@Override
protected void updateItem(Object t, boolean bln) {
super.updateItem(t, bln);
if (t != null) {
setText(t.toString());
}
}
};

cell.setOnDragEntered(new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent t) {
setSelection(cell, col);
}
});

cell.setOnDragDetected(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
if (cellRadio.isSelected() && colSelect.getValue() == col) {
Dragboard db = cell.getTableView().startDragAndDrop(TransferMode.COPY);
ClipboardContent content = new ClipboardContent();
content.put(dataFormat, "XData");
db.setContent(content);
setSelection(cell, col);
t.consume();
}
}
});
return cell;

}
});
}

/**
* For the changes on table cell selection used only on the TableCell selection mode
*
* @param cell
*/
private void setSelection(IndexedCell cell) {
if (cell.isSelected()) {
System.out.println("False");
tableView.getSelectionModel().clearSelection(cell.getIndex());
} else {
System.out.println("true");
tableView.getSelectionModel().select(cell.getIndex());
}
}

/**
* For the changes on the table row selection used only on TableRow selection mode
*
* @param cell
* @param col
*/
private void setSelection(IndexedCell cell, TableColumn col) {
if (cellRadio.isSelected()) {
if (cell.isSelected()) {
System.out.println("False enter");
tableView.getSelectionModel().clearSelection(cell.getIndex(), col);
} else {
System.out.println("Select");
tableView.getSelectionModel().select(cell.getIndex(), col);
}
}
}

/**
* Provides the Dummy Data for this application in string format
*
* @param length
* @return String
*/
public String getDummyText(int length) {
String most = "abdflntiso";
String alpha = "abcdefghijkmopqrstuvwxyz";
StringBuffer b = new StringBuffer();
int chars = 0;
for (int i = 0; i < length; i++) {
if (chars > 2 && chars > Math.random() * 10) {
b.append(" ");
chars = 0;
continue;
}
if (chars == 0 || i % 2 == 0) {
b.append(most.charAt((int)(Math.random() * most.length())));
} else {
b.append(alpha.charAt((int)(Math.random() * alpha.length())));
}
chars++;
}
return b.toString();
}

/**
* Provides the dummy String
*
* @param length
* @return
*/
public String getDummyDigits(int length) {

StringBuilder b = new StringBuilder();
for (int i = 0; i < length; i++) {
b.append((int)(Math.random() * 9));
}
return b.toString();
}

/**
* Provides the dummy Person data.
*
* @return
*/
public ObservableList<Person> getData() {
String[] names = new String[]{"Narayan", "Phil", "Pablo", "Michael", "Mike", "Timur", "Oszkar", "David"};

ObservableList<Person> persons = FXCollections.observableArrayList();
for (int i = 1; i < 500; i++) {
Person p = new Person();
p.setSn(i);
p.setName(names[(int)(Math.random() * names.length)]);
p.setAddress(getDummyText(15));
p.setPhone(getDummyDigits(9));
p.setGender(Gender.values()[i % 3]);
persons.add(p);
}
return persons;
}
}

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

<?import java.lang.String?>
<?import javafx.collections.FXCollections?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.RadioButton?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.ToggleGroup?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="tableviewdataselection.TableViewDataDemoController">
<children>
<ListView fx:id="listView" prefHeight="342.0" prefWidth="153.0" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="44.0" />
<Label text="Selected Indexes" AnchorPane.rightAnchor="72.0" AnchorPane.topAnchor="22.0">
<font>
<Font name="System Bold" size="12.0" />
</font>
</Label>
<RadioButton id="rowSelect" fx:id="rowRadio" layoutX="21.0" layoutY="16.0" mnemonicParsing="false" selected="true" text="Row Selection">
<toggleGroup>
<ToggleGroup fx:id="selectionGrp" />
</toggleGroup>
</RadioButton>
<RadioButton id="cellSelect" fx:id="cellRadio" layoutX="133.0" layoutY="16.0" mnemonicParsing="false" text="Cell Selection" toggleGroup="$selectionGrp" />
<ComboBox fx:id="colSelect" layoutX="236.0" layoutY="14.0">
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:value="Item 1" />
<String fx:value="Item 2" />
<String fx:value="Item 3" />
</FXCollections>
</items>
</ComboBox>
<TableView fx:id="tableView" layoutX="14.0" layoutY="44.0" prefHeight="342.0" prefWidth="407.0">
<columns>
<TableColumn fx:id="snCol" prefWidth="75.0" text="Sn." />
<TableColumn fx:id="nameCol" prefWidth="75.0" text="Name" />
<TableColumn fx:id="addressCol" prefWidth="75.0" text="Address" />
<TableColumn fx:id="genderCol" prefWidth="75.0" text="Gender" />
<TableColumn fx:id="phoneCol" prefWidth="75.0" text="Phone" />
</columns>
</TableView>
</children>
</AnchorPane>
wellspinto
 
Posts: 10
Joined: Fri Oct 06, 2017 4:59 pm

Re: How to tableview multselect

Postby Support@SIB » Wed Nov 29, 2017 10:21 am

What exactly doesn't work?

We don't answer general JavaFX questions, not related to JVx here.

The UIInternalFrame is a JavaFX node and nothing very special, so what do you think should work and what doesn't?

BTW

Please don't post source code from other developers without license here, because it's a legal problem. We'll remove the source code if you won't fix it.
User avatar
Support@SIB
 
Posts: 243
Joined: Mon Sep 28, 2009 1:56 pm

Re: How to tableview multselect

Postby rzenz » Wed Nov 29, 2017 11:19 am

Okay, before I dive head first into your code, I have a completely different question which we should get out of the way first: Why are you using the UI wrapper classes at all?

From what I can gather you do not seem to be interested in neither the model JVx provides nor the multi-platform capabilities, so why use the UI layer at all? If you want to use the JavaFX MDI solution which we've created, you can simply use the JFXtensions library and remain in pure JavaFX without the need to have a dependency upon JVx.

On another note, your example works flawlessly for me.
User avatar
rzenz
 
Posts: 34
Joined: Mon Dec 12, 2016 1:40 pm
Location: Vienna, Austria

Re: How to tableview multselect

Postby wellspinto » Thu Nov 30, 2017 1:07 pm

The following is:

The routine makes mulselect in the tableview.
I can select an item or several alternate items in the list just by using the ctrl key.

if I make a screen and call directly using scene and stage, everything works perfectly.
but if I use the jvx library it no longer works the selection.
wellspinto
 
Posts: 10
Joined: Fri Oct 06, 2017 4:59 pm

Re: How to tableview multselect

Postby rzenz » Tue Dec 05, 2017 10:01 am

I can only reiterate my previous posting:

  1. Why are you using the UI classes at all when all you want is JavaFX (and therefor the JFXtensions library)?
  2. Your example works for me. So either it is something on your system or, which is much more likely, something in the code surrounding the code you posted.

I'm not sure what else to tell you.
User avatar
rzenz
 
Posts: 34
Joined: Mon Dec 12, 2016 1:40 pm
Location: Vienna, Austria

Re: How to tableview multselect

Postby wellspinto » Tue Dec 05, 2017 4:38 pm

Hi!

I'm send videos to explain the problem:

First video withoutjvx - In this video it presents the code for multselect working perfectly. https://youtu.be/FQVRwhqdenk
Next video withjvx - In this video that has the same programming for mulselect more using the libraries jvx (Not working) https://youtu.be/7Klt1GAQAV0

Just create a tableview and add the following routines:
setRowFactory();
setRowSelection();

Below the multselect routine:
public void setRowFactory() {
table.setRowFactory(p -> {
final TableRow<retClass> row = new TableRow<retClass>();

row.setOnDragEntered(t -> setSelection(row));

row.setOnDragDetected(t -> {
Dragboard db = row.getTableView().startDragAndDrop(TransferMode.COPY);
ClipboardContent content = new ClipboardContent();
content.put(dataFormat, "XData");
db.setContent(content);
setSelection(row);
t.consume();
});
return row;
});
}

public void setRowSelection() {
table.getSelectionModel().clearSelection();
table.getSelectionModel().setCellSelectionEnabled(false);
}

private void setSelection(IndexedCell cell) {
if (cell.isSelected()) {
System.out.println("False");
table.getSelectionModel().clearSelection(cell.getIndex());
} else {
System.out.println("true");
table.getSelectionModel().select(cell.getIndex());
}
}

Here a class retClass:
mport javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;

import java.math.BigDecimal;

public class retClass {
private SimpleIntegerProperty id;
private SimpleStringProperty rgimv;
private SimpleStringProperty end;
private SimpleStringProperty taxa;
private SimpleObjectProperty<BigDecimal> valor;
private SimpleStringProperty Recto;
private SimpleStringProperty Vencto;
private SimpleBooleanProperty tag;

public retClass() {
this.id = new SimpleIntegerProperty(0);
this.rgimv = new SimpleStringProperty(null);
this.end = new SimpleStringProperty(null);
this.taxa = new SimpleStringProperty(null);
this.valor = new SimpleObjectProperty<>(new BigDecimal("0"));
this.Recto = new SimpleStringProperty(null);
this.Vencto = new SimpleStringProperty(null);
this.tag = new SimpleBooleanProperty(false);
}

public retClass(Integer id, String rgimv, String end, String taxa, BigDecimal valor, String Recto, String Vencto, Boolean tag) {
this.id = new SimpleIntegerProperty(id);
this.rgimv = new SimpleStringProperty(rgimv);
this.end = new SimpleStringProperty(end);
this.taxa = new SimpleStringProperty(taxa);
this.valor = new SimpleObjectProperty<>(valor);
this.Recto = new SimpleStringProperty(Recto);
this.Vencto = new SimpleStringProperty(Vencto);
this.tag = new SimpleBooleanProperty(tag);
}

public int getId() { return id.get(); }
public SimpleIntegerProperty idProperty() { return id; }
public void setId(int id) { this.id.set(id); }

public String getRgimv() { return rgimv.get(); }
public SimpleStringProperty rgimvProperty() { return rgimv; }
public void setRgimv(String rgimv) { this.rgimv.set(rgimv); }

public String getEnd() { return end.get(); }
public SimpleStringProperty endProperty() { return end; }
public void setEnd(String end) { this.end.set(end); }

public String getTaxa() { return taxa.get(); }
public SimpleStringProperty taxaProperty() { return taxa; }
public void setTaxa(String taxa) { this.taxa.set(taxa); }

public BigDecimal getValor() { return valor.get(); }
public SimpleObjectProperty<BigDecimal> valorProperty() { return valor; }
public void setValor(BigDecimal valor) { this.valor.set(valor); }

public String getRecto() { return Recto.get(); }
public SimpleStringProperty rectoProperty() { return Recto; }
public void setRecto(String recto) { this.Recto.set(recto); }

public String getVencto() { return Vencto.get(); }
public SimpleStringProperty venctoProperty() { return Vencto; }
public void setVencto(String vencto) { this.Vencto.set(vencto); }

public boolean isTag() { return tag.get(); }
public SimpleBooleanProperty tagProperty() { return tag; }
public void setTag(boolean tag) { this.tag.set(tag); }
}
wellspinto
 
Posts: 10
Joined: Fri Oct 06, 2017 4:59 pm

Re: How to tableview multselect

Postby rzenz » Tue Dec 05, 2017 4:59 pm

I still see myself unable to reproduce this on my end. Could you please package up a complete project with this issue and upload it somewhere so that I can actually have a look at everything that is going on?
User avatar
rzenz
 
Posts: 34
Joined: Mon Dec 12, 2016 1:40 pm
Location: Vienna, Austria


Return to Development