1
0
Fork 0
mirror of https://gitlab.com/kauron/jstudy synced 2024-11-13 07:33:44 +01:00

Save protocol update

This commit is contained in:
Carlos Galindo 2016-06-13 19:16:55 +02:00
parent 9450056e6f
commit 30a6ddaee2
Signed by: kauron
GPG key ID: 83E68706DEE119A3
5 changed files with 149 additions and 72 deletions

View file

@ -2,9 +2,12 @@ package es.kauron.jstudy.controller;
import es.kauron.jstudy.Main;
import es.kauron.jstudy.model.TestItem;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
@ -24,22 +27,25 @@ public class Controller implements Initializable {
@FXML
private BorderPane root;
@FXML
private ToolBar toolbar;
@FXML
private MenuItem saveMenu;
private BooleanProperty table = new SimpleBooleanProperty(false);
private Map<Tab, TableController> tabMap = new HashMap<>();
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
tabPane.getSelectionModel().selectedItemProperty().addListener((change, o, n) -> {
if (tabMap.get(n) != null) {
table.set(true);
} else table.set(false);
});
saveMenu.disableProperty().bind(table.not());
tabPane.getSelectionModel().selectedItemProperty().addListener((ob, o, n) -> table.set(tabMap.get(n) != null));
Platform.runLater(() ->
root.getScene().getWindow().setOnCloseRequest(event -> {
for (Tab tab : tabPane.getTabs()) {
EventHandler<Event> handler = tab.getOnCloseRequest();
if (tab.isClosable() && handler != null) {
tabPane.getSelectionModel().select(tab);
handler.handle(event);
if (event.isConsumed()) return;
}
}
})
);
}
@FXML
@ -63,7 +69,7 @@ public class Controller implements Initializable {
dialog.showAndWait();
dialog.setResultConverter(value -> value.getButtonData().equals(ButtonBar.ButtonData.OK_DONE) ? value.getText() : "");
if (dialog.getResult() == null || dialog.getResult().isEmpty()) return;
tabPane.getTabs().add(createTableTab(dialog.getResult(), new ArrayList<>()));
tabPane.getTabs().add(createTableTab(dialog.getResult(), new ArrayList<>(), null));
tabPane.getSelectionModel().selectLast();
}
@ -75,20 +81,11 @@ public class Controller implements Initializable {
if (file == null) return;
List<TestItem> aux = TestItem.loadFrom(file, TestItem.COLONS);
if (aux != null) {
tabPane.getTabs().add(createTableTab(file.getName().substring(0, file.getName().lastIndexOf('.')), aux));
tabPane.getTabs().add(createTableTab(file.getName().substring(0, file.getName().lastIndexOf('.')), aux, file));
tabPane.getSelectionModel().selectLast();
}
}
@FXML
private void onSaveAction(ActionEvent event) {
FileChooser chooser = new FileChooser();
chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("JStudy file", "*.jsdb"));
File file = chooser.showSaveDialog(root.getScene().getWindow());
if (file == null) return;
TestItem.saveTo(file, tabMap.get(tabPane.getSelectionModel().getSelectedItem()).getData());
}
@FXML
private void onImportAction(ActionEvent event) {
FileChooser chooser = new FileChooser();
@ -104,22 +101,37 @@ public class Controller implements Initializable {
separator = TestItem.COMMA;
List<TestItem> aux = TestItem.loadFrom(file, separator);
if (aux != null) {
tabPane.getTabs().add(createTableTab(file.getName().substring(0, file.getName().lastIndexOf('.')), aux));
tabPane.getTabs().add(createTableTab(file.getName().substring(0, file.getName().lastIndexOf('.')), aux, null));
tabPane.getSelectionModel().selectLast();
}
}
private Tab createTableTab(String name, List<TestItem> list) {
private Tab createTableTab(String name, List<TestItem> list, File file) {
try {
Tab tab = new Tab(name);
FXMLLoader loader = new FXMLLoader(Main.class.getResource("view/table.fxml"));
Parent tableRoot = loader.load();
((TableController) loader.getController()).setData(list, this);
((TableController) loader.getController()).setData(list, this, file);
tabMap.put(tab, loader.getController());
tab.setContent(tableRoot);
tab.setOnCloseRequest(event -> {
if (!((TableController) loader.getController()).saved.get()) {
Alert dialog = new Alert(Alert.AlertType.WARNING);
dialog.setHeaderText("The tab " + name + " has unsaved information");
dialog.setContentText("Do you want to save those changes?");
dialog.getButtonTypes().clear();
dialog.getButtonTypes().addAll(ButtonType.YES, ButtonType.NO, ButtonType.CANCEL);
dialog.showAndWait();
if (dialog.getResult().equals(ButtonType.YES)) {
((TableController) loader.getController()).onSaveAction(null);
} else if (dialog.getResult().equals(ButtonType.CANCEL)) {
event.consume();
}
}
});
return tab;
} catch (IOException e) {
e.printStackTrace();

View file

@ -1,6 +1,7 @@
package es.kauron.jstudy.controller;
import es.kauron.jstudy.model.TestItem;
import javafx.beans.property.BooleanProperty;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
@ -18,18 +19,21 @@ public class EditController implements Initializable {
private ObservableList<TestItem> list;
private int index;
private TestItem item;
private BooleanProperty saved;
private String originalQuestion, originalAnswer;
@Override
public void initialize(URL url, ResourceBundle rb) {
}
protected void setList(ObservableList list) {
setList(list, -1);
protected void setList(ObservableList list, BooleanProperty saved) {
setList(list, -1, saved);
}
protected void setList(ObservableList<TestItem> list, int index) {
protected void setList(ObservableList<TestItem> list, int index, BooleanProperty saved) {
this.list = list; // Save attributes correctly
this.index = index;
this.saved = saved;
// Copy current values to textViews
// and initialize item to hold the current object in edition
if (index < 0) item = new TestItem("","");
@ -38,12 +42,14 @@ public class EditController implements Initializable {
answerText.setText(list.get(index).getAnswer());
item = new TestItem(list.get(index));
}
originalQuestion = questionText.getText();
originalAnswer = answerText.getText();
item.questionProperty().bind(questionText.textProperty());
item.answerProperty().bind(answerText.textProperty());
}
@FXML
private void onSaveAction(ActionEvent event) {
protected void onSaveAction(ActionEvent event) {
if (index < 0) {
if (!item.isValid())
return;
@ -51,11 +57,12 @@ public class EditController implements Initializable {
} else {
list.set(index, item);
}
if (!originalQuestion.equals(item.getQuestion()) || !originalAnswer.equals(item.getAnswer())) saved.set(false);
onCancelAction(event);
}
@FXML
private void onCancelAction(ActionEvent event) {
protected void onCancelAction(ActionEvent event) {
((Stage) ((Node) event.getSource())
.getScene().getWindow())
.close();

View file

@ -2,7 +2,10 @@ package es.kauron.jstudy.controller;
import es.kauron.jstudy.Main;
import es.kauron.jstudy.model.TestItem;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
@ -14,9 +17,11 @@ import javafx.scene.control.Button;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.FileChooser;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.List;
@ -28,42 +33,55 @@ public class TableController implements Initializable {
@FXML
private TableColumn<TestItem, String> answerCol, questionCol;
@FXML
private Button editButton, duplicateButton, swapButton, testSelectionButton, deleteButton;
private Button editButton, duplicateButton, swapButton, testSelectionButton, deleteButton, saveButton;
private ObservableList<TestItem> data;
private Controller parent;
private File file;
protected BooleanProperty saved = new SimpleBooleanProperty();
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
answerCol.setCellValueFactory(e -> e.getValue().answerProperty());
questionCol.setCellValueFactory(e -> e.getValue().questionProperty());
bindButtons();
table.getSelectionModel().getSelectedIndices().addListener((ListChangeListener<? super Integer>) obs -> {
editButton.setDisable(obs.getList().size() != 1);
swapButton.setDisable(obs.getList().size() < 1);
deleteButton.setDisable(obs.getList().size() < 1);
duplicateButton.setDisable(obs.getList().size() < 1);
testSelectionButton.setDisable(obs.getList().size() < 1);
});
saveButton.disableProperty().bind(saved);
}
private void bindButtons() {
editButton.disableProperty().bind(table.getSelectionModel().selectedIndexProperty().lessThan(0));
swapButton.disableProperty().bind(table.getSelectionModel().selectedIndexProperty().lessThan(0));
deleteButton.disableProperty().bind(table.getSelectionModel().selectedIndexProperty().lessThan(0));
duplicateButton.disableProperty().bind(table.getSelectionModel().selectedIndexProperty().lessThan(0));
testSelectionButton.disableProperty().bind(table.getSelectionModel().selectedIndexProperty().lessThan(0));
}
void setData(List<TestItem> list, Controller controller) {
void setData(List<TestItem> list, Controller controller, File file) {
this.data = FXCollections.observableArrayList(list);
this.parent = controller;
table.setItems(data);
this.file = file;
saved.set(file != null);
}
List<TestItem> getData() {return data;}
@FXML
protected void onSaveAction(ActionEvent event) {
if (file == null) {
FileChooser chooser = new FileChooser();
chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("JStudy file", "*.jsdb"));
file = chooser.showSaveDialog(table.getScene().getWindow());
}
if (file == null) return;
TestItem.saveTo(file, data);
saved.set(true);
}
@FXML
private void onAddAction(ActionEvent event) {
protected void onAddAction(ActionEvent event) {
try {
FXMLLoader cargador = new FXMLLoader(Main.class.getResource("view/edit.fxml"));
Parent pRoot = cargador.load();
((EditController) cargador.getController()).setList(data);
((EditController) cargador.getController()).setList(data, saved);
Stage stage = new Stage();
stage.setTitle("New entry");
@ -76,7 +94,7 @@ public class TableController implements Initializable {
}
@FXML
private void onEditAction(ActionEvent event) {
protected void onEditAction(ActionEvent event) {
ObservableList<Integer> list = table.getSelectionModel().getSelectedIndices();
if (list.size() != 1) return;
int index = list.get(0);
@ -84,7 +102,7 @@ public class TableController implements Initializable {
FXMLLoader cargador = new FXMLLoader(Main.class.getResource("view/edit.fxml"));
Parent root = cargador.load();
((EditController) cargador.getController()).setList(table.getItems(), index);
((EditController) cargador.getController()).setList(table.getItems(), index, saved);
Stage stage = new Stage();
stage.setTitle("Editing entry...");
@ -97,7 +115,8 @@ public class TableController implements Initializable {
}
@FXML
private void onSwapAction(ActionEvent event) {
protected void onSwapAction(ActionEvent event) {
if (table.getSelectionModel().getSelectedIndices().size() > 0) saved.set(false);
for (TestItem item : table.getSelectionModel().getSelectedItems()) {
String question = item.getQuestion();
item.questionProperty().set(item.getAnswer());
@ -107,26 +126,28 @@ public class TableController implements Initializable {
}
@FXML
private void onDuplicateAction(ActionEvent event) {
protected void onDuplicateAction(ActionEvent event) {
if (table.getSelectionModel().getSelectedIndices().size() > 0) saved.set(false);
for (int i : table.getSelectionModel().getSelectedIndices())
table.getItems().add(new TestItem(table.getItems().get(i)));
table.requestFocus();
}
@FXML
private void onDeleteAction(ActionEvent event) {
protected void onDeleteAction(ActionEvent event) {
if (table.getSelectionModel().getSelectedIndices().size() > 0) saved.set(false);
for (int i : table.getSelectionModel().getSelectedIndices())
table.getItems().remove(i);
table.requestFocus();
}
@FXML
private void onTestSelectionAction(ActionEvent event) {
protected void onTestSelectionAction(ActionEvent event) {
parent.newTest(table.getSelectionModel().getSelectedItems());
}
@FXML
private void onTestAction(ActionEvent event) {
protected void onTestAction(ActionEvent event) {
parent.newTest(data);
}
}

View file

@ -21,7 +21,10 @@
<Image url="@../img/File.png" />
</image>
</ImageView>
</graphic></Button>
</graphic>
<tooltip>
<Tooltip text="Create new empty table" />
</tooltip></Button>
<Button alignment="TOP_LEFT" onAction="#onLoadAction" prefWidth="150.0" text="_Load file">
<graphic>
<ImageView fitHeight="30.0" fitWidth="30.0" pickOnBounds="true" preserveRatio="true">
@ -29,7 +32,10 @@
<Image url="@../img/Open%20Folder.png" />
</image>
</ImageView>
</graphic></Button>
</graphic>
<tooltip>
<Tooltip text="Open an existing table from a file" />
</tooltip></Button>
<Button alignment="TOP_LEFT" layoutX="260.0" layoutY="187.0" onAction="#onImportAction" prefWidth="150.0" text="_Import data">
<graphic>
<ImageView fitHeight="30.0" fitWidth="30.0" pickOnBounds="true" preserveRatio="true">
@ -37,7 +43,10 @@
<Image url="@../img/Download.png" />
</image>
</ImageView>
</graphic></Button>
</graphic>
<tooltip>
<Tooltip text="Import data from other table-based software" />
</tooltip></Button>
<Button alignment="TOP_LEFT" layoutX="260.0" layoutY="208.0" onAction="#onSettingsAction" prefWidth="150.0" text="_Settings">
<graphic>
<ImageView fitHeight="30.0" fitWidth="30.0" pickOnBounds="true" preserveRatio="true">
@ -45,7 +54,10 @@
<Image url="@../img/Settings.png" />
</image>
</ImageView>
</graphic></Button>
</graphic>
<tooltip>
<Tooltip text="Change the settings" />
</tooltip></Button>
</children>
<padding>
<Insets bottom="15.0" left="15.0" right="15.0" top="15.0" />
@ -86,19 +98,6 @@
</ImageView>
</graphic>
</MenuItem>
<MenuItem fx:id="saveMenu" onAction="#onSaveAction" text="_Save">
<accelerator>
<KeyCodeCombination alt="UP" code="S" control="DOWN" meta="UP" shift="UP" shortcut="UP" />
</accelerator>
<graphic>
<ImageView fitHeight="25.0" fitWidth="25.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../img/Save.png" />
</image>
</ImageView>
</graphic>
</MenuItem>
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem onAction="#onImportAction" text="_Import">
<graphic>
<ImageView fitHeight="25.0" fitWidth="25.0" pickOnBounds="true" preserveRatio="true">

View file

@ -1,13 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<HBox xmlns="http://javafx.com/javafx/8.0.76-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="es.kauron.jstudy.controller.TableController">
<children>
<TableView fx:id="table" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="400.0" HBox.hgrow="ALWAYS">
<TableView fx:id="table" minHeight="-Infinity" minWidth="-Infinity" prefHeight="380.0" prefWidth="400.0" HBox.hgrow="ALWAYS">
<columns>
<TableColumn fx:id="questionCol" prefWidth="75.0" text="Question" />
<TableColumn fx:id="answerCol" prefWidth="75.0" text="Answer" />
@ -18,7 +17,25 @@
</TableView>
<VBox spacing="5.0">
<children>
<Button defaultButton="true" onAction="#onAddAction" prefWidth="105.0" text="_Add" />
<Button fx:id="saveButton" alignment="CENTER" contentDisplay="CENTER" layoutX="10.0" layoutY="163.0" onAction="#onSaveAction" prefWidth="105.0">
<graphic>
<ImageView fitHeight="50.0" fitWidth="50.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../img/Save.png" />
</image>
</ImageView>
</graphic>
<VBox.margin>
<Insets />
</VBox.margin>
<tooltip>
<Tooltip text="Save table to a file for future use" />
</tooltip>
</Button>
<Button defaultButton="true" onAction="#onAddAction" prefWidth="105.0" text="_Add">
<tooltip>
<Tooltip text="Add a new entry to the table" />
</tooltip></Button>
<Button fx:id="editButton" alignment="TOP_LEFT" onAction="#onEditAction" prefWidth="105.0" text="_Edit">
<graphic>
<ImageView fitHeight="25.0" fitWidth="25.0" pickOnBounds="true" preserveRatio="true">
@ -27,6 +44,9 @@
</image>
</ImageView>
</graphic>
<tooltip>
<Tooltip text="Edit the selected entry" />
</tooltip>
</Button>
<Button fx:id="swapButton" alignment="TOP_LEFT" layoutX="10.0" layoutY="76.0" onAction="#onSwapAction" prefWidth="105.0" text="S_wap">
<graphic>
@ -36,6 +56,9 @@
</image>
</ImageView>
</graphic>
<tooltip>
<Tooltip text="Make the answer the question and viceversa" />
</tooltip>
</Button>
<Button fx:id="duplicateButton" alignment="TOP_LEFT" layoutX="10.0" layoutY="76.0" onAction="#onDuplicateAction" prefWidth="105.0" text="D_uplicate">
<graphic>
@ -45,6 +68,9 @@
</image>
</ImageView>
</graphic>
<tooltip>
<Tooltip text="Make a copy (may appear at the end)" />
</tooltip>
</Button>
<Button fx:id="deleteButton" alignment="TOP_LEFT" onAction="#onDeleteAction" prefWidth="105.0" text="_Delete">
<graphic>
@ -54,12 +80,24 @@
</image>
</ImageView>
</graphic>
<tooltip>
<Tooltip text="Delete all selected entries FOREVER" />
</tooltip>
</Button>
<VBox alignment="BOTTOM_CENTER" spacing="5.0" VBox.vgrow="ALWAYS">
<children>
<Button fx:id="testSelectionButton" onAction="#onTestSelectionAction" prefWidth="105.0" text="Test _selected" />
<Button layoutX="10.0" layoutY="273.0" onAction="#onTestAction" prefWidth="105.0" text="_Test all" />
<Button fx:id="testSelectionButton" onAction="#onTestSelectionAction" prefWidth="105.0" text="Test _selected">
<tooltip>
<Tooltip text="Begin a test with the selected rows" />
</tooltip></Button>
<Button layoutX="10.0" layoutY="273.0" onAction="#onTestAction" prefWidth="105.0" text="_Test all">
<tooltip>
<Tooltip text="Begin a test for the whole table" />
</tooltip></Button>
</children>
<VBox.margin>
<Insets />
</VBox.margin>
</VBox>
</children>
<HBox.margin>