1
0
Fork 0
mirror of https://gitlab.com/kauron/jstudy synced 2025-09-30 21:01:10 +02:00

Initial commit

This commit is contained in:
Carlos Galindo 2016-06-12 00:20:11 +02:00
commit a39aaca33e
Signed by: kauron
GPG key ID: 83E68706DEE119A3
25 changed files with 973 additions and 0 deletions

View file

@ -0,0 +1,23 @@
package es.kauron.jstudy;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(Main.class.getResource("view/main.fxml"));
primaryStage.setTitle("JStudy");
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

View file

@ -0,0 +1,113 @@
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.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.stage.FileChooser;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.*;
public class Controller implements Initializable {
@FXML
private TabPane tabPane;
@FXML
private BorderPane root;
@FXML
private ToolBar toolbar;
@FXML
private MenuItem saveMenu;
@FXML
private CheckMenuItem caseMenu;
@FXML
private RadioMenuItem allMenu, selectedMenu;
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 (n.getContent().getId() != null) {
table.set(true);
root.getTop().autosize();
}
});
saveMenu.disableProperty().bind(table.not());
}
@FXML
private void onNewAction(ActionEvent event) {
TextInputDialog dialog = new TextInputDialog("Name");
dialog.showAndWait();
tabPane.getTabs().add(createTableTab(dialog.getResult(), new ArrayList<>()));
tabPane.getSelectionModel().selectLast();
}
@FXML
private void onLoadAction(ActionEvent event) {
FileChooser chooser = new FileChooser();
chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("JStudy file", "*.jsdb"));
File file = chooser.showOpenDialog(root.getScene().getWindow());
if (file == null) return;
List<TestItem> aux = TestItem.loadFrom(file);
if (aux != null) {
tabPane.getTabs().add(createTableTab(file.getName().substring(0, file.getName().lastIndexOf('.')), aux));
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());
}
private Tab createTableTab(String name, List<TestItem> list) {
try {
Tab tab = new Tab(name);
tab.setId("table" + tab.hashCode());
FXMLLoader loader = new FXMLLoader(Main.class.getResource("view/table.fxml"));
Parent tableRoot = loader.load();
((TableController) loader.getController()).setData(list, this);
tabMap.put(tab, loader.getController());
tab.setContent(tableRoot);
return tab;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
void newTest(List<TestItem> list) {
try {
FXMLLoader loader = new FXMLLoader(Main.class.getResource("view/test.fxml"));
Parent root = loader.load();
((TestController) loader.getController()).setList(new ArrayList<>(list));
tabPane.getTabs().add(new Tab("Test: " + tabPane.getSelectionModel().getSelectedItem().getText(), root));
tabPane.getSelectionModel().selectLast();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,63 @@
package es.kauron.jstudy.controller;
import es.kauron.jstudy.model.TestItem;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import java.net.URL;
import java.util.ResourceBundle;
public class EditController implements Initializable {
@FXML
private TextField questionText, answerText;
private ObservableList<TestItem> list;
private int index;
private TestItem item;
@Override
public void initialize(URL url, ResourceBundle rb) {
}
protected void setList(ObservableList list) {
setList(list, -1);
}
protected void setList(ObservableList<TestItem> list, int index) {
this.list = list; // Save attributes correctly
this.index = index;
// Copy current values to textViews
// and initialize item to hold the current object in edition
if (index < 0) item = new TestItem("","");
else {
questionText.setText(list.get(index).getQuestion());
answerText.setText(list.get(index).getAnswer());
item = new TestItem(list.get(index));
}
item.questionProperty().bind(questionText.textProperty());
item.answerProperty().bind(answerText.textProperty());
}
@FXML
private void onSaveAction(ActionEvent event) {
if (index < 0) {
if (!item.isValid())
return;
list.add(item);
} else {
list.set(index, item);
}
onCancelAction(event);
}
@FXML
private void onCancelAction(ActionEvent event) {
((Stage) ((Node) event.getSource())
.getScene().getWindow())
.close();
}
}

View file

@ -0,0 +1,121 @@
package es.kauron.jstudy.controller;
import es.kauron.jstudy.Main;
import es.kauron.jstudy.model.TestItem;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
public class TableController implements Initializable {
@FXML
private TableView<TestItem> table;
@FXML
private TableColumn<TestItem, String> answerCol, questionCol;
@FXML
private Button editButton, duplicateButton, swapButton, testSelectionButton, deleteButton;
private ObservableList<TestItem> data;
private Controller parent;
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
answerCol.setCellValueFactory(e -> e.getValue().answerProperty());
questionCol.setCellValueFactory(e -> e.getValue().questionProperty());
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) {
this.data = FXCollections.observableArrayList(list);
this.parent = controller;
table.setItems(data);
}
List<TestItem> getData() {return data;}
@FXML
private void onAddAction(ActionEvent event) {
try {
FXMLLoader cargador = new FXMLLoader(Main.class.getResource("view/edit.fxml"));
Parent pRoot = cargador.load();
((EditController) cargador.getController()).setList(data);
Stage stage = new Stage();
stage.setTitle("New entry");
stage.setScene(new Scene(pRoot));
stage.initModality(Modality.APPLICATION_MODAL);
stage.showAndWait();
} catch (IOException e) {
e.printStackTrace();
}
}
@FXML
private void onEditAction(ActionEvent event) {
ObservableList<Integer> list = table.getSelectionModel().getSelectedIndices();
if (list.size() != 1) return;
int index = list.get(0);
try {
FXMLLoader cargador = new FXMLLoader(Main.class.getResource("view/edit.fxml"));
Parent root = cargador.load();
((EditController) cargador.getController()).setList(table.getItems(), index);
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
private void onSwapAction(ActionEvent event) {
for (TestItem item : table.getSelectionModel().getSelectedItems()) {
String question = item.getQuestion();
item.questionProperty().set(item.getAnswer());
item.answerProperty().set(question);
}
}
@FXML
private void onDuplicateAction(ActionEvent event) {
table.getItems().addAll(table.getSelectionModel().getSelectedItems());
}
@FXML
private void onDeleteAction(ActionEvent event) {
table.getItems().removeAll(table.getSelectionModel().getSelectedItems());
}
@FXML
private void onTestSelectionAction(ActionEvent event) {
parent.newTest(table.getSelectionModel().getSelectedItems());
}
@FXML
private void onTestAction(ActionEvent event) {
parent.newTest(data);
}
}

View file

@ -0,0 +1,68 @@
package es.kauron.jstudy.controller;
import com.jfoenix.controls.JFXTextField;
import es.kauron.jstudy.model.TestItem;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
public class TestController implements Initializable {
@FXML
private Label question, prevQuestion, prevAnswer, correctAnswer, progressLabel, correctLabel;
@FXML
private JFXTextField answer;
@FXML
private ProgressBar progress;
private List<TestItem> list;
private int total, current;
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
}
void setList(List<TestItem> list) {
this.list = list;
total = list.size();
progress.setProgress(0);
progressLabel.setText("0/" + total);
onSkipAction(null);
}
@FXML
private void onNextAction(ActionEvent event) {
prevQuestion.setText(list.get(current).getQuestion());
prevAnswer.setText(answer.getText());
correctAnswer.setText(list.get(current).getAnswer());
boolean right = list.get(current).getAnswer().equals(answer.getText());
correctAnswer.setVisible(!right);
correctLabel.setVisible(!right);
list.remove(current);
progress.setProgress(progress.getProgress() + 1.0/total);
progressLabel.setText((int) (progress.getProgress() * total) + "/" + total);
onSkipAction(event);
}
@FXML
private void onSkipAction(ActionEvent event) {
if (list.size() == 0) {
answer.setText("");
answer.setDisable(true);
question.setText("That's it!");
} else {
answer.setText("");
current = (int) (Math.random() * list.size());
question.setText(list.get(current).getQuestion());
answer.requestFocus();
}
}
}

View file

@ -0,0 +1,83 @@
package es.kauron.jstudy.model;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import java.io.*;
import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Scanner;
public class TestItem {
private StringProperty question, answer;
public TestItem(SimpleStringProperty question, SimpleStringProperty answer) {
this.question = question;
this.answer = answer;
}
public TestItem(TestItem item) {
this(item.getQuestion(), item.getAnswer());
}
public TestItem(String question, String answer) {
this(new SimpleStringProperty(question), new SimpleStringProperty(answer));
}
public String getQuestion() {
return question.get();
}
public StringProperty questionProperty() {
return question;
}
public String getAnswer() {
return answer.get();
}
public StringProperty answerProperty() {
return answer;
}
public boolean isValid() {
return !question.get().isEmpty() && !answer.get().isEmpty();
}
public boolean checkAnswer(String answer, boolean sensible) {
return sensible ? getAnswer().equals(answer) : getAnswer().equalsIgnoreCase(answer);
}
public static void saveTo(File file, List<TestItem> data) {
try {
OutputStreamWriter writer = new FileWriter(file);
for (TestItem item : data) {
writer.write(item.getQuestion() + "::" + item.getAnswer() + "\n");
}
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static List<TestItem> loadFrom(File file) {
List<TestItem> list = new ArrayList<>();
try {
Scanner in = new Scanner(file);
while (in.hasNextLine()) {
String line = in.nextLine();
int index = line.indexOf("::");
String question = line.substring(0, index);
String answer = line.substring(index + 2);
list.add(new TestItem(question, answer));
System.err.println(question + " :: " + answer);
}
} catch (FileNotFoundException | InputMismatchException e) {
e.printStackTrace();
}
return list;
}
}