├── .gitignore
├── docs
├── README.md
└── output.png
├── pom.xml
└── src
└── main
├── java
└── np
│ └── com
│ └── ngopal
│ └── tableviewdataselection
│ ├── Gender.java
│ ├── Person.java
│ ├── TableViewDataDemoController.java
│ └── TableViewDataSelection.java
└── resources
└── fxml
└── TableViewDataFXML.fxml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Maven template
3 | target/
4 | pom.xml.tag
5 | pom.xml.releaseBackup
6 | pom.xml.versionsBackup
7 | pom.xml.next
8 | release.properties
9 | dependency-reduced-pom.xml
10 | buildNumber.properties
11 | .mvn/timing.properties
12 | # https://github.com/takari/maven-wrapper#usage-without-binary-jar
13 | .mvn/wrapper/maven-wrapper.jar
14 | target/
15 | nb*.xml
16 | *.iml
17 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # JavaFX TableView Data Selection
2 |
3 | This project is for doing the selection based upon the columns and row and show the index data of it.
4 |
5 | ### Requirement
6 | - JavaFX 14
7 |
8 | ### Usage
9 | ```shell script
10 | mvn clean javafx:run
11 | ```
12 |
13 | #### Output
14 | 
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/docs/output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/privatejava/javafx-tableview-data-selection/e6faff47e583249ce24c20917bacdca0ca35c682/docs/output.png
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | np.com.ngopal
7 | javafx-tableview-data-selection
8 | 1.0-SNAPSHOT
9 | jar
10 |
11 | javafx-tableview-data-selection
12 |
13 |
14 | 14
15 | 14
16 | UTF-8
17 | np.com.ngopal.tableviewdataselection.MainApp
18 |
19 |
20 |
21 |
22 | org.openjfx
23 | javafx-controls
24 | 14
25 |
26 |
27 |
28 | org.openjfx
29 | javafx-fxml
30 | 14
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | org.openjfx
39 | javafx-maven-plugin
40 | 0.0.4
41 |
42 | 14
43 | 14
44 | 14
45 | np.com.ngopal.tableviewdataselection.TableViewDataSelection
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/src/main/java/np/com/ngopal/tableviewdataselection/Gender.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this template, choose Tools | Templates
3 | * and open the template in the editor.
4 | */
5 | package np.com.ngopal.tableviewdataselection;
6 |
7 | /**
8 | *
9 | * @author Narayan G. Maharjan
10 | */
11 | public enum Gender {
12 | MALE, FEMALE, OTHER;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/np/com/ngopal/tableviewdataselection/Person.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this template, choose Tools | Templates
3 | * and open the template in the editor.
4 | */
5 | package np.com.ngopal.tableviewdataselection;
6 |
7 | import javafx.beans.property.*;
8 |
9 | /**
10 | *
11 | * @author Narayan G. Maharjan
12 | */
13 | public class Person {
14 | private final IntegerProperty sn = new SimpleIntegerProperty();
15 |
16 | private final StringProperty address = new SimpleStringProperty();
17 |
18 | private final StringProperty name = new SimpleStringProperty();
19 |
20 | private final StringProperty phone = new SimpleStringProperty();
21 |
22 | private final ObjectProperty gender = new SimpleObjectProperty(Gender.OTHER);
23 |
24 | public int getSn() {
25 | return sn.get();
26 | }
27 |
28 | public void setSn(int value) {
29 | sn.set(value);
30 | }
31 |
32 | public IntegerProperty snProperty() {
33 | return sn;
34 | }
35 |
36 | public Gender getGender() {
37 | return gender.get();
38 | }
39 |
40 | public void setGender(Gender value) {
41 | gender.set(value);
42 | }
43 |
44 | public ObjectProperty genderProperty() {
45 | return gender;
46 | }
47 |
48 | public String getPhone() {
49 | return phone.get();
50 | }
51 |
52 | public void setPhone(String value) {
53 | phone.set(value);
54 | }
55 |
56 | public StringProperty phoneProperty() {
57 | return phone;
58 | }
59 |
60 | public String getAddress() {
61 | return address.get();
62 | }
63 |
64 | public void setAddress(String value) {
65 | address.set(value);
66 | }
67 |
68 | public StringProperty addressProperty() {
69 | return address;
70 | }
71 |
72 | public String getName() {
73 | return name.get();
74 | }
75 |
76 | public void setName(String value) {
77 | name.set(value);
78 | }
79 |
80 | public StringProperty nameProperty() {
81 | return name;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/main/java/np/com/ngopal/tableviewdataselection/TableViewDataDemoController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this template, choose Tools | Templates
3 | * and open the template in the editor.
4 | */
5 | package np.com.ngopal.tableviewdataselection;
6 |
7 | import java.net.URL;
8 | import java.util.ResourceBundle;
9 | import javafx.beans.value.ChangeListener;
10 | import javafx.beans.value.ObservableValue;
11 | import javafx.collections.FXCollections;
12 | import javafx.collections.ListChangeListener;
13 | import javafx.collections.ListChangeListener.Change;
14 | import javafx.collections.ObservableList;
15 | import javafx.event.EventHandler;
16 | import javafx.fxml.FXML;
17 | import javafx.scene.control.*;
18 | import javafx.scene.control.cell.PropertyValueFactory;
19 | import javafx.scene.input.*;
20 | import javafx.util.Callback;
21 | import javafx.util.StringConverter;
22 |
23 | /**
24 | * FXML Controller class
25 | *
26 | * @author Narayan G. Maharjan
27 | */
28 | public class TableViewDataDemoController {
29 | /**
30 | * For the data transformation
31 | */
32 | public static DataFormat dataFormat = new DataFormat("mydata");
33 |
34 | @FXML
35 | private ToggleGroup selectionGrp;
36 |
37 | @FXML
38 | private ComboBox> colSelect;
39 |
40 | @FXML
41 | private RadioButton cellRadio, rowRadio;
42 |
43 | @FXML
44 | private ResourceBundle resources;
45 |
46 | @FXML
47 | private URL location;
48 |
49 | @FXML
50 | private ListView listView;
51 |
52 | @FXML
53 | private TableColumn addressCol;
54 |
55 | @FXML
56 | private TableColumn genderCol;
57 |
58 | @FXML
59 | private TableColumn nameCol;
60 |
61 | @FXML
62 | private TableColumn phoneCol;
63 |
64 | @FXML
65 | private TableColumn snCol;
66 |
67 | @FXML
68 | private TableView tableView;
69 |
70 | ObservableList selectedIndexes = FXCollections.observableArrayList();
71 |
72 | @FXML
73 | void initialize() {
74 | assert addressCol != null : "fx:id=\"addressCol\" was not injected: check your FXML file 'TableViewDataFXML.fxml'.";
75 | assert genderCol != null : "fx:id=\"genderCol\" was not injected: check your FXML file 'TableViewDataFXML.fxml'.";
76 | assert nameCol != null : "fx:id=\"nameCol\" was not injected: check your FXML file 'TableViewDataFXML.fxml'.";
77 | assert phoneCol != null : "fx:id=\"phoneCol\" was not injected: check your FXML file 'TableViewDataFXML.fxml'.";
78 | assert snCol != null : "fx:id=\"snCol\" was not injected: check your FXML file 'TableViewDataFXML.fxml'.";
79 | assert tableView != null : "fx:id=\"tableView\" was not injected: check your FXML file 'TableViewDataFXML.fxml'.";
80 |
81 | // changed to multiple selection mode
82 | tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
83 | // set cell value factories
84 | setCellValueFactories();
85 |
86 | //set Dummy Data for the TableView
87 | tableView.setItems(getData());
88 |
89 | //ListView items bound with selection index property of tableview
90 | listView.setItems(selectedIndexes);
91 |
92 | //change listview observable list
93 | tableView.getSelectionModel().getSelectedIndices().addListener(new ListChangeListener() {
94 | @Override
95 | public void onChanged(Change extends Integer> change) {
96 | selectedIndexes.setAll(change.getList());
97 | }
98 | });
99 |
100 | //Setting the items for columns selection
101 | colSelect.setItems(tableView.getColumns());
102 | for (TableColumn c : colSelect.getItems()) {
103 | setCellColumnSelection(c);
104 | }
105 |
106 | //add listener and update of selection type
107 | colSelect.valueProperty().addListener(new ChangeListener>() {
108 | @Override
109 | public void changed(
110 | ObservableValue extends TableColumn> ov,
111 | TableColumn t,
112 | final TableColumn t1) {
113 | if (t1 != null) {
114 | if (cellRadio.isSelected()) {
115 | setCellSelection();
116 | }
117 | }
118 |
119 | }
120 | });
121 |
122 |
123 | //For showing the column name properly
124 | colSelect.setConverter(new StringConverter>() {
125 | @Override
126 | public String toString(TableColumn t) {
127 | if(t== null ){
128 | return "";
129 | }
130 | return t.getText();
131 | }
132 |
133 | @Override
134 | public TableColumn fromString(String string) {
135 | for (TableColumn t : colSelect.getItems()) {
136 | if (t.getText().equals(string)) {
137 | return t;
138 | }
139 | }
140 | return null;
141 | }
142 | });
143 |
144 | //the radio buttons change property listener [Row/Cell] selection
145 | selectionGrp.selectedToggleProperty().addListener(new ChangeListener() {
146 | @Override
147 | public void changed(
148 | ObservableValue extends Toggle> ov, Toggle t, Toggle t1) {
149 | if (t1 == cellRadio) {
150 | setCellSelection();
151 | } else {
152 | setRowSelection();
153 | }
154 |
155 | }
156 | });
157 | //Stricting the Column selection
158 | colSelect.disableProperty().bind(cellRadio.selectedProperty().not());
159 |
160 | //set the Row Factory of the table
161 | setRowFactory();
162 |
163 | //Set row selection as default
164 | setRowSelection();
165 | }
166 |
167 | private void setCellValueFactories() {
168 | snCol.setCellValueFactory(new PropertyValueFactory("sn"));
169 | nameCol.setCellValueFactory(new PropertyValueFactory("name"));
170 | genderCol.setCellValueFactory(new PropertyValueFactory("gender"));
171 | phoneCol.setCellValueFactory(new PropertyValueFactory("phone"));
172 | addressCol.setCellValueFactory(new PropertyValueFactory("address"));
173 | }
174 |
175 | /**
176 | * Change the cell selection boolean value of TableView
177 | */
178 | public void setRowSelection() {
179 | tableView.getSelectionModel().clearSelection();
180 | tableView.getSelectionModel().setCellSelectionEnabled(false);
181 | }
182 |
183 | /**
184 | * Change the cell selection boolean value of TableView
185 | */
186 | public void setCellSelection() {
187 | tableView.getSelectionModel().clearSelection();
188 | tableView.getSelectionModel().setCellSelectionEnabled(true);
189 |
190 | }
191 |
192 | /**
193 | * Set Row Factory for the TableView
194 | */
195 | public void setRowFactory() {
196 | tableView.setRowFactory(new Callback, TableRow>() {
197 | @Override
198 | public TableRow call(TableView p) {
199 | final TableRow row = new TableRow();
200 | row.setOnDragEntered(new EventHandler() {
201 | @Override
202 | public void handle(DragEvent t) {
203 | setSelection(row);
204 | }
205 | });
206 |
207 | row.setOnDragDetected(new EventHandler() {
208 | @Override
209 | public void handle(MouseEvent t) {
210 | if (rowRadio.isSelected()) {
211 | Dragboard db = row.getTableView().startDragAndDrop(TransferMode.COPY);
212 | ClipboardContent content = new ClipboardContent();
213 | content.put(dataFormat, "XData");
214 | db.setContent(content);
215 | setSelection(row);
216 | t.consume();
217 | }
218 | }
219 | });
220 | return row;
221 | }
222 | });
223 | }
224 |
225 | /**
226 | * This function helps to make the Cell Factory for specific TableColumn
227 | *
228 | * @param col
229 | */
230 | public void setCellColumnSelection(final TableColumn col) {
231 | col.setCellFactory(new Callback, TableCell>() {
232 | @Override
233 | public TableCell call(
234 | TableColumn p) {
235 | final TableCell cell = new TableCell() {
236 | @Override
237 | protected void updateItem(Object t, boolean bln) {
238 | super.updateItem(t, bln);
239 | if (t != null) {
240 | setText(t.toString());
241 | }
242 | }
243 | };
244 |
245 | cell.setOnDragEntered(new EventHandler() {
246 | @Override
247 | public void handle(DragEvent t) {
248 | setSelection(cell, col);
249 | }
250 | });
251 |
252 | cell.setOnDragDetected(new EventHandler() {
253 | @Override
254 | public void handle(MouseEvent t) {
255 | if (cellRadio.isSelected() && colSelect.getValue() == col) {
256 | Dragboard db = cell.getTableView().startDragAndDrop(TransferMode.COPY);
257 | ClipboardContent content = new ClipboardContent();
258 | content.put(dataFormat, "XData");
259 | db.setContent(content);
260 | setSelection(cell, col);
261 | t.consume();
262 | }
263 | }
264 | });
265 | return cell;
266 |
267 | }
268 | });
269 | }
270 |
271 | /**
272 | * For the changes on table cell selection used only on the TableCell selection mode
273 | *
274 | * @param cell
275 | */
276 | private void setSelection(IndexedCell cell) {
277 | if (rowRadio.isSelected()) {
278 | if (cell.isSelected()) {
279 | System.out.println("False");
280 | tableView.getSelectionModel().clearSelection(cell.getIndex());
281 | } else {
282 | System.out.println("true");
283 | tableView.getSelectionModel().select(cell.getIndex());
284 | }
285 | }
286 |
287 | }
288 |
289 | /**
290 | * For the changes on the table row selection used only on TableRow selection mode
291 | *
292 | * @param cell
293 | * @param col
294 | */
295 | private void setSelection(IndexedCell cell, TableColumn col) {
296 | if (cellRadio.isSelected()) {
297 | if (cell.isSelected()) {
298 | System.out.println("False enter");
299 | tableView.getSelectionModel().clearSelection(cell.getIndex(), col);
300 | } else {
301 | System.out.println("Select");
302 | tableView.getSelectionModel().select(cell.getIndex(), col);
303 | }
304 | }
305 | }
306 |
307 | /**
308 | * Provides the Dummy Data for this application in string format
309 | *
310 | * @param length
311 | * @return String
312 | */
313 | public String getDummyText(int length) {
314 | String most = "abdflntiso";
315 | String alpha = "abcdefghijkmopqrstuvwxyz";
316 | StringBuffer b = new StringBuffer();
317 | int chars = 0;
318 | for (int i = 0; i < length; i++) {
319 | if (chars > 2 && chars > Math.random() * 10) {
320 | b.append(" ");
321 | chars = 0;
322 | continue;
323 | }
324 | if (chars == 0 || i % 2 == 0) {
325 | b.append(most.charAt((int)(Math.random() * most.length())));
326 | } else {
327 | b.append(alpha.charAt((int)(Math.random() * alpha.length())));
328 | }
329 | chars++;
330 | }
331 | return b.toString();
332 | }
333 |
334 | /**
335 | * Provides the dummy String
336 | *
337 | * @param length
338 | * @return
339 | */
340 | public String getDummyDigits(int length) {
341 |
342 | StringBuilder b = new StringBuilder();
343 | for (int i = 0; i < length; i++) {
344 | b.append((int)(Math.random() * 9));
345 | }
346 | return b.toString();
347 | }
348 |
349 | /**
350 | * Provides the dummy Person data.
351 | *
352 | * @return
353 | */
354 | public ObservableList getData() {
355 | String[] names = new String[]{"Narayan", "Phil", "Pablo", "Michael", "Mike", "Timur", "Oszkar", "David"};
356 |
357 | ObservableList persons = FXCollections.observableArrayList();
358 | for (int i = 1; i < 500; i++) {
359 | Person p = new Person();
360 | p.setSn(i);
361 | p.setName(names[(int)(Math.random() * names.length)]);
362 | p.setAddress(getDummyText(15));
363 | p.setPhone(getDummyDigits(9));
364 | p.setGender(Gender.values()[i % 3]);
365 | persons.add(p);
366 | }
367 | return persons;
368 | }
369 | }
370 |
--------------------------------------------------------------------------------
/src/main/java/np/com/ngopal/tableviewdataselection/TableViewDataSelection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this template, choose Tools | Templates
3 | * and open the template in the editor.
4 | */
5 | package np.com.ngopal.tableviewdataselection;
6 |
7 | import java.io.IOException;
8 | import java.util.logging.Level;
9 | import java.util.logging.Logger;
10 | import javafx.application.Application;
11 | import javafx.fxml.FXMLLoader;
12 | import javafx.scene.Scene;
13 | import javafx.scene.control.Label;
14 | import javafx.scene.layout.BorderPane;
15 | import javafx.scene.layout.Pane;
16 | import javafx.stage.Stage;
17 |
18 | /**
19 | *
20 | * @author Narayan G. Maharjan
21 | */
22 | public class TableViewDataSelection extends Application {
23 | @Override
24 | public void start(Stage primaryStage) {
25 | Pane p = null;
26 | try {
27 | p = FXMLLoader.load(getClass().getResource("/fxml/TableViewDataFXML.fxml"));
28 | } catch (IOException ex) {
29 | p = new BorderPane();
30 | Label l = new Label("Error on FXML loading:" + ex.getMessage());
31 | p.getChildren().add(l);
32 | Logger.getLogger(TableViewDataSelection.class.getName()).log(Level.SEVERE, null, ex);
33 | }
34 |
35 |
36 | Scene scene = new Scene(p);
37 |
38 | primaryStage.setTitle("TableView Data Selection Demo !");
39 | primaryStage.setScene(scene);
40 | primaryStage.show();
41 | }
42 |
43 | /**
44 | * The main() method is ignored in correctly deployed JavaFX
45 | * application. main() serves only as fallback in case the
46 | * application can not be launched through deployment artifacts,
47 | * e.g., in IDEs with limited FX support. NetBeans ignores main().
48 | *
49 | * @param args the command line arguments
50 | */
51 | public static void main(String[] args) {
52 | launch(args);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/resources/fxml/TableViewDataFXML.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------