1
0
Fork 0
mirror of https://gitlab.com/kauron/jstudy synced 2024-12-22 08:23:33 +01:00

Table: new editing and filtering

* Split buttons between the context menu and above the table.
* Moved adding/editing to above the table.
* Added filtering.
* Added shortcut to edit (double click) and to delete rows.
This commit is contained in:
Carlos Galindo 2019-09-13 00:15:27 +02:00
parent 93b7dce200
commit 7fe80b07ec
Signed by: kauron
GPG key ID: 83E68706DEE119A3
2 changed files with 76 additions and 57 deletions

View file

@ -1,50 +1,47 @@
package es.kauron.jstudy.controller; package es.kauron.jstudy.controller;
import es.kauron.jstudy.Main;
import es.kauron.jstudy.model.AppPrefs; import es.kauron.jstudy.model.AppPrefs;
import es.kauron.jstudy.model.TestItem; import es.kauron.jstudy.model.TestItem;
import javafx.beans.property.BooleanProperty; import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.*;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
import javafx.scene.Parent; import javafx.scene.control.*;
import javafx.scene.Scene; import javafx.scene.input.KeyCode;
import javafx.scene.control.Button; import javafx.scene.input.KeyEvent;
import javafx.scene.control.SelectionMode; import javafx.scene.input.MouseEvent;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.ResourceBundle;
public class TableController implements Initializable { public class TableController implements Initializable {
@FXML @FXML
private TableView<TestItem> table; private TableView<TestItem> table;
@FXML @FXML
private TextField newQuestionField, newAnswerField, searchField;
@FXML
private Button addButton;
@FXML
private TableColumn<TestItem, String> answerCol, questionCol; private TableColumn<TestItem, String> answerCol, questionCol;
private FilteredList<TestItem> filtered;
private ObservableList<TestItem> data; private ObservableList<TestItem> data;
private Controller parent; private Controller parent;
private File file; private File file;
StringProperty name; StringProperty name;
final BooleanProperty saved = new SimpleBooleanProperty(); final BooleanProperty saved = new SimpleBooleanProperty();
private final ObjectProperty<TestItem> editing = new SimpleObjectProperty<>(null);
@Override @Override
public void initialize(URL url, ResourceBundle resourceBundle) { public void initialize(URL url, ResourceBundle resourceBundle) {
addButton.textProperty().bind(Bindings.when(editing.isNull()).then("_Add item").otherwise("_Save item"));
// Add context menu to Table // Add context menu to Table
MenuItem menuEdit = new MenuItem("_Edit"); MenuItem menuEdit = new MenuItem("_Edit");
menuEdit.setOnAction(this::onEditAction); menuEdit.setOnAction(this::onEditAction);
@ -61,16 +58,18 @@ public class TableController implements Initializable {
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
answerCol.setCellValueFactory(e -> e.getValue().answerProperty()); answerCol.setCellValueFactory(e -> e.getValue().answerProperty());
questionCol.setCellValueFactory(e -> e.getValue().questionProperty()); questionCol.setCellValueFactory(e -> e.getValue().questionProperty());
table.getSelectionModel().getSelectedIndices().addListener((ListChangeListener<? super Integer>) obs -> { table.getSelectionModel().getSelectedIndices().addListener(
menuEdit.setDisable(obs.getList().size() != 1); (ListChangeListener<? super Integer>) obs -> menuEdit.setDisable(obs.getList().size() != 1));
}); searchField.textProperty().addListener((obj, o, n) ->
filtered.setPredicate((item) -> item.getQuestion().contains(n) || item.getAnswer().contains(n)));
} }
void setData(String name, List<TestItem> list, Controller controller, File file) { void setData(String name, List<TestItem> list, Controller controller, File file) {
this.name = new SimpleStringProperty(name); this.name = new SimpleStringProperty(name);
this.data = FXCollections.observableArrayList(list); this.data = FXCollections.observableArrayList(list);
this.filtered = data.filtered((item) -> true);
this.parent = controller; this.parent = controller;
table.setItems(data); table.setItems(filtered);
this.file = file; this.file = file;
saved.set(file != null); saved.set(file != null);
} }
@ -99,41 +98,31 @@ public class TableController implements Initializable {
@FXML @FXML
protected void onAddAction(ActionEvent event) { protected void onAddAction(ActionEvent event) {
try { if (editing.get() == null) {
FXMLLoader loader = new FXMLLoader(Main.class.getResource("view/edit.fxml")); TestItem item = new TestItem(newQuestionField.getText().trim(), newAnswerField.getText().trim());
Parent pRoot = loader.load(); data.add(item);
newQuestionField.setText("");
((EditController) loader.getController()).setList(data, saved); newAnswerField.setText("");
saved.set(false);
Stage stage = new Stage(); } else {
stage.setTitle("New entry"); editing.get().answerProperty().set(newAnswerField.getText().trim());
stage.setScene(new Scene(pRoot)); editing.get().questionProperty().set(newQuestionField.getText().trim());
stage.initModality(Modality.APPLICATION_MODAL); editing.set(null);
stage.showAndWait(); newQuestionField.setText("");
} catch (IOException e) { newAnswerField.setText("");
e.printStackTrace();
} }
newQuestionField.requestFocus();
} }
@FXML @FXML
protected void onEditAction(ActionEvent event) { protected void onEditAction(ActionEvent event) {
ObservableList<Integer> list = table.getSelectionModel().getSelectedIndices(); ObservableList<TestItem> list = table.getSelectionModel().getSelectedItems();
if (list.size() != 1) return; if (list.size() != 1) return;
int index = list.get(0); editing.set(list.get(0));
try { newQuestionField.setText(list.get(0).getQuestion());
FXMLLoader loader = new FXMLLoader(Main.class.getResource("view/edit.fxml")); newAnswerField.setText(list.get(0).getAnswer());
Parent root = loader.load(); saved.set(false);
newQuestionField.requestFocus();
((EditController) loader.getController()).setList(table.getItems(), index, saved);
Stage stage = new Stage();
stage.setTitle("Editing entry...");
stage.setScene(new Scene(root));
stage.initModality(Modality.APPLICATION_MODAL);
stage.showAndWait();
} catch (IOException e) {
e.printStackTrace();
}
} }
@FXML @FXML
@ -151,15 +140,14 @@ public class TableController implements Initializable {
protected void onDuplicateAction(ActionEvent event) { protected void onDuplicateAction(ActionEvent event) {
if (table.getSelectionModel().getSelectedIndices().size() > 0) saved.set(false); if (table.getSelectionModel().getSelectedIndices().size() > 0) saved.set(false);
for (int i : table.getSelectionModel().getSelectedIndices()) for (int i : table.getSelectionModel().getSelectedIndices())
table.getItems().add(new TestItem(table.getItems().get(i))); data.add(new TestItem(filtered.get(i)));
table.requestFocus(); table.requestFocus();
} }
@FXML @FXML
protected void onDeleteAction(ActionEvent event) { protected void onDeleteAction(ActionEvent event) {
if (table.getSelectionModel().getSelectedIndices().size() > 0) saved.set(false); if (table.getSelectionModel().getSelectedIndices().size() > 0) saved.set(false);
for (int i : table.getSelectionModel().getSelectedIndices()) data.removeAll(table.getSelectionModel().getSelectedItems());
table.getItems().remove(i);
table.requestFocus(); table.requestFocus();
} }
@ -170,6 +158,32 @@ public class TableController implements Initializable {
@FXML @FXML
protected void onTestAction(ActionEvent event) { protected void onTestAction(ActionEvent event) {
parent.newTest(data); parent.newTest(filtered);
}
@FXML
protected void onTableKeyEvent(KeyEvent event) {
if (event.getCode().equals(KeyCode.DELETE)) {
onDeleteAction(null);
}
}
private final Timer timer = new Timer();
private TimerTask timerTask = null;
@FXML
protected void onTableMouseClicked(MouseEvent event) {
if (timerTask == null) {
timerTask = new TimerTask() {
@Override
public void run() {
timerTask = null;
}
};
timer.schedule(timerTask, 200);
} else {
if (timerTask.cancel())
onEditAction(null);
timerTask = null;
}
} }
} }

View file

@ -7,11 +7,14 @@
<children> <children>
<HBox alignment="CENTER_LEFT" spacing="5.0"> <HBox alignment="CENTER_LEFT" spacing="5.0">
<children> <children>
<Button defaultButton="true" onAction="#onAddAction" prefWidth="105.0" text="_Add new"> <TextField fx:id="newQuestionField" promptText="Question" />
<TextField fx:id="newAnswerField" promptText="Answer" />
<Button defaultButton="true" fx:id="addButton" onAction="#onAddAction" prefWidth="105.0" text="_Add new">
<tooltip> <tooltip>
<Tooltip text="Add a new entry to the table" /> <Tooltip text="Add a new entry to the table" />
</tooltip> </tooltip>
</Button> </Button>
<TextField fx:id="searchField" promptText="Search..." />
<HBox alignment="CENTER_RIGHT" spacing="5.0" HBox.hgrow="ALWAYS" VBox.vgrow="ALWAYS"> <HBox alignment="CENTER_RIGHT" spacing="5.0" HBox.hgrow="ALWAYS" VBox.vgrow="ALWAYS">
<children> <children>
<Button layoutX="10.0" layoutY="273.0" onAction="#onTestAction" prefWidth="105.0" text="_Test all"> <Button layoutX="10.0" layoutY="273.0" onAction="#onTestAction" prefWidth="105.0" text="_Test all">
@ -35,7 +38,9 @@
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" /> <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</VBox.margin> </VBox.margin>
</HBox> </HBox>
<TableView fx:id="table" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="400.0" HBox.hgrow="ALWAYS" VBox.vgrow="ALWAYS"> <TableView fx:id="table" onMouseClicked="#onTableMouseClicked" onKeyPressed="#onTableKeyEvent" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity"
prefHeight="200.0" prefWidth="400.0" HBox.hgrow="ALWAYS" VBox.vgrow="ALWAYS">
<columns> <columns>
<TableColumn fx:id="questionCol" prefWidth="75.0" text="Question" /> <TableColumn fx:id="questionCol" prefWidth="75.0" text="Question" />
<TableColumn fx:id="answerCol" prefWidth="75.0" text="Answer" /> <TableColumn fx:id="answerCol" prefWidth="75.0" text="Answer" />