Project copied
This commit is contained in:
454
src/main/java/gui/CharacterAnalysisTab.java
Normal file
454
src/main/java/gui/CharacterAnalysisTab.java
Normal file
@@ -0,0 +1,454 @@
|
||||
package gui;
|
||||
|
||||
import data.*;
|
||||
import javafx.application.HostServices;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.Pane;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.controlsfx.control.CheckComboBox;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static alg.XML_processing.readXML;
|
||||
import static gui.GUIController.showAlert;
|
||||
import static gui.Messages.*;
|
||||
|
||||
@SuppressWarnings("Duplicates")
|
||||
public class CharacterAnalysisTab {
|
||||
public final static Logger logger = LogManager.getLogger(CharacterAnalysisTab.class);
|
||||
|
||||
@FXML
|
||||
public Label selectedFiltersLabel;
|
||||
@FXML
|
||||
public Label solarFilters;
|
||||
|
||||
@FXML
|
||||
private TextField msdTF;
|
||||
private ArrayList<Pattern> msd;
|
||||
private ArrayList<String> msdStrings;
|
||||
|
||||
@FXML
|
||||
private CheckComboBox<String> taxonomyCCB;
|
||||
private ArrayList<String> taxonomy;
|
||||
|
||||
@FXML
|
||||
private CheckBox calculatecvvCB;
|
||||
private boolean calculateCvv;
|
||||
|
||||
@FXML
|
||||
private TextField stringLengthTF;
|
||||
private Integer stringLength;
|
||||
|
||||
@FXML
|
||||
private ToggleGroup calculateForRB;
|
||||
private CalculateFor calculateFor;
|
||||
|
||||
@FXML
|
||||
private RadioButton lemmaRB;
|
||||
|
||||
@FXML
|
||||
private RadioButton varietyRB;
|
||||
|
||||
@FXML
|
||||
private Pane paneLetters;
|
||||
|
||||
@FXML
|
||||
private Button computeNgramsB;
|
||||
|
||||
@FXML
|
||||
public ProgressBar ngramProgressBar;
|
||||
@FXML
|
||||
public Label progressLabel;
|
||||
|
||||
@FXML
|
||||
private Hyperlink helpH;
|
||||
|
||||
private enum MODE {
|
||||
LETTER
|
||||
}
|
||||
|
||||
private MODE currentMode;
|
||||
|
||||
private Corpus corpus;
|
||||
private HashMap<String, HashSet<String>> solarFiltersMap;
|
||||
private Filter filter;
|
||||
private boolean useDb;
|
||||
private HostServices hostService;
|
||||
|
||||
private static final ObservableList<String> N_GRAM_COMPUTE_FOR_LETTERS = FXCollections.observableArrayList("različnica", "lema");
|
||||
private static final ObservableList<String> N_GRAM_COMPUTE_FOR_WORDS_ORTH = FXCollections.observableArrayList("različnica");
|
||||
|
||||
|
||||
// TODO: pass observables for taxonomy based on header scan
|
||||
// after header scan
|
||||
private ObservableList<String> taxonomyCCBValues;
|
||||
private CorpusType currentCorpusType;
|
||||
|
||||
public void init() {
|
||||
currentMode = MODE.LETTER;
|
||||
toggleMode(currentMode);
|
||||
|
||||
calculateForRB.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Toggle> observable, Toggle oldValue, Toggle newValue) {
|
||||
//logger.info("calculateForRB:", newValue.toString());
|
||||
RadioButton chk = (RadioButton)newValue.getToggleGroup().getSelectedToggle(); // Cast object to radio button
|
||||
calculateFor = CalculateFor.factory(chk.getText());
|
||||
logger.info("calculateForRB:", chk.getText());
|
||||
//System.out.println("Selected Radio Button - "+chk.getText());
|
||||
}
|
||||
});
|
||||
|
||||
// msd
|
||||
msdTF.focusedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (!newValue) {
|
||||
// focus lost
|
||||
String value = msdTF.getText();
|
||||
logger.info("msdTf: ", value);
|
||||
|
||||
if (!ValidationUtil.isEmpty(value)) {
|
||||
ArrayList<String> msdTmp = new ArrayList<>(Arrays.asList(value.split(" ")));
|
||||
|
||||
int nOfRequiredMsdTokens = 1;
|
||||
if (msdTmp.size() != nOfRequiredMsdTokens) {
|
||||
String msg = String.format(Messages.WARNING_MISMATCHED_NGRAM_AND_TOKENS_VALUES, nOfRequiredMsdTokens, msdTmp.size());
|
||||
logAlert(msg);
|
||||
showAlert(Alert.AlertType.ERROR, msg);
|
||||
}
|
||||
msd = new ArrayList<>();
|
||||
msdStrings = new ArrayList<>();
|
||||
for (String msdToken : msdTmp) {
|
||||
msd.add(Pattern.compile(msdToken));
|
||||
msdStrings.add(msdToken);
|
||||
}
|
||||
logger.info(String.format("msd accepted (%d)", msd.size()));
|
||||
|
||||
} else if (!ValidationUtil.isEmpty(newValue)) {
|
||||
msd = new ArrayList<>();
|
||||
msdStrings = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
msdTF.setText("");
|
||||
msd = new ArrayList<>();
|
||||
|
||||
// taxonomy
|
||||
if (Tax.getCorpusTypesWithTaxonomy().contains(corpus.getCorpusType())) {
|
||||
taxonomyCCB.getItems().removeAll();
|
||||
taxonomyCCB.getItems().setAll(corpus.getTaxonomy());
|
||||
taxonomyCCB.getCheckModel().getCheckedItems().addListener((ListChangeListener<String>) c -> {
|
||||
taxonomy = new ArrayList<>();
|
||||
ObservableList<String> checkedItems = taxonomyCCB.getCheckModel().getCheckedItems();
|
||||
taxonomy.addAll(checkedItems);
|
||||
logger.info(String.format("Selected taxonomy: %s", StringUtils.join(checkedItems, ",")));
|
||||
});
|
||||
taxonomyCCB.getCheckModel().clearChecks();
|
||||
} else {
|
||||
taxonomyCCB.setDisable(true);
|
||||
}
|
||||
|
||||
// cvv
|
||||
calculatecvvCB.selectedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
calculateCvv = newValue;
|
||||
logger.info("calculate cvv: " + calculateCvv);
|
||||
});
|
||||
|
||||
|
||||
// string length
|
||||
stringLengthTF.focusedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (!newValue) {
|
||||
// focus lost
|
||||
String value = stringLengthTF.getText();
|
||||
if (!ValidationUtil.isEmpty(value)) {
|
||||
if (!ValidationUtil.isNumber(value)) {
|
||||
logAlert("stringlengthTf: " + WARNING_ONLY_NUMBERS_ALLOWED);
|
||||
GUIController.showAlert(Alert.AlertType.ERROR, WARNING_ONLY_NUMBERS_ALLOWED);
|
||||
}
|
||||
stringLength = Integer.parseInt(value);
|
||||
} else {
|
||||
GUIController.showAlert(Alert.AlertType.ERROR, WARNING_MISSING_STRING_LENGTH);
|
||||
stringLengthTF.setText("1");
|
||||
logAlert(WARNING_MISSING_STRING_LENGTH);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
computeNgramsB.setOnAction(e -> {
|
||||
compute();
|
||||
logger.info("compute button");
|
||||
});
|
||||
|
||||
helpH.setOnAction(e -> openHelpWebsite());
|
||||
}
|
||||
|
||||
/**
|
||||
* case a: values for combo boxes can change after a corpus change
|
||||
* <ul>
|
||||
* <li>different corpus type - reset all fields so no old values remain</li>
|
||||
* <li>same corpus type, different subset - keep</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* case b: values for combo boxes can change after a header scan
|
||||
* <ul>
|
||||
* <li>at first, fields are populated by corpus type defaults</li>
|
||||
* <li>after, with gathered data</li>
|
||||
* </ul>
|
||||
* <p></p>
|
||||
* ngrams: 1
|
||||
* calculateFor: word
|
||||
* msd:
|
||||
* taxonomy:
|
||||
* skip: 0
|
||||
* iscvv: false
|
||||
* string length: 1
|
||||
*/
|
||||
public void populateFields() {
|
||||
// corpus changed if: current one is null (this is first run of the app)
|
||||
// or if currentCorpus != gui's corpus
|
||||
boolean corpusChanged = currentCorpusType == null
|
||||
|| currentCorpusType != corpus.getCorpusType();
|
||||
|
||||
// TODO: check for GOS, GIGAFIDA, SOLAR...
|
||||
// refresh and:
|
||||
// TODO if current value != null && is in new calculateFor ? keep : otherwise reset
|
||||
if (calculateFor == null) {
|
||||
calculateForRB.selectToggle(lemmaRB);
|
||||
calculateFor = CalculateFor.factory(calculateForRB.getSelectedToggle().toString());
|
||||
}
|
||||
|
||||
if (!filter.hasMsd()) {
|
||||
// if current corpus doesn't have msd data, disable this field
|
||||
msd = new ArrayList<>();
|
||||
msdTF.setText("");
|
||||
msdTF.setDisable(true);
|
||||
logger.info("no msd data");
|
||||
} else {
|
||||
if (ValidationUtil.isEmpty(msd)
|
||||
|| (!ValidationUtil.isEmpty(msd) && corpusChanged)) {
|
||||
// msd has not been set previously
|
||||
// or msd has been set but the corpus changed -> reset
|
||||
msd = new ArrayList<>();
|
||||
msdTF.setText("");
|
||||
msdTF.setDisable(false);
|
||||
logger.info("msd reset");
|
||||
} else if (!ValidationUtil.isEmpty(msd) && !corpusChanged) {
|
||||
// if msd has been set, but corpus type remained the same, we can keep any set msd value
|
||||
msdTF.setText(StringUtils.join(msdStrings, " "));
|
||||
msdTF.setDisable(false);
|
||||
logger.info("msd kept");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: taxonomy: refresh and keep if in new taxonomy, otherwise empty (no selection)
|
||||
|
||||
// keep calculateCvv
|
||||
calculatecvvCB.setSelected(calculateCvv);
|
||||
|
||||
// keep string length if set
|
||||
if (stringLength != null) {
|
||||
stringLengthTF.setText(String.valueOf(stringLength));
|
||||
} else {
|
||||
stringLengthTF.setText("1");
|
||||
stringLength = 1;
|
||||
}
|
||||
|
||||
// TODO: trigger on rescan
|
||||
if ((currentCorpusType != null && currentCorpusType != corpus.getCorpusType())) {
|
||||
// user changed corpus (by type) or by selection & triggered a rescan of headers
|
||||
// see if we read taxonomy from headers, otherwise use default values for given corpus
|
||||
ObservableList<String> tax = corpus.getTaxonomy();
|
||||
taxonomyCCBValues = tax != null ? tax : Taxonomy.getDefaultForComboBox(corpus.getCorpusType());
|
||||
|
||||
currentCorpusType = corpus.getCorpusType();
|
||||
// setTaxonomyIsDirty(false);
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
// see if we read taxonomy from headers, otherwise use default values for given corpus
|
||||
ObservableList<String> tax = corpus.getTaxonomy();
|
||||
taxonomyCCBValues = tax != null ? tax : Taxonomy.getDefaultForComboBox(corpus.getCorpusType());
|
||||
taxonomyCCB.getItems().addAll(taxonomyCCBValues);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles visibility for panes which hold fields for skipgram value (not applicable when calculating for letters) etc.,
|
||||
* sets combobox values to what is applicable ...
|
||||
*
|
||||
* @param mode
|
||||
*/
|
||||
public void toggleMode(MODE mode) {
|
||||
if (mode == null) {
|
||||
mode = currentMode;
|
||||
}
|
||||
|
||||
logger.info("mode: ", mode.toString());
|
||||
|
||||
if (mode == MODE.LETTER) {
|
||||
paneLetters.setVisible(true);
|
||||
|
||||
// populate with default cvv length value
|
||||
if (stringLength == null) {
|
||||
stringLengthTF.setText("1");
|
||||
stringLength = 1;
|
||||
} else {
|
||||
stringLengthTF.setText(String.valueOf(stringLength));
|
||||
}
|
||||
|
||||
// if calculateFor was selected for something other than a word or a lemma -> reset
|
||||
if (!(calculateFor == CalculateFor.WORD || calculateFor == CalculateFor.LEMMA)) {
|
||||
// if the user selected something else before selecting ngram for letters, reset that choice
|
||||
calculateFor = CalculateFor.LEMMA;
|
||||
calculateForRB.selectToggle(lemmaRB);
|
||||
}
|
||||
}
|
||||
|
||||
// override if orth mode, allow only word
|
||||
if (corpus.isGosOrthMode()) {
|
||||
// TODO change to
|
||||
varietyRB.setDisable(true);
|
||||
msdTF.setDisable(true);
|
||||
} else {
|
||||
msdTF.setDisable(false);
|
||||
varietyRB.setDisable(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void compute() {
|
||||
Filter filter = new Filter();
|
||||
filter.setNgramValue(0);
|
||||
filter.setCalculateFor(calculateFor);
|
||||
filter.setMsd(msd);
|
||||
filter.setTaxonomy(Tax.getTaxonomyCodes(taxonomy, corpus.getCorpusType()));
|
||||
filter.setAl(AnalysisLevel.STRING_LEVEL);
|
||||
filter.setSkipValue(0);
|
||||
filter.setIsCvv(calculateCvv);
|
||||
filter.setSolarFilters(solarFiltersMap);
|
||||
filter.setStringLength(stringLength);
|
||||
|
||||
String message = Validation.validateForStringLevel(filter);
|
||||
if (message == null) {
|
||||
// no errors
|
||||
logger.info("Executing: ", filter.toString());
|
||||
StatisticsNew statistic = new StatisticsNew(corpus, filter, useDb);
|
||||
execute(statistic);
|
||||
} else {
|
||||
logAlert(message);
|
||||
showAlert(Alert.AlertType.ERROR, "Prosim izpolnite polja:", message);
|
||||
}
|
||||
}
|
||||
|
||||
private void openHelpWebsite(){
|
||||
hostService.showDocument(Messages.HELP_URL);
|
||||
}
|
||||
|
||||
private void logAlert(String alert) {
|
||||
logger.info("alert: " + alert);
|
||||
}
|
||||
|
||||
public Corpus getCorpus() {
|
||||
return corpus;
|
||||
}
|
||||
|
||||
public void setCorpus(Corpus corpus) {
|
||||
this.corpus = corpus;
|
||||
|
||||
if (corpus.getCorpusType() != CorpusType.SOLAR) {
|
||||
setSelectedFiltersLabel(null);
|
||||
} else {
|
||||
setSelectedFiltersLabel("/");
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelectedFiltersLabel(String content) {
|
||||
if (content != null) {
|
||||
solarFilters.setVisible(true);
|
||||
selectedFiltersLabel.setVisible(true);
|
||||
selectedFiltersLabel.setText(content);
|
||||
} else {
|
||||
solarFilters.setVisible(false);
|
||||
selectedFiltersLabel.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void execute(StatisticsNew statistic) {
|
||||
logger.info("Started execution: ", statistic.getFilter());
|
||||
|
||||
Collection<File> corpusFiles = statistic.getCorpus().getDetectedCorpusFiles();
|
||||
boolean corpusIsSplit = corpusFiles.size() > 1;
|
||||
|
||||
final Task<Void> task = new Task<Void>() {
|
||||
@SuppressWarnings("Duplicates")
|
||||
@Override
|
||||
protected Void call() throws Exception {
|
||||
long i = 0;
|
||||
for (File f : corpusFiles) {
|
||||
readXML(f.toString(), statistic);
|
||||
i++;
|
||||
this.updateProgress(i, corpusFiles.size());
|
||||
this.updateMessage(String.format(ONGOING_NOTIFICATION_ANALYZING_FILE_X_OF_Y, i, corpusFiles.size(), f.getName()));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
ngramProgressBar.progressProperty().bind(task.progressProperty());
|
||||
progressLabel.textProperty().bind(task.messageProperty());
|
||||
|
||||
task.setOnSucceeded(e -> {
|
||||
try {
|
||||
boolean successullySaved = statistic.saveResultToDisk();
|
||||
if (successullySaved) {
|
||||
showAlert(Alert.AlertType.INFORMATION, Messages.NOTIFICATION_ANALYSIS_COMPLETED);
|
||||
} else {
|
||||
showAlert(Alert.AlertType.INFORMATION, Messages.NOTIFICATION_ANALYSIS_COMPLETED_NO_RESULTS);
|
||||
}
|
||||
} catch (UnsupportedEncodingException e1) {
|
||||
showAlert(Alert.AlertType.ERROR, ERROR_WHILE_SAVING_RESULTS_TO_CSV);
|
||||
logger.error("Error while saving", e1);
|
||||
}
|
||||
|
||||
ngramProgressBar.progressProperty().unbind();
|
||||
ngramProgressBar.setStyle(Settings.FX_ACCENT_OK);
|
||||
progressLabel.textProperty().unbind();
|
||||
progressLabel.setText("");
|
||||
});
|
||||
|
||||
task.setOnFailed(e -> {
|
||||
showAlert(Alert.AlertType.ERROR, ERROR_WHILE_EXECUTING);
|
||||
logger.error("Error while executing", e);
|
||||
ngramProgressBar.progressProperty().unbind();
|
||||
ngramProgressBar.setProgress(0.0);
|
||||
ngramProgressBar.setStyle(Settings.FX_ACCENT_NOK);
|
||||
progressLabel.textProperty().unbind();
|
||||
progressLabel.setText("");
|
||||
});
|
||||
|
||||
final Thread thread = new Thread(task, "task");
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public void setSolarFiltersMap(HashMap<String, HashSet<String>> solarFiltersMap) {
|
||||
this.solarFiltersMap = solarFiltersMap;
|
||||
}
|
||||
|
||||
public void setHostServices(HostServices hostServices){
|
||||
this.hostService = hostServices;
|
||||
}
|
||||
}
|
||||
517
src/main/java/gui/CorpusTab.java
Normal file
517
src/main/java/gui/CorpusTab.java
Normal file
@@ -0,0 +1,517 @@
|
||||
package gui;
|
||||
|
||||
import static data.CorpusType.*;
|
||||
import static gui.GUIController.*;
|
||||
import static gui.Messages.*;
|
||||
import static util.Util.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOCase;
|
||||
import org.apache.commons.io.filefilter.FileFilterUtils;
|
||||
import org.apache.commons.io.filefilter.TrueFileFilter;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import alg.XML_processing;
|
||||
import data.Corpus;
|
||||
import data.CorpusType;
|
||||
import data.Enums.solar.SolarFilters;
|
||||
import data.Tax;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.application.HostServices;
|
||||
|
||||
public class CorpusTab {
|
||||
public final static Logger logger = LogManager.getLogger(CorpusTab.class);
|
||||
public Pane setCorpusWrapperP;
|
||||
|
||||
private Stage stage;
|
||||
|
||||
@FXML
|
||||
private Button chooseCorpusLocationB;
|
||||
private File chosenCorpusLocation;
|
||||
|
||||
@FXML
|
||||
private CheckBox readHeaderInfoChB;
|
||||
private boolean readHeaderInfo;
|
||||
|
||||
@FXML
|
||||
private CheckBox gosUseOrthChB;
|
||||
private boolean gosUseOrth;
|
||||
|
||||
@FXML
|
||||
private Button chooseResultsLocationB;
|
||||
|
||||
@FXML
|
||||
private Label chooseCorpusL;
|
||||
private String chooseCorpusLabelContent;
|
||||
|
||||
@FXML
|
||||
private Label chooseResultsL;
|
||||
private String chooseResultsLabelContent;
|
||||
|
||||
@FXML
|
||||
private ProgressIndicator locationScanPI;
|
||||
|
||||
@FXML
|
||||
private Hyperlink helpH;
|
||||
|
||||
// *** shared ***
|
||||
private Corpus corpus;
|
||||
private CorpusType corpusType;
|
||||
|
||||
// tabs - used to enable/disable
|
||||
private Tab stringLevelTabNew2;
|
||||
private Tab oneWordAnalysisTab;
|
||||
private Tab characterLevelTab;
|
||||
private Tab wordFormationTab;
|
||||
private Tab wordLevelTab;
|
||||
private Tab filterTab;
|
||||
private TabPane tabPane;
|
||||
private StringAnalysisTabNew2 satNew2Controller;
|
||||
private OneWordAnalysisTab oneWordTabController;
|
||||
private CharacterAnalysisTab catController;
|
||||
private FiltersForSolar ffsController;
|
||||
//private WordFormationTab wfController;
|
||||
private WordLevelTab wlController;
|
||||
private HostServices hostService;
|
||||
|
||||
|
||||
public void initialize() {
|
||||
stage = new Stage();
|
||||
|
||||
// add listeners
|
||||
chooseCorpusLocationB.setOnAction(e -> chooseCorpusLocation());
|
||||
chooseCorpusLocationB.setTooltip(new Tooltip(TOOLTIP_chooseCorpusLocationB));
|
||||
helpH.setOnAction(e -> openHelpWebsite());
|
||||
|
||||
readHeaderInfoChB.selectedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
readHeaderInfo = newValue;
|
||||
logger.info("read headers: ", readHeaderInfo);
|
||||
});
|
||||
readHeaderInfoChB.setTooltip(new Tooltip(TOOLTIP_readHeaderInfoChB));
|
||||
|
||||
gosUseOrthChB.selectedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
gosUseOrth = newValue;
|
||||
corpus.setGosOrthMode(gosUseOrth);
|
||||
wordFormationTab.setDisable(gosUseOrth);
|
||||
satNew2Controller.toggleMode(null);
|
||||
oneWordTabController.toggleMode(null);
|
||||
catController.toggleMode(null);
|
||||
|
||||
logger.info("gosUseOrth: ", gosUseOrth);
|
||||
});
|
||||
|
||||
chooseResultsLocationB.setOnAction(e -> chooseResultsLocation(null));
|
||||
|
||||
// set labels and toggle visibility
|
||||
toggleGosChBVisibility();
|
||||
|
||||
chooseCorpusLabelContent = Messages.LABEL_CORPUS_LOCATION_NOT_SET;
|
||||
chooseCorpusL.setText(chooseCorpusLabelContent);
|
||||
|
||||
chooseResultsLabelContent = Messages.LABEL_RESULTS_LOCATION_NOT_SET;
|
||||
chooseResultsL.setText(chooseResultsLabelContent);
|
||||
|
||||
togglePiAndSetCorpusWrapper(false);
|
||||
}
|
||||
|
||||
private void togglePiAndSetCorpusWrapper(boolean piIsActive) {
|
||||
locationScanPI.setVisible(piIsActive);
|
||||
setCorpusWrapperP.setLayoutX(piIsActive ? 100.0 : 10.0);
|
||||
}
|
||||
|
||||
private void openHelpWebsite(){
|
||||
hostService.showDocument(Messages.HELP_URL);
|
||||
}
|
||||
|
||||
/**
|
||||
* In order for a directory to pass as a valid corpus location, following criteria has to be met:
|
||||
* <ul>
|
||||
* <li>it can't be null</li>
|
||||
* <li>it has to be readable</li>
|
||||
* <li>it has to contain xml files</li>
|
||||
* <li>xml files have to contain valid headers from which we can infer the corpus type</li>
|
||||
* <li>corpus type must be one of the expected corpus types - as noted in the @see data.CorpusType.class </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Additionally, if the user checks to read taxonomy/filters from the corpus files, that read
|
||||
* has to produce a non-empty list results list
|
||||
*/
|
||||
private void chooseCorpusLocation() {
|
||||
File selectedDirectory = directoryChooser();
|
||||
|
||||
if (selectedDirectory != null && ValidationUtil.isReadableDirectory(selectedDirectory)) {
|
||||
logger.info("selected corpus dir: ", selectedDirectory.getAbsolutePath());
|
||||
|
||||
// scan for xml files
|
||||
Collection<File> corpusFiles = FileUtils.listFiles(selectedDirectory, FileFilterUtils.suffixFileFilter("xml", IOCase.INSENSITIVE), TrueFileFilter.INSTANCE);
|
||||
|
||||
// make sure there are corpus files in selected directory or notify the user about it
|
||||
if (corpusFiles.size() == 0) {
|
||||
logger.info("alert: ", WARNING_CORPUS_NOT_FOUND);
|
||||
showAlert(Alert.AlertType.ERROR, WARNING_CORPUS_NOT_FOUND, null);
|
||||
} else {
|
||||
String chooseCorpusLabelContentTmp = detectCorpusType(corpusFiles, selectedDirectory.getAbsolutePath());
|
||||
|
||||
if (chooseCorpusLabelContentTmp == null) {
|
||||
logger.info("alert: ", WARNING_CORPUS_NOT_FOUND);
|
||||
showAlert(Alert.AlertType.ERROR, WARNING_CORPUS_NOT_FOUND, null);
|
||||
} else {
|
||||
initNewCorpus(selectedDirectory, corpusFiles);
|
||||
|
||||
corpus.setChosenCorpusLocation(selectedDirectory);
|
||||
corpus.setDetectedCorpusFiles(corpusFiles);
|
||||
chooseCorpusLabelContent = chooseCorpusLabelContentTmp;
|
||||
logger.info("corpus dir: ", corpus.getChosenCorpusLocation().getAbsolutePath());
|
||||
|
||||
if (readHeaderInfo) {
|
||||
logger.info("reading header info...");
|
||||
readHeaderInfo();
|
||||
} else {
|
||||
setResults();
|
||||
|
||||
setCorpusForAnalysis();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If a user selects a valid corpus location, we define a new corpus (so none of the old data gets carried over)
|
||||
*
|
||||
* @param selectedDirectory
|
||||
* @param corpusFiles
|
||||
*/
|
||||
private void initNewCorpus(File selectedDirectory, Collection<File> corpusFiles) {
|
||||
corpus = new Corpus();
|
||||
corpus.setCorpusType(corpusType);
|
||||
corpus.setDetectedCorpusFiles(corpusFiles);
|
||||
corpus.setChosenCorpusLocation(selectedDirectory);
|
||||
chooseResultsLocation(selectedDirectory);
|
||||
}
|
||||
|
||||
private void chooseResultsLocation(File dir) {
|
||||
// results location can be set either to default value (after selecting valid corpus location) - dir attribute
|
||||
// or to a dir picked via directoryChooser (when dir == null
|
||||
File selectedDirectory = dir == null ? directoryChooser() : dir;
|
||||
|
||||
if (selectedDirectory != null) {
|
||||
String resultsLocationPath = selectedDirectory.getAbsolutePath().concat(File.separator);
|
||||
File chosenResultsLocationTmp = new File(resultsLocationPath);
|
||||
|
||||
if (!ValidationUtil.isValidDirectory(chosenResultsLocationTmp)) {
|
||||
showAlert(Alert.AlertType.ERROR, WARNING_RESULTS_DIR_NOT_VALID);
|
||||
logger.info("alert: ", WARNING_RESULTS_DIR_NOT_VALID);
|
||||
} else {
|
||||
corpus.setChosenResultsLocation(chosenResultsLocationTmp);
|
||||
chooseResultsLabelContent = corpus.getChosenResultsLocation().getAbsolutePath();
|
||||
chooseResultsL.setText(chooseResultsLabelContent);
|
||||
logger.info("results dir: " + chooseResultsLabelContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setResults() {
|
||||
// if everything is ok
|
||||
// check and enable checkbox if GOS
|
||||
toggleGosChBVisibility();
|
||||
|
||||
// set default results location
|
||||
String defaultResultsLocationPath = corpus.getChosenCorpusLocation().getAbsolutePath();
|
||||
logger.info("setting default results location to: ", defaultResultsLocationPath);
|
||||
|
||||
chooseCorpusL.setText(chooseCorpusLabelContent);
|
||||
}
|
||||
|
||||
private void readHeaderInfo() {
|
||||
CorpusType corpusType = corpus.getCorpusType();
|
||||
Collection<File> corpusFiles = corpus.getDetectedCorpusFiles();
|
||||
togglePiAndSetCorpusWrapper(true);
|
||||
chooseCorpusL.setText(LABEL_SCANNING_CORPUS);
|
||||
|
||||
logger.info("reading header data for ", corpusType.toString());
|
||||
|
||||
if (corpusType == CorpusType.GIGAFIDA || corpusType == CorpusType.GOS || corpusType == CorpusType.CCKRES) {
|
||||
boolean corpusIsSplit = corpusFiles.size() > 1;
|
||||
|
||||
final Task<HashSet<String>> task = new Task<HashSet<String>>() {
|
||||
@Override
|
||||
protected HashSet<String> call() throws Exception {
|
||||
HashSet<String> values = new HashSet<>();
|
||||
long i = 0;
|
||||
|
||||
if (!corpusIsSplit) {
|
||||
updateProgress(-1.0f, -1.0f);
|
||||
}
|
||||
|
||||
for (File file : corpusFiles) {
|
||||
values.addAll((Collection<? extends String>) XML_processing.readXmlHeaderTaxonomyAndFilters(file.getAbsolutePath(), corpusIsSplit, corpusType));
|
||||
i++;
|
||||
|
||||
if (corpusIsSplit) {
|
||||
updateProgress(i, corpusFiles.size());
|
||||
}
|
||||
}
|
||||
|
||||
updateProgress(1.0f, 1.0f);
|
||||
return values;
|
||||
}
|
||||
};
|
||||
|
||||
locationScanPI.progressProperty().bind(task.progressProperty());
|
||||
|
||||
task.setOnSucceeded(e -> {
|
||||
ObservableList<String> readTaxonomy = Tax.getTaxonomyForComboBox(corpusType, task.getValue());
|
||||
|
||||
if (ValidationUtil.isEmpty(readTaxonomy)) {
|
||||
// if no taxonomy found alert the user and keep other tabs disabled
|
||||
logger.info("No taxonomy found in headers.");
|
||||
GUIController.showAlert(Alert.AlertType.ERROR, WARNING_NO_TAXONOMY_FOUND);
|
||||
} else {
|
||||
// set taxonomy, update label
|
||||
corpus.setTaxonomy(readTaxonomy);
|
||||
corpus.setHeaderRead(true);
|
||||
chooseCorpusL.setText(chooseCorpusLabelContent);
|
||||
setResults();
|
||||
setCorpusForAnalysis();
|
||||
}
|
||||
|
||||
togglePiAndSetCorpusWrapper(false);
|
||||
|
||||
});
|
||||
|
||||
task.setOnCancelled(e -> togglePiAndSetCorpusWrapper(false));
|
||||
task.setOnFailed(e -> togglePiAndSetCorpusWrapper(false));
|
||||
|
||||
final Thread thread = new Thread(task, "task");
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
} else if (corpusType == CorpusType.SOLAR) {
|
||||
// many many fields
|
||||
boolean corpusIsSplit = corpusFiles.size() > 1;
|
||||
|
||||
final Task<HashMap<String, HashSet<String>>> task = new Task<HashMap<String, HashSet<String>>>() {
|
||||
@Override
|
||||
protected HashMap<String, HashSet<String>> call() throws Exception {
|
||||
HashMap<String, HashSet<String>> values = new HashMap<>();
|
||||
long i = 0;
|
||||
|
||||
if (!corpusIsSplit) {
|
||||
updateProgress(-1.0f, -1.0f);
|
||||
}
|
||||
|
||||
for (File file : corpusFiles) {
|
||||
HashMap<String, HashSet<String>> tmpvalues = (HashMap<String, HashSet<String>>) XML_processing.readXmlHeaderTaxonomyAndFilters(file.getAbsolutePath(), corpusIsSplit, corpusType);
|
||||
|
||||
// update final results
|
||||
for (Map.Entry<String, HashSet<String>> entry : tmpvalues.entrySet()) {
|
||||
if (values.containsKey(entry.getKey())) {
|
||||
values.get(entry.getKey()).addAll(entry.getValue());
|
||||
} else {
|
||||
values.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
if (corpusIsSplit) {
|
||||
updateProgress(i, corpusFiles.size());
|
||||
}
|
||||
}
|
||||
|
||||
updateProgress(1.0f, 1.0f);
|
||||
return values;
|
||||
}
|
||||
};
|
||||
|
||||
locationScanPI.progressProperty().bind(task.progressProperty());
|
||||
|
||||
task.setOnSucceeded(e -> {
|
||||
HashMap<String, HashSet<String>> values = task.getValue();
|
||||
|
||||
if (ValidationUtil.isEmpty(values)) {
|
||||
// if no taxonomy found alert the user and keep other tabs disabled
|
||||
logger.info("No solar filters found in headers.");
|
||||
GUIController.showAlert(Alert.AlertType.ERROR, WARNING_NO_SOLAR_FILTERS_FOUND);
|
||||
} else {
|
||||
HashMap<String, ObservableList<String>> filtersForComboBoxes = SolarFilters.getFiltersForComboBoxes(values);
|
||||
// set taxonomy, update label
|
||||
corpus.setSolarFiltersForXML(values);
|
||||
corpus.setSolarFilters(filtersForComboBoxes);
|
||||
corpus.setHeaderRead(true);
|
||||
chooseCorpusL.setText(chooseCorpusLabelContent);
|
||||
setResults();
|
||||
setCorpusForAnalysis();
|
||||
}
|
||||
|
||||
togglePiAndSetCorpusWrapper(false);
|
||||
|
||||
});
|
||||
|
||||
task.setOnCancelled(e -> togglePiAndSetCorpusWrapper(false));
|
||||
task.setOnFailed(e -> togglePiAndSetCorpusWrapper(false));
|
||||
|
||||
final Thread thread = new Thread(task, "task");
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setCorpusForAnalysis() {
|
||||
if (corpus.validate()) {
|
||||
// new statistic, enable tabs...
|
||||
stringLevelTabNew2.setDisable(false);
|
||||
satNew2Controller.setCorpus(corpus);
|
||||
satNew2Controller.init();
|
||||
oneWordAnalysisTab.setDisable(false);
|
||||
oneWordTabController.setCorpus(corpus);
|
||||
oneWordTabController.init();
|
||||
characterLevelTab.setDisable(false);
|
||||
catController.setCorpus(corpus);
|
||||
catController.init();
|
||||
wordFormationTab.setDisable(false);
|
||||
wordLevelTab.setDisable(false);
|
||||
//wfController.setCorpus(corpus);
|
||||
//wfController.init();
|
||||
wlController.setCorpus(corpus);
|
||||
wlController.init();
|
||||
|
||||
if (corpus.getCorpusType() == CorpusType.SOLAR) {
|
||||
filterTab.setDisable(false);
|
||||
tabPane.getTabs().add(1, filterTab);
|
||||
ffsController.setCorpus(corpus);
|
||||
ffsController.initFilters();
|
||||
} else {
|
||||
filterTab.setDisable(true);
|
||||
tabPane.getTabs().removeAll(filterTab);
|
||||
}
|
||||
} else {
|
||||
GUIController.showAlert(Alert.AlertType.ERROR, corpus.getValidationErrorsToString());
|
||||
}
|
||||
}
|
||||
|
||||
private File directoryChooser() {
|
||||
DirectoryChooser directoryChooser = new DirectoryChooser();
|
||||
|
||||
// open in the folder where the jar is located if possible
|
||||
File workingDir = getWorkingDirectory();
|
||||
|
||||
if (workingDir != null) {
|
||||
directoryChooser.setInitialDirectory(workingDir);
|
||||
}
|
||||
|
||||
return directoryChooser.showDialog(stage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides GOS related checkbox until needed.
|
||||
*/
|
||||
private void toggleGosChBVisibility() {
|
||||
gosUseOrthChB.setVisible(corpus != null && corpus.getCorpusType() != null && corpus.getCorpusType() == CorpusType.GOS);
|
||||
}
|
||||
|
||||
private String detectCorpusType(Collection<File> corpusFiles, String corpusLocation) {
|
||||
// check that we recognize this corpus
|
||||
// read first file only, maybe later do all, if toll on resources is acceptable
|
||||
File f = corpusFiles.iterator().next();
|
||||
String title = XML_processing.readXMLHeaderTag(f.getAbsolutePath(), "title").toLowerCase();
|
||||
String test = CCKRES.getNameLowerCase();
|
||||
String debug = "";
|
||||
|
||||
// check if XML file's title contains any of recognized corpus titles
|
||||
corpusType = null;
|
||||
if (title.contains(SOLAR.getNameLowerCase())) {
|
||||
corpusType = SOLAR;
|
||||
} else if (title.contains(GIGAFIDA.getNameLowerCase())) {
|
||||
corpusType = GIGAFIDA;
|
||||
} else if (title.contains(CCKRES.getNameLowerCase())) {
|
||||
corpusType = CCKRES;
|
||||
} else if (title.contains(GOS.getNameLowerCase())) {
|
||||
corpusType = GOS;
|
||||
}
|
||||
|
||||
if (corpusType == null) {
|
||||
return null;
|
||||
} else {
|
||||
corpus.setCorpusType(corpusType);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(corpusLocation)
|
||||
.append("\n")
|
||||
.append(String.format(NOTIFICATION_FOUND_X_FILES, corpusFiles.size()))
|
||||
.append("\n")
|
||||
.append(String.format("Korpus: %s", corpusType.toString()));
|
||||
|
||||
String result = sb.toString();
|
||||
|
||||
logger.debug(result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public Corpus getCorpus() {
|
||||
return corpus;
|
||||
}
|
||||
|
||||
public void setCorpus(Corpus corpus) {
|
||||
this.corpus = corpus;
|
||||
}
|
||||
|
||||
public void setStringLevelTabNew2(Tab stringLevelTabNew2) { this.stringLevelTabNew2 = stringLevelTabNew2; }
|
||||
|
||||
public void setOneWordAnalysisTab(Tab oneWordAnalysisTab) { this.oneWordAnalysisTab = oneWordAnalysisTab; }
|
||||
|
||||
public void setCharacterLevelTab(Tab characterLevelTab) { this.characterLevelTab = characterLevelTab; }
|
||||
|
||||
public void setWordLevelTab(Tab wordLevelTab) {
|
||||
this.wordLevelTab = wordLevelTab;
|
||||
}
|
||||
|
||||
public void setFilterTab(Tab filterTab) {
|
||||
this.filterTab = filterTab;
|
||||
}
|
||||
|
||||
public void setFfsController(FiltersForSolar ffsController) {
|
||||
this.ffsController = ffsController;
|
||||
}
|
||||
|
||||
public void setTabPane(TabPane tabPane) {
|
||||
this.tabPane = tabPane;
|
||||
}
|
||||
|
||||
public void setSatNew2Controller(StringAnalysisTabNew2 satNew2Controller) { this.satNew2Controller = satNew2Controller; }
|
||||
|
||||
public void setOneWordTabController(OneWordAnalysisTab oneWordTabController) { this.oneWordTabController = oneWordTabController; }
|
||||
|
||||
public void setCatController(CharacterAnalysisTab catController) { this.catController = catController; }
|
||||
|
||||
/*public void setWfController(WordFormationTab wfController) {
|
||||
this.wfController = wfController;
|
||||
}*/
|
||||
|
||||
public void setWlController(WordLevelTab wlController) {
|
||||
this.wlController = wlController;
|
||||
}
|
||||
|
||||
public void setWordFormationTab(Tab wordFormationTab) {
|
||||
this.wordFormationTab = wordFormationTab;
|
||||
}
|
||||
|
||||
public void setHostServices(HostServices hostServices){
|
||||
this.hostService = hostServices;
|
||||
}
|
||||
}
|
||||
187
src/main/java/gui/FiltersForSolar.java
Normal file
187
src/main/java/gui/FiltersForSolar.java
Normal file
@@ -0,0 +1,187 @@
|
||||
package gui;
|
||||
|
||||
import static data.Enums.solar.SolarFilters.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
||||
import javafx.application.HostServices;
|
||||
import javafx.scene.control.Hyperlink;
|
||||
import org.controlsfx.control.CheckComboBox;
|
||||
|
||||
import data.Corpus;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import util.Util;
|
||||
|
||||
public class FiltersForSolar {
|
||||
|
||||
@FXML
|
||||
public AnchorPane solarFiltersTabPane;
|
||||
@FXML
|
||||
public CheckComboBox<String> solarRegijaCCB;
|
||||
@FXML
|
||||
public CheckComboBox<String> solarPredmetCCB;
|
||||
@FXML
|
||||
public CheckComboBox<String> solarRazredCCB;
|
||||
@FXML
|
||||
public CheckComboBox<String> solarLetoCCB;
|
||||
@FXML
|
||||
public CheckComboBox<String> solarSolaCCB;
|
||||
@FXML
|
||||
public CheckComboBox<String> solarVrstaBesedilaCCB;
|
||||
@FXML
|
||||
public Label selectedFiltersLabel;
|
||||
@FXML
|
||||
private Hyperlink helpH;
|
||||
|
||||
private HashMap<String, ObservableList<String>> selectedFilters;
|
||||
private Corpus corpus;
|
||||
|
||||
private StringAnalysisTabNew2 satNew2Controller;
|
||||
private OneWordAnalysisTab oneWordTabController;
|
||||
private CharacterAnalysisTab catController;
|
||||
//private WordFormationTab wfController;
|
||||
private WordLevelTab wlController;
|
||||
private HostServices hostService;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void initialize() {
|
||||
selectedFilters = new HashMap<>();
|
||||
|
||||
solarRegijaCCB.getCheckModel().getCheckedItems().addListener((ListChangeListener) c -> {
|
||||
selectedFilters.put(REGIJA, solarRegijaCCB.getCheckModel().getCheckedItems());
|
||||
updateSolarFilterLabel();
|
||||
});
|
||||
|
||||
solarPredmetCCB.getCheckModel().getCheckedItems().addListener((ListChangeListener) c -> {
|
||||
selectedFilters.put(PREDMET, solarPredmetCCB.getCheckModel().getCheckedItems());
|
||||
updateSolarFilterLabel();
|
||||
});
|
||||
|
||||
solarRazredCCB.getCheckModel().getCheckedItems().addListener((ListChangeListener) c -> {
|
||||
selectedFilters.put(RAZRED, solarRazredCCB.getCheckModel().getCheckedItems());
|
||||
updateSolarFilterLabel();
|
||||
});
|
||||
|
||||
solarLetoCCB.getCheckModel().getCheckedItems().addListener((ListChangeListener) c -> {
|
||||
selectedFilters.put(LETO, solarLetoCCB.getCheckModel().getCheckedItems());
|
||||
updateSolarFilterLabel();
|
||||
});
|
||||
|
||||
solarSolaCCB.getCheckModel().getCheckedItems().addListener((ListChangeListener) c -> {
|
||||
selectedFilters.put(SOLA, solarSolaCCB.getCheckModel().getCheckedItems());
|
||||
updateSolarFilterLabel();
|
||||
});
|
||||
|
||||
solarVrstaBesedilaCCB.getCheckModel().getCheckedItems().addListener((ListChangeListener) c -> {
|
||||
selectedFilters.put(TIP, solarVrstaBesedilaCCB.getCheckModel().getCheckedItems());
|
||||
updateSolarFilterLabel();
|
||||
});
|
||||
|
||||
helpH.setOnAction(e -> openHelpWebsite());
|
||||
}
|
||||
|
||||
public void initFilters() {
|
||||
solarRegijaCCB.getItems().removeAll();
|
||||
solarRegijaCCB.getItems().setAll(corpus.getSolarFilters().get(REGIJA));
|
||||
solarRegijaCCB.getItems().sorted();
|
||||
solarPredmetCCB.getItems().removeAll();
|
||||
solarPredmetCCB.getItems().setAll(corpus.getSolarFilters().get(PREDMET));
|
||||
solarPredmetCCB.getItems().sorted();
|
||||
solarRazredCCB.getItems().removeAll();
|
||||
solarRazredCCB.getItems().setAll(corpus.getSolarFilters().get(RAZRED));
|
||||
solarRazredCCB.getItems().sorted();
|
||||
solarLetoCCB.getItems().removeAll();
|
||||
solarLetoCCB.getItems().setAll(corpus.getSolarFilters().get(LETO));
|
||||
solarLetoCCB.getItems().sorted();
|
||||
solarSolaCCB.getItems().removeAll();
|
||||
solarSolaCCB.getItems().setAll(corpus.getSolarFilters().get(SOLA));
|
||||
solarSolaCCB.getItems().sorted();
|
||||
solarVrstaBesedilaCCB.getItems().removeAll();
|
||||
solarVrstaBesedilaCCB.getItems().setAll(corpus.getSolarFilters().get(TIP));
|
||||
solarVrstaBesedilaCCB.getItems().sorted();
|
||||
}
|
||||
|
||||
private void updateSolarFilterLabel() {
|
||||
if (Util.isMapEmpty(selectedFilters)) {
|
||||
setSOlarFIlterLabelText("/");
|
||||
} else {
|
||||
StringBuilder allFilters = new StringBuilder();
|
||||
for (Map.Entry<String, ObservableList<String>> entry : selectedFilters.entrySet()) {
|
||||
ArrayList<String> values = new ArrayList<>(entry.getValue());
|
||||
|
||||
if (!values.isEmpty()) {
|
||||
allFilters.append(entry.getKey())
|
||||
.append(": ");
|
||||
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
allFilters.append(values.get(i));
|
||||
|
||||
if (i < values.size() - 1) {
|
||||
// so we won't append a comma after the last element
|
||||
allFilters.append(", ");
|
||||
}
|
||||
}
|
||||
allFilters.append("\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
setSOlarFIlterLabelText(allFilters.toString());
|
||||
}
|
||||
|
||||
HashMap<String, HashSet<String>> solarFiltersMap = new HashMap<>();
|
||||
for (Map.Entry<String, ObservableList<String>> e : selectedFilters.entrySet()) {
|
||||
HashSet<String> values = new HashSet<>();
|
||||
values.addAll(e.getValue());
|
||||
|
||||
solarFiltersMap.put(e.getKey(), values);
|
||||
}
|
||||
|
||||
satNew2Controller.setSolarFiltersMap(solarFiltersMap);
|
||||
oneWordTabController.setSolarFiltersMap(solarFiltersMap);
|
||||
catController.setSolarFiltersMap(solarFiltersMap);
|
||||
//wfController.setSolarFiltersMap(solarFiltersMap);
|
||||
wlController.setSolarFiltersMap(solarFiltersMap);
|
||||
}
|
||||
|
||||
private void openHelpWebsite(){
|
||||
hostService.showDocument(Messages.HELP_URL);
|
||||
}
|
||||
|
||||
private void setSOlarFIlterLabelText(String content) {
|
||||
selectedFiltersLabel.setText(content);
|
||||
satNew2Controller.setSelectedFiltersLabel(content);
|
||||
oneWordTabController.setSelectedFiltersLabel(content);
|
||||
catController.setSelectedFiltersLabel(content);
|
||||
//wfController.setSelectedFiltersLabel(content);
|
||||
wlController.setSelectedFiltersLabel(content);
|
||||
}
|
||||
|
||||
public void setCorpus(Corpus corpus) {
|
||||
this.corpus = corpus;
|
||||
}
|
||||
|
||||
public void setSatNew2Controller(StringAnalysisTabNew2 satNew2Controller) { this.satNew2Controller = satNew2Controller; }
|
||||
|
||||
public void setOneWordTabController(OneWordAnalysisTab oneWordTabController) { this.oneWordTabController = oneWordTabController; }
|
||||
|
||||
public void setCatController(CharacterAnalysisTab catController) { this.catController = catController; }
|
||||
|
||||
/*public void setWfController(WordFormationTab wfController) {
|
||||
this.wfController = wfController;
|
||||
}*/
|
||||
|
||||
public void setWlController(WordLevelTab wlController) {
|
||||
this.wlController = wlController;
|
||||
}
|
||||
|
||||
public void setHostServices(HostServices hostServices){
|
||||
this.hostService = hostServices;
|
||||
}
|
||||
}
|
||||
150
src/main/java/gui/GUIController.java
Normal file
150
src/main/java/gui/GUIController.java
Normal file
@@ -0,0 +1,150 @@
|
||||
package gui;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.kordamp.ikonli.fontawesome.FontAwesome;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import data.Corpus;
|
||||
import javafx.application.Application;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TabPane;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class GUIController extends Application {
|
||||
public final static Logger logger = LogManager.getLogger(GUIController.class);
|
||||
|
||||
@FXML
|
||||
public Tab StringLevelTabNew2;
|
||||
@FXML
|
||||
public Tab OneWordAnalysisTab;
|
||||
@FXML
|
||||
public Tab CharacterLevelTabNew;
|
||||
@FXML
|
||||
public Tab corpusTab;
|
||||
public TabPane tabPane;
|
||||
@FXML
|
||||
private CharacterAnalysisTab catController;
|
||||
@FXML
|
||||
private static Parent sat;
|
||||
@FXML
|
||||
private StringAnalysisTabNew2 satNew2Controller;
|
||||
@FXML
|
||||
private static Parent satNew2;
|
||||
@FXML
|
||||
private OneWordAnalysisTab oneWordTabController;
|
||||
@FXML
|
||||
private static Parent oneWordTab;
|
||||
@FXML
|
||||
private CorpusTab ctController;
|
||||
@FXML
|
||||
private Parent ct;
|
||||
//@FXML
|
||||
//private WordFormationTab wfController;
|
||||
@FXML
|
||||
private Parent wf;
|
||||
@FXML
|
||||
private WordLevelTab wlController;
|
||||
@FXML
|
||||
private Parent wl;
|
||||
@FXML
|
||||
private FiltersForSolar ffsController;
|
||||
@FXML
|
||||
private Parent ffs;
|
||||
@FXML
|
||||
private SelectedFiltersPane sfpController;
|
||||
@FXML
|
||||
private Parent sfp;
|
||||
@FXML
|
||||
public Tab stringLevelTab;
|
||||
@FXML
|
||||
public Tab wordLevelTab;
|
||||
/*@FXML
|
||||
public Tab wordFormationTab;*/
|
||||
|
||||
|
||||
@FXML
|
||||
public Tab filterTab;
|
||||
public Stage stage;
|
||||
|
||||
private Corpus corpus;
|
||||
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Parent root = FXMLLoader.load(getClass().getResource("/GUI.fxml"));
|
||||
primaryStage.setTitle("GUI");
|
||||
Scene scene = new Scene(root, 800, 600);
|
||||
// https://github.com/dicolar/jbootx
|
||||
// scene.getStylesheets().add(GUIController.class.getResource("bootstrap3.css").toExternalForm())
|
||||
primaryStage.setScene(scene);
|
||||
stage = primaryStage;
|
||||
primaryStage.show();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
launch(args);
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
corpus = new Corpus();
|
||||
ctController.setCorpus(corpus);
|
||||
ctController.setFilterTab(filterTab);
|
||||
ctController.setStringLevelTabNew2(StringLevelTabNew2);
|
||||
ctController.setOneWordAnalysisTab(OneWordAnalysisTab);
|
||||
ctController.setCharacterLevelTab(CharacterLevelTabNew);
|
||||
ctController.setSatNew2Controller(satNew2Controller);
|
||||
ctController.setOneWordTabController(oneWordTabController);
|
||||
ctController.setCatController(catController);
|
||||
//ctController.setWfController(wfController);
|
||||
ctController.setWlController(wlController);
|
||||
ctController.setTabPane(tabPane);
|
||||
ctController.setFfsController(ffsController);
|
||||
//ctController.setWordFormationTab(wordFormationTab);
|
||||
ctController.setWordLevelTab(wordLevelTab);
|
||||
ctController.setHostServices(getHostServices());
|
||||
|
||||
satNew2Controller.setCorpus(corpus);
|
||||
satNew2Controller.setHostServices(getHostServices());
|
||||
oneWordTabController.setCorpus(corpus);
|
||||
oneWordTabController.setHostServices(getHostServices());
|
||||
catController.setCorpus(corpus);
|
||||
catController.setHostServices(getHostServices());
|
||||
//wfController.setCorpus(corpus);
|
||||
//wfController.setHostServices(getHostServices());
|
||||
wlController.setCorpus(corpus);
|
||||
wlController.setHostServices(getHostServices());
|
||||
ffsController.setSatNew2Controller(satNew2Controller);
|
||||
ffsController.setOneWordTabController(oneWordTabController);
|
||||
ffsController.setCatController(catController);
|
||||
//ffsController.setWfController(wfController);
|
||||
ffsController.setWlController(wlController);
|
||||
ffsController.setHostServices(getHostServices());
|
||||
|
||||
// set tab icons
|
||||
corpusTab.setGraphic(new FontIcon(FontAwesome.COG));
|
||||
filterTab.setGraphic(new FontIcon(FontAwesome.FILTER));
|
||||
|
||||
// hide filter tab
|
||||
tabPane.getTabs().removeAll(filterTab);
|
||||
}
|
||||
|
||||
static void showAlert(Alert.AlertType alertType, String headerText, String contentText) {
|
||||
Alert alert = new Alert(alertType);
|
||||
alert.setTitle(Messages.windowTitles.get(alertType));
|
||||
alert.setHeaderText(headerText != null ? headerText : "");
|
||||
alert.setContentText(contentText != null ? contentText : "");
|
||||
alert.showAndWait();
|
||||
}
|
||||
|
||||
static void showAlert(Alert.AlertType alertType, String headerText) {
|
||||
showAlert(alertType, headerText, null);
|
||||
}
|
||||
}
|
||||
74
src/main/java/gui/Messages.java
Normal file
74
src/main/java/gui/Messages.java
Normal file
@@ -0,0 +1,74 @@
|
||||
package gui;
|
||||
|
||||
import static javafx.scene.control.Alert.AlertType.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import javafx.scene.control.Alert;
|
||||
|
||||
public class Messages {
|
||||
|
||||
// warnings & errors
|
||||
public static final String WARNING_CORPUS_NOT_FOUND = "V izbranem direktoriju ni ustreznih korpusnih datotek.";
|
||||
public static final String WARNING_RESULTS_DIR_NOT_VALID = "Za dostop do izbranega direktorija nimate potrebnih pravic.";
|
||||
public static final String WARNING_DIFFERING_NGRAM_LEVEL_AND_FILTER_TOKENS = "Izbran nivo ngramov in vpisano št. besed v filtru se ne ujemata.";
|
||||
public static final String WARNING_DIFFERING_NGRAM_LEVEL_AND_FILTER_TOKENS_INFO = "Izberite drugo število ali popravite filter.";
|
||||
public static final String WARNING_WORD_OR_LEMMA = "Izberite, če želite statistiko izračunati za besede ali leme.";
|
||||
public static final String WARNING_ONLY_NUMBERS_ALLOWED = "Prosim vnesite veljavno število.";
|
||||
public static final String WARNING_MISMATCHED_NGRAM_AND_TOKENS_VALUES = "Število za ngram (%d) in število msd oznak (%d) se morata ujemati.";
|
||||
public static final String WARNING_MISSING_STRING_LENGTH = "Dolžina niza mora biti večja od 0. Vstavljena je privzeta vrednost (1).";
|
||||
public static final String WARNING_NO_TAXONOMY_FOUND = "Iz korpusnih datotek ni bilo moč razbrati taksonomije. Prosim izberite drugo lokacijo ali korpus.";
|
||||
public static final String WARNING_NO_SOLAR_FILTERS_FOUND = "Iz korpusnih datotek ni bilo moč razbrati filtrov. Prosim izberite drugo lokacijo ali korpus.";
|
||||
public static final String ERROR_WHILE_EXECUTING = "Prišlo je do napake med izvajanjem.";
|
||||
public static final String ERROR_WHILE_SAVING_RESULTS_TO_CSV = "Prišlo je do napake med shranjevanje rezultatov.";
|
||||
|
||||
// missing
|
||||
public static final String MISSING_NGRAM_LEVEL = "N-gram nivo";
|
||||
public static final String MISSING_CALCULATE_FOR = "Izračunaj za";
|
||||
public static final String MISSING_SKIP = "";
|
||||
public static final String MISSING_STRING_LENGTH = "Dolžina niza";
|
||||
public static final String MISMATCHED_STRING_LENGTH_AND_MSD_REGEX = "Neujemajoča dolžina niza in regex filter";
|
||||
|
||||
|
||||
// general notifications - static content/set only once
|
||||
public static final String NOTIFICATION_FOUND_X_FILES = "Št. najdenih datotek: %d";
|
||||
public static final String NOTIFICATION_ANALYSIS_COMPLETED = "Analiza je zaključena, rezultati so shranjeni.";
|
||||
public static final String NOTIFICATION_ANALYSIS_COMPLETED_NO_RESULTS = "Analiza je zaključena, vendar ni bilo moč izračunati statistike, ki bi ustrezala vsem navedenim pogojem.";
|
||||
public static final String RESULTS_PATH_SET_TO_DEFAULT = "Lokacija za shranjevanje rezultatov je nastavljena na lokacijo korpusa.";
|
||||
|
||||
// ongoing notifications - displayed while processing, dynamically changing
|
||||
public static final String ONGOING_NOTIFICATION_ANALYZING_FILE_X_OF_Y = "Analiziram datoteko %d od %d (%s)";
|
||||
|
||||
// Labels
|
||||
public static final String LABEL_CORPUS_LOCATION_NOT_SET = "Lokacija korpusa ni nastavljena";
|
||||
public static final String LABEL_RESULTS_LOCATION_NOT_SET = "Lokacija za shranjevanje rezultatov ni nastavljena";
|
||||
public static final String LABEL_RESULTS_CORPUS_TYPE_NOT_SET = "Vrsta korpusa ni nastavljena";
|
||||
|
||||
public static final String LABEL_SCANNING_CORPUS = "Iskanje in analiza korpusnih datotek...";
|
||||
public static final String LABEL_SCANNING_SINGLE_FILE_CORPUS = "Analiza vnosa ";
|
||||
public static final String COMPLETED = "končano";
|
||||
|
||||
public static final String TOOLTIP_chooseCorpusLocationB = "Izberite mapo v kateri se nahaja korpus. Program izbrano mapo preišče rekurzivno, zato bodite pozorni, da ne izberete mape z več korpusi ali z mnogo datotekami, ki niso del korpusa.";
|
||||
public static final String TOOLTIP_readHeaderInfoChB = "Če izberete to opcijo, se bo iz headerjev korpusa prebrala razpoložljiva taksonomija oz. filtri (korpus Šolar). Ta operacija lahko traja dlje časa, sploh če je korpus združen v eni sami datoteki.";
|
||||
|
||||
|
||||
|
||||
// Not properly to be here. TODO move somewhere else in future
|
||||
public static final String HELP_URL = "http://slovnica.ijs.si/";
|
||||
|
||||
// helper maps
|
||||
/**
|
||||
* Typical window titles
|
||||
* ERROR = "Napaka"
|
||||
* WARNING = "Opozorilo"
|
||||
* CONFIRMATION = "Potrdilo"
|
||||
*/
|
||||
static HashMap<Alert.AlertType, String> windowTitles = new HashMap<>();
|
||||
|
||||
static {
|
||||
// automatically set window's title
|
||||
windowTitles.put(ERROR, "Napaka");
|
||||
windowTitles.put(WARNING, "Opozorilo");
|
||||
windowTitles.put(CONFIRMATION, "Potrdilo");
|
||||
}
|
||||
}
|
||||
389
src/main/java/gui/OneWordAnalysisTab.java
Executable file
389
src/main/java/gui/OneWordAnalysisTab.java
Executable file
@@ -0,0 +1,389 @@
|
||||
package gui;
|
||||
|
||||
import data.*;
|
||||
import javafx.application.HostServices;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.Pane;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.controlsfx.control.CheckComboBox;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static alg.XML_processing.readXML;
|
||||
import static gui.GUIController.showAlert;
|
||||
import static gui.Messages.*;
|
||||
|
||||
@SuppressWarnings("Duplicates")
|
||||
public class OneWordAnalysisTab {
|
||||
public final static Logger logger = LogManager.getLogger(OneWordAnalysisTab.class);
|
||||
|
||||
@FXML
|
||||
public Label selectedFiltersLabel;
|
||||
@FXML
|
||||
public Label solarFilters;
|
||||
|
||||
@FXML
|
||||
private TextField msdTF;
|
||||
private ArrayList<Pattern> msd;
|
||||
private ArrayList<String> msdStrings;
|
||||
|
||||
@FXML
|
||||
private CheckComboBox<String> taxonomyCCB;
|
||||
private ArrayList<String> taxonomy;
|
||||
|
||||
@FXML
|
||||
private ComboBox<String> calculateForCB;
|
||||
private CalculateFor calculateFor;
|
||||
|
||||
|
||||
@FXML
|
||||
private Button computeNgramsB;
|
||||
|
||||
@FXML
|
||||
public ProgressBar ngramProgressBar;
|
||||
@FXML
|
||||
public Label progressLabel;
|
||||
|
||||
@FXML
|
||||
private Hyperlink helpH;
|
||||
|
||||
private enum MODE {
|
||||
LETTER,
|
||||
WORD
|
||||
}
|
||||
|
||||
private MODE currentMode;
|
||||
|
||||
private Corpus corpus;
|
||||
private HashMap<String, HashSet<String>> solarFiltersMap;
|
||||
private Filter filter;
|
||||
private boolean useDb;
|
||||
private HostServices hostService;
|
||||
|
||||
private static final ObservableList<String> N_GRAM_COMPUTE_FOR_WORDS = FXCollections.observableArrayList("lema", "različnica", "oblikoskladenjska oznaka");
|
||||
private static final ObservableList<String> N_GRAM_COMPUTE_FOR_LETTERS = FXCollections.observableArrayList("lema", "različnica");
|
||||
private static final ObservableList<String> N_GRAM_COMPUTE_FOR_WORDS_ORTH = FXCollections.observableArrayList("različnica");
|
||||
|
||||
|
||||
// TODO: pass observables for taxonomy based on header scan
|
||||
// after header scan
|
||||
private ObservableList<String> taxonomyCCBValues;
|
||||
private CorpusType currentCorpusType;
|
||||
|
||||
public void init() {
|
||||
currentMode = MODE.WORD;
|
||||
toggleMode(currentMode);
|
||||
|
||||
// calculateForCB
|
||||
calculateForCB.valueProperty().addListener((observable, oldValue, newValue) -> {
|
||||
calculateFor = CalculateFor.factory(newValue);
|
||||
logger.info("calculateForCB:", calculateFor.toString());
|
||||
});
|
||||
|
||||
calculateForCB.getSelectionModel().select(0);
|
||||
|
||||
// msd
|
||||
msdTF.focusedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (!newValue) {
|
||||
// focus lost
|
||||
String value = msdTF.getText();
|
||||
logger.info("msdTf: ", value);
|
||||
|
||||
if (!ValidationUtil.isEmpty(value)) {
|
||||
ArrayList<String> msdTmp = new ArrayList<>(Arrays.asList(value.split(" ")));
|
||||
|
||||
int nOfRequiredMsdTokens = 1;
|
||||
if (msdTmp.size() != nOfRequiredMsdTokens) {
|
||||
String msg = String.format(Messages.WARNING_MISMATCHED_NGRAM_AND_TOKENS_VALUES, nOfRequiredMsdTokens, msdTmp.size());
|
||||
logAlert(msg);
|
||||
showAlert(Alert.AlertType.ERROR, msg);
|
||||
}
|
||||
msd = new ArrayList<>();
|
||||
msdStrings = new ArrayList<>();
|
||||
for (String msdToken : msdTmp) {
|
||||
msd.add(Pattern.compile(msdToken));
|
||||
msdStrings.add(msdToken);
|
||||
}
|
||||
logger.info(String.format("msd accepted (%d)", msd.size()));
|
||||
|
||||
} else if (!ValidationUtil.isEmpty(newValue)) {
|
||||
msd = new ArrayList<>();
|
||||
msdStrings = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
msdTF.setText("");
|
||||
msd = new ArrayList<>();
|
||||
|
||||
// taxonomy
|
||||
if (Tax.getCorpusTypesWithTaxonomy().contains(corpus.getCorpusType())) {
|
||||
taxonomyCCB.getItems().removeAll();
|
||||
taxonomyCCB.getItems().setAll(corpus.getTaxonomy());
|
||||
taxonomyCCB.getCheckModel().getCheckedItems().addListener((ListChangeListener<String>) c -> {
|
||||
taxonomy = new ArrayList<>();
|
||||
ObservableList<String> checkedItems = taxonomyCCB.getCheckModel().getCheckedItems();
|
||||
taxonomy.addAll(checkedItems);
|
||||
logger.info(String.format("Selected taxonomy: %s", StringUtils.join(checkedItems, ",")));
|
||||
});
|
||||
taxonomyCCB.getCheckModel().clearChecks();
|
||||
} else {
|
||||
taxonomyCCB.setDisable(true);
|
||||
}
|
||||
|
||||
computeNgramsB.setOnAction(e -> {
|
||||
compute();
|
||||
logger.info("compute button");
|
||||
});
|
||||
helpH.setOnAction(e -> openHelpWebsite());
|
||||
}
|
||||
|
||||
/**
|
||||
* case a: values for combo boxes can change after a corpus change
|
||||
* <ul>
|
||||
* <li>different corpus type - reset all fields so no old values remain</li>
|
||||
* <li>same corpus type, different subset - keep</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* case b: values for combo boxes can change after a header scan
|
||||
* <ul>
|
||||
* <li>at first, fields are populated by corpus type defaults</li>
|
||||
* <li>after, with gathered data</li>
|
||||
* </ul>
|
||||
* <p></p>
|
||||
* ngrams: 1
|
||||
* calculateFor: word
|
||||
* msd:
|
||||
* taxonomy:
|
||||
* skip: 0
|
||||
* iscvv: false
|
||||
* string length: 1
|
||||
*/
|
||||
public void populateFields() {
|
||||
// corpus changed if: current one is null (this is first run of the app)
|
||||
// or if currentCorpus != gui's corpus
|
||||
boolean corpusChanged = currentCorpusType == null
|
||||
|| currentCorpusType != corpus.getCorpusType();
|
||||
|
||||
|
||||
// TODO: check for GOS, GIGAFIDA, SOLAR...
|
||||
// refresh and:
|
||||
// TODO if current value != null && is in new calculateFor ? keep : otherwise reset
|
||||
if (calculateFor == null) {
|
||||
calculateForCB.getSelectionModel().select(calculateForCB.getItems().get(0));
|
||||
calculateFor = CalculateFor.factory(calculateForCB.getItems().get(0));
|
||||
}
|
||||
|
||||
if (!filter.hasMsd()) {
|
||||
// if current corpus doesn't have msd data, disable this field
|
||||
msd = new ArrayList<>();
|
||||
msdTF.setText("");
|
||||
msdTF.setDisable(true);
|
||||
logger.info("no msd data");
|
||||
} else {
|
||||
if (ValidationUtil.isEmpty(msd)
|
||||
|| (!ValidationUtil.isEmpty(msd) && corpusChanged)) {
|
||||
// msd has not been set previously
|
||||
// or msd has been set but the corpus changed -> reset
|
||||
msd = new ArrayList<>();
|
||||
msdTF.setText("");
|
||||
msdTF.setDisable(false);
|
||||
logger.info("msd reset");
|
||||
} else if (!ValidationUtil.isEmpty(msd) && !corpusChanged) {
|
||||
// if msd has been set, but corpus type remained the same, we can keep any set msd value
|
||||
msdTF.setText(StringUtils.join(msdStrings, " "));
|
||||
msdTF.setDisable(false);
|
||||
logger.info("msd kept");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: trigger on rescan
|
||||
if ((currentCorpusType != null && currentCorpusType != corpus.getCorpusType())) {
|
||||
// user changed corpus (by type) or by selection & triggered a rescan of headers
|
||||
// see if we read taxonomy from headers, otherwise use default values for given corpus
|
||||
ObservableList<String> tax = corpus.getTaxonomy();
|
||||
taxonomyCCBValues = tax != null ? tax : Taxonomy.getDefaultForComboBox(corpus.getCorpusType());
|
||||
|
||||
currentCorpusType = corpus.getCorpusType();
|
||||
// setTaxonomyIsDirty(false);
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
// see if we read taxonomy from headers, otherwise use default values for given corpus
|
||||
ObservableList<String> tax = corpus.getTaxonomy();
|
||||
taxonomyCCBValues = tax != null ? tax : Taxonomy.getDefaultForComboBox(corpus.getCorpusType());
|
||||
taxonomyCCB.getItems().addAll(taxonomyCCBValues);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles visibility for panes which hold fields for skipgram value (not applicable when calculating for letters) etc.,
|
||||
* sets combobox values to what is applicable ...
|
||||
*
|
||||
* @param mode
|
||||
*/
|
||||
public void toggleMode(MODE mode) {
|
||||
if (mode == null) {
|
||||
mode = currentMode;
|
||||
}
|
||||
|
||||
logger.info("mode: ", mode.toString());
|
||||
|
||||
if (mode == MODE.WORD) {
|
||||
calculateForCB.getItems().setAll(N_GRAM_COMPUTE_FOR_WORDS);
|
||||
} else if (mode == MODE.LETTER) {
|
||||
calculateForCB.getItems().setAll(N_GRAM_COMPUTE_FOR_LETTERS);
|
||||
|
||||
|
||||
// if calculateFor was selected for something other than a word or a lemma -> reset
|
||||
if (!(calculateFor == CalculateFor.WORD || calculateFor == CalculateFor.LEMMA)) {
|
||||
// if the user selected something else before selecting ngram for letters, reset that choice
|
||||
calculateFor = CalculateFor.WORD;
|
||||
calculateForCB.getSelectionModel().select("različnica");
|
||||
}
|
||||
}
|
||||
|
||||
// override if orth mode, allow only word
|
||||
if (corpus.isGosOrthMode()) {
|
||||
calculateForCB.getItems().setAll(N_GRAM_COMPUTE_FOR_WORDS_ORTH);
|
||||
msdTF.setDisable(true);
|
||||
} else {
|
||||
msdTF.setDisable(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void compute() {
|
||||
Filter filter = new Filter();
|
||||
filter.setNgramValue(1);
|
||||
filter.setCalculateFor(calculateFor);
|
||||
filter.setMsd(msd);
|
||||
filter.setTaxonomy(Tax.getTaxonomyCodes(taxonomy, corpus.getCorpusType()));
|
||||
filter.setAl(AnalysisLevel.STRING_LEVEL);
|
||||
filter.setSkipValue(0);
|
||||
filter.setIsCvv(false);
|
||||
filter.setSolarFilters(solarFiltersMap);
|
||||
filter.setStringLength(1);
|
||||
|
||||
String message = Validation.validateForStringLevel(filter);
|
||||
if (message == null) {
|
||||
// no errors
|
||||
logger.info("Executing: ", filter.toString());
|
||||
StatisticsNew statistic = new StatisticsNew(corpus, filter, useDb);
|
||||
execute(statistic);
|
||||
} else {
|
||||
logAlert(message);
|
||||
showAlert(Alert.AlertType.ERROR, "Prosim izpolnite polja:", message);
|
||||
}
|
||||
}
|
||||
|
||||
private void logAlert(String alert) {
|
||||
logger.info("alert: " + alert);
|
||||
}
|
||||
|
||||
private void openHelpWebsite(){
|
||||
hostService.showDocument(Messages.HELP_URL);
|
||||
}
|
||||
|
||||
public Corpus getCorpus() {
|
||||
return corpus;
|
||||
}
|
||||
|
||||
public void setCorpus(Corpus corpus) {
|
||||
this.corpus = corpus;
|
||||
|
||||
if (corpus.getCorpusType() != CorpusType.SOLAR) {
|
||||
setSelectedFiltersLabel(null);
|
||||
} else {
|
||||
setSelectedFiltersLabel("/");
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelectedFiltersLabel(String content) {
|
||||
if (content != null) {
|
||||
solarFilters.setVisible(true);
|
||||
selectedFiltersLabel.setVisible(true);
|
||||
selectedFiltersLabel.setText(content);
|
||||
} else {
|
||||
solarFilters.setVisible(false);
|
||||
selectedFiltersLabel.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void execute(StatisticsNew statistic) {
|
||||
logger.info("Started execution: ", statistic.getFilter());
|
||||
|
||||
Collection<File> corpusFiles = statistic.getCorpus().getDetectedCorpusFiles();
|
||||
boolean corpusIsSplit = corpusFiles.size() > 1;
|
||||
|
||||
final Task<Void> task = new Task<Void>() {
|
||||
@SuppressWarnings("Duplicates")
|
||||
@Override
|
||||
protected Void call() throws Exception {
|
||||
long i = 0;
|
||||
for (File f : corpusFiles) {
|
||||
readXML(f.toString(), statistic);
|
||||
i++;
|
||||
this.updateProgress(i, corpusFiles.size());
|
||||
this.updateMessage(String.format(ONGOING_NOTIFICATION_ANALYZING_FILE_X_OF_Y, i, corpusFiles.size(), f.getName()));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
ngramProgressBar.progressProperty().bind(task.progressProperty());
|
||||
progressLabel.textProperty().bind(task.messageProperty());
|
||||
|
||||
task.setOnSucceeded(e -> {
|
||||
try {
|
||||
boolean successullySaved = statistic.saveResultToDisk();
|
||||
if (successullySaved) {
|
||||
showAlert(Alert.AlertType.INFORMATION, Messages.NOTIFICATION_ANALYSIS_COMPLETED);
|
||||
} else {
|
||||
showAlert(Alert.AlertType.INFORMATION, Messages.NOTIFICATION_ANALYSIS_COMPLETED_NO_RESULTS);
|
||||
}
|
||||
} catch (UnsupportedEncodingException e1) {
|
||||
showAlert(Alert.AlertType.ERROR, ERROR_WHILE_SAVING_RESULTS_TO_CSV);
|
||||
logger.error("Error while saving", e1);
|
||||
}
|
||||
|
||||
ngramProgressBar.progressProperty().unbind();
|
||||
ngramProgressBar.setStyle(Settings.FX_ACCENT_OK);
|
||||
progressLabel.textProperty().unbind();
|
||||
progressLabel.setText("");
|
||||
});
|
||||
|
||||
task.setOnFailed(e -> {
|
||||
showAlert(Alert.AlertType.ERROR, ERROR_WHILE_EXECUTING);
|
||||
logger.error("Error while executing", e);
|
||||
ngramProgressBar.progressProperty().unbind();
|
||||
ngramProgressBar.setProgress(0.0);
|
||||
ngramProgressBar.setStyle(Settings.FX_ACCENT_NOK);
|
||||
progressLabel.textProperty().unbind();
|
||||
progressLabel.setText("");
|
||||
});
|
||||
|
||||
final Thread thread = new Thread(task, "task");
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public void setSolarFiltersMap(HashMap<String, HashSet<String>> solarFiltersMap) {
|
||||
this.solarFiltersMap = solarFiltersMap;
|
||||
}
|
||||
public void setHostServices(HostServices hostServices){
|
||||
this.hostService = hostServices;
|
||||
}
|
||||
|
||||
}
|
||||
18
src/main/java/gui/SelectedFiltersPane.java
Normal file
18
src/main/java/gui/SelectedFiltersPane.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package gui;
|
||||
|
||||
import javafx.scene.control.Label;
|
||||
|
||||
public class SelectedFiltersPane {
|
||||
|
||||
|
||||
public Label selectedFiltersLabel;
|
||||
|
||||
public Label getSelectedFiltersLabel() {
|
||||
return selectedFiltersLabel;
|
||||
}
|
||||
|
||||
public void setSelectedFiltersLabel(String filters) {
|
||||
this.selectedFiltersLabel = new Label(filters);
|
||||
this.selectedFiltersLabel.setText("test?");
|
||||
}
|
||||
}
|
||||
511
src/main/java/gui/StringAnalysisTabNew2.java
Executable file
511
src/main/java/gui/StringAnalysisTabNew2.java
Executable file
@@ -0,0 +1,511 @@
|
||||
package gui;
|
||||
|
||||
import static alg.XML_processing.*;
|
||||
import static gui.GUIController.*;
|
||||
import static gui.Messages.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javafx.application.HostServices;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.controlsfx.control.CheckComboBox;
|
||||
|
||||
import data.*;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
@SuppressWarnings("Duplicates")
|
||||
public class StringAnalysisTabNew2 {
|
||||
public final static Logger logger = LogManager.getLogger(StringAnalysisTabNew2.class);
|
||||
|
||||
@FXML
|
||||
public Label selectedFiltersLabel;
|
||||
@FXML
|
||||
public Label solarFilters;
|
||||
|
||||
@FXML
|
||||
private TextField msdTF;
|
||||
private ArrayList<Pattern> msd;
|
||||
private ArrayList<String> msdStrings;
|
||||
|
||||
@FXML
|
||||
private CheckComboBox<String> taxonomyCCB;
|
||||
private ArrayList<String> taxonomy;
|
||||
|
||||
@FXML
|
||||
private CheckBox calculatecvvCB;
|
||||
private boolean calculateCvv;
|
||||
|
||||
@FXML
|
||||
private TextField stringLengthTF;
|
||||
private Integer stringLength;
|
||||
|
||||
@FXML
|
||||
private ComboBox<String> calculateForCB;
|
||||
private CalculateFor calculateFor;
|
||||
|
||||
@FXML
|
||||
private ComboBox<String> ngramValueCB;
|
||||
private Integer ngramValue;
|
||||
|
||||
@FXML
|
||||
private ComboBox<String> skipValueCB;
|
||||
private Integer skipValue;
|
||||
|
||||
@FXML
|
||||
private Pane paneWords;
|
||||
|
||||
@FXML
|
||||
private Pane paneLetters;
|
||||
|
||||
@FXML
|
||||
private Button computeNgramsB;
|
||||
|
||||
@FXML
|
||||
public ProgressBar ngramProgressBar;
|
||||
@FXML
|
||||
public Label progressLabel;
|
||||
|
||||
@FXML
|
||||
private Hyperlink helpH;
|
||||
|
||||
private enum MODE {
|
||||
LETTER,
|
||||
WORD
|
||||
}
|
||||
|
||||
private MODE currentMode;
|
||||
|
||||
private Corpus corpus;
|
||||
private HashMap<String, HashSet<String>> solarFiltersMap;
|
||||
private Filter filter;
|
||||
private boolean useDb;
|
||||
private HostServices hostService;
|
||||
|
||||
private static final ObservableList<String> N_GRAM_COMPUTE_FOR_WORDS = FXCollections.observableArrayList("lema", "različnica", "oblikoskladenjska oznaka");
|
||||
private static final ObservableList<String> N_GRAM_COMPUTE_FOR_LETTERS = FXCollections.observableArrayList("lema", "različnica");
|
||||
private static final ObservableList<String> N_GRAM_COMPUTE_FOR_WORDS_ORTH = FXCollections.observableArrayList("različnica");
|
||||
|
||||
|
||||
// TODO: pass observables for taxonomy based on header scan
|
||||
// after header scan
|
||||
private ObservableList<String> taxonomyCCBValues;
|
||||
private CorpusType currentCorpusType;
|
||||
|
||||
public void init() {
|
||||
currentMode = MODE.WORD;
|
||||
toggleMode(currentMode);
|
||||
|
||||
// ngram value CB
|
||||
ngramValueCB.valueProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (newValue.equals("nivo črk")) {
|
||||
ngramValue = 0;
|
||||
toggleMode(MODE.LETTER);
|
||||
} else {
|
||||
ngramValue = Integer.valueOf(newValue);
|
||||
toggleMode(MODE.WORD);
|
||||
}
|
||||
|
||||
// skip only on ngrams of more than one word
|
||||
if (ngramValue > 1) {
|
||||
skipValueCB.setDisable(false);
|
||||
} else {
|
||||
skipValueCB.getSelectionModel().select(0);
|
||||
skipValue = 0;
|
||||
skipValueCB.setDisable(true);
|
||||
}
|
||||
|
||||
logger.info("ngramValueCB:", ngramValue);
|
||||
});
|
||||
|
||||
// set first n-gram value to 2 at index 0
|
||||
ngramValueCB.getSelectionModel().select(0); // selected index
|
||||
ngramValue = 2; // actual value at that index
|
||||
|
||||
// calculateForCB
|
||||
calculateForCB.valueProperty().addListener((observable, oldValue, newValue) -> {
|
||||
calculateFor = CalculateFor.factory(newValue);
|
||||
logger.info("calculateForCB:", calculateFor.toString());
|
||||
});
|
||||
|
||||
calculateForCB.getSelectionModel().select(0);
|
||||
|
||||
// msd
|
||||
msdTF.focusedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (!newValue) {
|
||||
// focus lost
|
||||
String value = msdTF.getText();
|
||||
logger.info("msdTf: ", value);
|
||||
|
||||
if (!ValidationUtil.isEmpty(value)) {
|
||||
ArrayList<String> msdTmp = new ArrayList<>(Arrays.asList(value.split(" ")));
|
||||
|
||||
int nOfRequiredMsdTokens = ngramValue == 0 ? 1 : ngramValue;
|
||||
if (msdTmp.size() != nOfRequiredMsdTokens) {
|
||||
String msg = String.format(Messages.WARNING_MISMATCHED_NGRAM_AND_TOKENS_VALUES, nOfRequiredMsdTokens, msdTmp.size());
|
||||
logAlert(msg);
|
||||
showAlert(Alert.AlertType.ERROR, msg);
|
||||
}
|
||||
msd = new ArrayList<>();
|
||||
msdStrings = new ArrayList<>();
|
||||
for (String msdToken : msdTmp) {
|
||||
msd.add(Pattern.compile(msdToken));
|
||||
msdStrings.add(msdToken);
|
||||
}
|
||||
logger.info(String.format("msd accepted (%d)", msd.size()));
|
||||
|
||||
} else if (!ValidationUtil.isEmpty(newValue)) {
|
||||
msd = new ArrayList<>();
|
||||
msdStrings = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
msdTF.setText("");
|
||||
msd = new ArrayList<>();
|
||||
|
||||
// taxonomy
|
||||
if (Tax.getCorpusTypesWithTaxonomy().contains(corpus.getCorpusType())) {
|
||||
taxonomyCCB.getItems().removeAll();
|
||||
taxonomyCCB.getItems().setAll(corpus.getTaxonomy());
|
||||
taxonomyCCB.getCheckModel().getCheckedItems().addListener((ListChangeListener<String>) c -> {
|
||||
taxonomy = new ArrayList<>();
|
||||
ObservableList<String> checkedItems = taxonomyCCB.getCheckModel().getCheckedItems();
|
||||
taxonomy.addAll(checkedItems);
|
||||
logger.info(String.format("Selected taxonomy: %s", StringUtils.join(checkedItems, ",")));
|
||||
});
|
||||
taxonomyCCB.getCheckModel().clearChecks();
|
||||
} else {
|
||||
taxonomyCCB.setDisable(true);
|
||||
}
|
||||
|
||||
// skip
|
||||
skipValueCB.valueProperty().addListener((observable, oldValue, newValue) -> {
|
||||
skipValue = Integer.valueOf(newValue);
|
||||
logger.info("Skip " + skipValue);
|
||||
});
|
||||
|
||||
skipValueCB.getSelectionModel().select(0);
|
||||
skipValue = 0;
|
||||
|
||||
// cvv
|
||||
calculatecvvCB.selectedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
calculateCvv = newValue;
|
||||
logger.info("calculate cvv: " + calculateCvv);
|
||||
});
|
||||
|
||||
calculatecvvCB.setSelected(false);
|
||||
|
||||
// string length
|
||||
stringLengthTF.focusedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (!newValue) {
|
||||
// focus lost
|
||||
String value = stringLengthTF.getText();
|
||||
if (!ValidationUtil.isEmpty(value)) {
|
||||
if (!ValidationUtil.isNumber(value)) {
|
||||
logAlert("stringlengthTf: " + WARNING_ONLY_NUMBERS_ALLOWED);
|
||||
GUIController.showAlert(Alert.AlertType.ERROR, WARNING_ONLY_NUMBERS_ALLOWED);
|
||||
}
|
||||
stringLength = Integer.parseInt(value);
|
||||
} else {
|
||||
GUIController.showAlert(Alert.AlertType.ERROR, WARNING_MISSING_STRING_LENGTH);
|
||||
stringLengthTF.setText("1");
|
||||
logAlert(WARNING_MISSING_STRING_LENGTH);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
computeNgramsB.setOnAction(e -> {
|
||||
compute();
|
||||
logger.info("compute button");
|
||||
});
|
||||
|
||||
helpH.setOnAction(e -> openHelpWebsite());
|
||||
}
|
||||
|
||||
/**
|
||||
* case a: values for combo boxes can change after a corpus change
|
||||
* <ul>
|
||||
* <li>different corpus type - reset all fields so no old values remain</li>
|
||||
* <li>same corpus type, different subset - keep</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* case b: values for combo boxes can change after a header scan
|
||||
* <ul>
|
||||
* <li>at first, fields are populated by corpus type defaults</li>
|
||||
* <li>after, with gathered data</li>
|
||||
* </ul>
|
||||
* <p></p>
|
||||
* ngrams: 1
|
||||
* calculateFor: word
|
||||
* msd:
|
||||
* taxonomy:
|
||||
* skip: 0
|
||||
* iscvv: false
|
||||
* string length: 1
|
||||
*/
|
||||
public void populateFields() {
|
||||
// corpus changed if: current one is null (this is first run of the app)
|
||||
// or if currentCorpus != gui's corpus
|
||||
boolean corpusChanged = currentCorpusType == null
|
||||
|| currentCorpusType != corpus.getCorpusType();
|
||||
|
||||
// keep ngram value if set
|
||||
if (ngramValue == null) {
|
||||
ngramValueCB.getSelectionModel().select("1");
|
||||
ngramValue = 1;
|
||||
}
|
||||
|
||||
// TODO: check for GOS, GIGAFIDA, SOLAR...
|
||||
// refresh and:
|
||||
// TODO if current value != null && is in new calculateFor ? keep : otherwise reset
|
||||
if (calculateFor == null) {
|
||||
calculateForCB.getSelectionModel().select(calculateForCB.getItems().get(0));
|
||||
calculateFor = CalculateFor.factory(calculateForCB.getItems().get(0));
|
||||
}
|
||||
|
||||
if (!filter.hasMsd()) {
|
||||
// if current corpus doesn't have msd data, disable this field
|
||||
msd = new ArrayList<>();
|
||||
msdTF.setText("");
|
||||
msdTF.setDisable(true);
|
||||
logger.info("no msd data");
|
||||
} else {
|
||||
if (ValidationUtil.isEmpty(msd)
|
||||
|| (!ValidationUtil.isEmpty(msd) && corpusChanged)) {
|
||||
// msd has not been set previously
|
||||
// or msd has been set but the corpus changed -> reset
|
||||
msd = new ArrayList<>();
|
||||
msdTF.setText("");
|
||||
msdTF.setDisable(false);
|
||||
logger.info("msd reset");
|
||||
} else if (!ValidationUtil.isEmpty(msd) && !corpusChanged) {
|
||||
// if msd has been set, but corpus type remained the same, we can keep any set msd value
|
||||
msdTF.setText(StringUtils.join(msdStrings, " "));
|
||||
msdTF.setDisable(false);
|
||||
logger.info("msd kept");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: taxonomy: refresh and keep if in new taxonomy, otherwise empty (no selection)
|
||||
|
||||
// keep skip value
|
||||
if (skipValue == null) {
|
||||
skipValueCB.getSelectionModel().select("0");
|
||||
skipValue = 0;
|
||||
}
|
||||
|
||||
// keep calculateCvv
|
||||
calculatecvvCB.setSelected(calculateCvv);
|
||||
|
||||
// keep string length if set
|
||||
if (stringLength != null) {
|
||||
stringLengthTF.setText(String.valueOf(stringLength));
|
||||
} else {
|
||||
stringLengthTF.setText("1");
|
||||
stringLength = 1;
|
||||
}
|
||||
|
||||
// TODO: trigger on rescan
|
||||
if ((currentCorpusType != null && currentCorpusType != corpus.getCorpusType())) {
|
||||
// user changed corpus (by type) or by selection & triggered a rescan of headers
|
||||
// see if we read taxonomy from headers, otherwise use default values for given corpus
|
||||
ObservableList<String> tax = corpus.getTaxonomy();
|
||||
taxonomyCCBValues = tax != null ? tax : Taxonomy.getDefaultForComboBox(corpus.getCorpusType());
|
||||
|
||||
currentCorpusType = corpus.getCorpusType();
|
||||
// setTaxonomyIsDirty(false);
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
// see if we read taxonomy from headers, otherwise use default values for given corpus
|
||||
ObservableList<String> tax = corpus.getTaxonomy();
|
||||
taxonomyCCBValues = tax != null ? tax : Taxonomy.getDefaultForComboBox(corpus.getCorpusType());
|
||||
taxonomyCCB.getItems().addAll(taxonomyCCBValues);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles visibility for panes which hold fields for skipgram value (not applicable when calculating for letters) etc.,
|
||||
* sets combobox values to what is applicable ...
|
||||
*
|
||||
* @param mode
|
||||
*/
|
||||
public void toggleMode(MODE mode) {
|
||||
if (mode == null) {
|
||||
mode = currentMode;
|
||||
}
|
||||
|
||||
logger.info("mode: ", mode.toString());
|
||||
|
||||
if (mode == MODE.WORD) {
|
||||
paneWords.setVisible(true);
|
||||
paneLetters.setVisible(false);
|
||||
calculateForCB.getItems().setAll(N_GRAM_COMPUTE_FOR_WORDS);
|
||||
} else if (mode == MODE.LETTER) {
|
||||
paneWords.setVisible(false);
|
||||
paneLetters.setVisible(true);
|
||||
calculateForCB.getItems().setAll(N_GRAM_COMPUTE_FOR_LETTERS);
|
||||
|
||||
// populate with default cvv length value
|
||||
if (stringLength == null) {
|
||||
stringLengthTF.setText("1");
|
||||
stringLength = 1;
|
||||
} else {
|
||||
stringLengthTF.setText(String.valueOf(stringLength));
|
||||
}
|
||||
|
||||
// if calculateFor was selected for something other than a word or a lemma -> reset
|
||||
if (!(calculateFor == CalculateFor.WORD || calculateFor == CalculateFor.LEMMA)) {
|
||||
// if the user selected something else before selecting ngram for letters, reset that choice
|
||||
calculateFor = CalculateFor.WORD;
|
||||
calculateForCB.getSelectionModel().select("različnica");
|
||||
}
|
||||
}
|
||||
|
||||
// override if orth mode, allow only word
|
||||
if (corpus.isGosOrthMode()) {
|
||||
calculateForCB.getItems().setAll(N_GRAM_COMPUTE_FOR_WORDS_ORTH);
|
||||
msdTF.setDisable(true);
|
||||
} else {
|
||||
msdTF.setDisable(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void compute() {
|
||||
Filter filter = new Filter();
|
||||
filter.setNgramValue(ngramValue);
|
||||
filter.setCalculateFor(calculateFor);
|
||||
filter.setMsd(msd);
|
||||
filter.setTaxonomy(Tax.getTaxonomyCodes(taxonomy, corpus.getCorpusType()));
|
||||
filter.setAl(AnalysisLevel.STRING_LEVEL);
|
||||
filter.setSkipValue(skipValue);
|
||||
filter.setIsCvv(calculateCvv);
|
||||
filter.setSolarFilters(solarFiltersMap);
|
||||
|
||||
if (ngramValue != null && ngramValue == 0) {
|
||||
filter.setStringLength(stringLength);
|
||||
}
|
||||
|
||||
String message = Validation.validateForStringLevel(filter);
|
||||
if (message == null) {
|
||||
// no errors
|
||||
logger.info("Executing: ", filter.toString());
|
||||
StatisticsNew statistic = new StatisticsNew(corpus, filter, useDb);
|
||||
execute(statistic);
|
||||
} else {
|
||||
logAlert(message);
|
||||
showAlert(Alert.AlertType.ERROR, "Prosim izpolnite polja:", message);
|
||||
}
|
||||
}
|
||||
|
||||
private void logAlert(String alert) {
|
||||
logger.info("alert: " + alert);
|
||||
}
|
||||
|
||||
private void openHelpWebsite(){
|
||||
hostService.showDocument(Messages.HELP_URL);
|
||||
}
|
||||
|
||||
public Corpus getCorpus() {
|
||||
return corpus;
|
||||
}
|
||||
|
||||
public void setCorpus(Corpus corpus) {
|
||||
this.corpus = corpus;
|
||||
|
||||
if (corpus.getCorpusType() != CorpusType.SOLAR) {
|
||||
setSelectedFiltersLabel(null);
|
||||
} else {
|
||||
setSelectedFiltersLabel("/");
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelectedFiltersLabel(String content) {
|
||||
if (content != null) {
|
||||
solarFilters.setVisible(true);
|
||||
selectedFiltersLabel.setVisible(true);
|
||||
selectedFiltersLabel.setText(content);
|
||||
} else {
|
||||
solarFilters.setVisible(false);
|
||||
selectedFiltersLabel.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void execute(StatisticsNew statistic) {
|
||||
logger.info("Started execution: ", statistic.getFilter());
|
||||
|
||||
Collection<File> corpusFiles = statistic.getCorpus().getDetectedCorpusFiles();
|
||||
boolean corpusIsSplit = corpusFiles.size() > 1;
|
||||
|
||||
final Task<Void> task = new Task<Void>() {
|
||||
@SuppressWarnings("Duplicates")
|
||||
@Override
|
||||
protected Void call() throws Exception {
|
||||
long i = 0;
|
||||
for (File f : corpusFiles) {
|
||||
readXML(f.toString(), statistic);
|
||||
i++;
|
||||
this.updateProgress(i, corpusFiles.size());
|
||||
this.updateMessage(String.format(ONGOING_NOTIFICATION_ANALYZING_FILE_X_OF_Y, i, corpusFiles.size(), f.getName()));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
ngramProgressBar.progressProperty().bind(task.progressProperty());
|
||||
progressLabel.textProperty().bind(task.messageProperty());
|
||||
|
||||
task.setOnSucceeded(e -> {
|
||||
try {
|
||||
boolean successullySaved = statistic.saveResultToDisk();
|
||||
if (successullySaved) {
|
||||
showAlert(Alert.AlertType.INFORMATION, Messages.NOTIFICATION_ANALYSIS_COMPLETED);
|
||||
} else {
|
||||
showAlert(Alert.AlertType.INFORMATION, Messages.NOTIFICATION_ANALYSIS_COMPLETED_NO_RESULTS);
|
||||
}
|
||||
} catch (UnsupportedEncodingException e1) {
|
||||
showAlert(Alert.AlertType.ERROR, ERROR_WHILE_SAVING_RESULTS_TO_CSV);
|
||||
logger.error("Error while saving", e1);
|
||||
}
|
||||
|
||||
ngramProgressBar.progressProperty().unbind();
|
||||
ngramProgressBar.setStyle(Settings.FX_ACCENT_OK);
|
||||
progressLabel.textProperty().unbind();
|
||||
progressLabel.setText("");
|
||||
});
|
||||
|
||||
task.setOnFailed(e -> {
|
||||
showAlert(Alert.AlertType.ERROR, ERROR_WHILE_EXECUTING);
|
||||
logger.error("Error while executing", e);
|
||||
ngramProgressBar.progressProperty().unbind();
|
||||
ngramProgressBar.setProgress(0.0);
|
||||
ngramProgressBar.setStyle(Settings.FX_ACCENT_NOK);
|
||||
progressLabel.textProperty().unbind();
|
||||
progressLabel.setText("");
|
||||
});
|
||||
|
||||
final Thread thread = new Thread(task, "task");
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public void setSolarFiltersMap(HashMap<String, HashSet<String>> solarFiltersMap) {
|
||||
this.solarFiltersMap = solarFiltersMap;
|
||||
}
|
||||
public void setHostServices(HostServices hostServices){
|
||||
this.hostService = hostServices;
|
||||
}
|
||||
}
|
||||
77
src/main/java/gui/ValidationUtil.java
Normal file
77
src/main/java/gui/ValidationUtil.java
Normal file
@@ -0,0 +1,77 @@
|
||||
package gui;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
|
||||
public class ValidationUtil {
|
||||
|
||||
public static boolean isNumber(String value) {
|
||||
return NumberUtils.isCreatable(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an object is empty or null. Null part is especially important,
|
||||
* since Java's built-in isEmpty() methods don't check for this condition
|
||||
* and throw a nullPointerException as a result.
|
||||
* <p>
|
||||
* Supported structures:
|
||||
* <ul>
|
||||
* <li>String: empty if null or length is zero</li>
|
||||
* <li>List: empty if null or size() == 0</li>
|
||||
* <li>Map: empty if null or if it contains no keys, or if all keys map to an empty value </li>
|
||||
* </ul>
|
||||
*/
|
||||
public static boolean isEmpty(Object o) {
|
||||
if (o == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (o instanceof String) {
|
||||
if (((String) o).length() == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (o instanceof List) {
|
||||
if (((List) o).isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (o instanceof Map) {
|
||||
if (((Map) o).keySet().isEmpty()) {
|
||||
return true;
|
||||
} else {
|
||||
for (Object val : ((Map) o).values()) {
|
||||
if (!isEmpty(val)) {
|
||||
// if map contains any value that isn't empty, the map isn't considered empty
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isNotEmpty(Object o) {
|
||||
return !isEmpty(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given File is a folder for which we have appropriate permission
|
||||
*/
|
||||
public static boolean isValidDirectory(File f) {
|
||||
return f.isDirectory() && f.canRead() && f.canWrite();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given File is a folder for which we have appropriate permission
|
||||
*/
|
||||
public static boolean isReadableDirectory(File f) {
|
||||
return f.isDirectory() && f.canRead();
|
||||
}
|
||||
}
|
||||
208
src/main/java/gui/WordFormationTab.java
Normal file
208
src/main/java/gui/WordFormationTab.java
Normal file
@@ -0,0 +1,208 @@
|
||||
package gui;
|
||||
|
||||
import static alg.XML_processing.*;
|
||||
import static gui.GUIController.*;
|
||||
import static gui.Messages.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
import javafx.application.HostServices;
|
||||
import javafx.scene.control.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.controlsfx.control.CheckComboBox;
|
||||
|
||||
import data.*;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
|
||||
@SuppressWarnings("Duplicates")
|
||||
public class WordFormationTab {
|
||||
public final static Logger logger = LogManager.getLogger(WordFormationTab.class);
|
||||
|
||||
public AnchorPane wordAnalysisTabPane;
|
||||
|
||||
@FXML
|
||||
public Label selectedFiltersLabel;
|
||||
@FXML
|
||||
public Label solarFilters;
|
||||
|
||||
@FXML
|
||||
private CheckComboBox<String> taxonomyCCB;
|
||||
private ArrayList<String> taxonomy;
|
||||
|
||||
@FXML
|
||||
private Button computeB;
|
||||
|
||||
@FXML
|
||||
public ProgressBar ngramProgressBar;
|
||||
@FXML
|
||||
public Label progressLabel;
|
||||
|
||||
@FXML
|
||||
private Hyperlink helpH;
|
||||
|
||||
private Corpus corpus;
|
||||
private HashMap<String, HashSet<String>> solarFiltersMap;
|
||||
private HostServices hostService;
|
||||
|
||||
// after header scan
|
||||
private ObservableList<String> taxonomyCCBValues;
|
||||
private CorpusType currentCorpusType;
|
||||
private boolean useDb;
|
||||
|
||||
|
||||
public void init() {
|
||||
// taxonomy
|
||||
if (Tax.getCorpusTypesWithTaxonomy().contains(corpus.getCorpusType())) {
|
||||
taxonomyCCB.getItems().removeAll();
|
||||
taxonomyCCB.getItems().setAll(corpus.getTaxonomy());
|
||||
taxonomyCCB.getCheckModel().getCheckedItems().addListener((ListChangeListener<String>) c -> {
|
||||
taxonomy = new ArrayList<>();
|
||||
ObservableList<String> checkedItems = taxonomyCCB.getCheckModel().getCheckedItems();
|
||||
taxonomy.addAll(checkedItems);
|
||||
logger.info(String.format("Selected taxonomy: %s", StringUtils.join(checkedItems, ",")));
|
||||
});
|
||||
taxonomyCCB.getCheckModel().clearChecks();
|
||||
} else {
|
||||
taxonomyCCB.setDisable(true);
|
||||
}
|
||||
|
||||
computeB.setOnAction(e -> {
|
||||
compute();
|
||||
logger.info("compute button");
|
||||
});
|
||||
|
||||
helpH.setOnAction(e -> openHelpWebsite());
|
||||
}
|
||||
|
||||
private void compute() {
|
||||
Filter filter = new Filter();
|
||||
filter.setNgramValue(1);
|
||||
filter.setCalculateFor(CalculateFor.MORPHOSYNTACTIC_PROPERTY);
|
||||
filter.setTaxonomy(Tax.getTaxonomyCodes(taxonomy, corpus.getCorpusType()));
|
||||
filter.setAl(AnalysisLevel.STRING_LEVEL);
|
||||
filter.setSkipValue(0);
|
||||
filter.setMsd(new ArrayList<>());
|
||||
filter.setIsCvv(false);
|
||||
filter.setSolarFilters(solarFiltersMap);
|
||||
|
||||
String message = Validation.validateForStringLevel(filter);
|
||||
if (message == null) {
|
||||
// no errors
|
||||
logger.info("Executing: ", filter.toString());
|
||||
StatisticsNew statistic = new StatisticsNew(corpus, filter, useDb);
|
||||
execute(statistic);
|
||||
} else {
|
||||
logAlert(message);
|
||||
showAlert(Alert.AlertType.ERROR, "Prosim izpolnite polja:", message);
|
||||
}
|
||||
}
|
||||
|
||||
private void openHelpWebsite(){
|
||||
hostService.showDocument(Messages.HELP_URL);
|
||||
}
|
||||
|
||||
private void execute(StatisticsNew statistic) {
|
||||
logger.info("Started execution: ", statistic.getFilter());
|
||||
|
||||
Collection<File> corpusFiles = statistic.getCorpus().getDetectedCorpusFiles();
|
||||
|
||||
final Task<Void> task = new Task<Void>() {
|
||||
@SuppressWarnings("Duplicates")
|
||||
@Override
|
||||
protected Void call() throws Exception {
|
||||
long i = 0;
|
||||
for (File f : corpusFiles) {
|
||||
readXML(f.toString(), statistic);
|
||||
i++;
|
||||
this.updateProgress(i, corpusFiles.size());
|
||||
this.updateMessage(String.format(ONGOING_NOTIFICATION_ANALYZING_FILE_X_OF_Y, i, corpusFiles.size(), f.getName()));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
ngramProgressBar.progressProperty().bind(task.progressProperty());
|
||||
progressLabel.textProperty().bind(task.messageProperty());
|
||||
|
||||
task.setOnSucceeded(e -> {
|
||||
try {
|
||||
// first, we have to recalculate all occurrences to detailed statistics
|
||||
boolean successullySaved = statistic.recalculateAndSaveResultToDisk();
|
||||
|
||||
if (successullySaved) {
|
||||
showAlert(Alert.AlertType.INFORMATION, Messages.NOTIFICATION_ANALYSIS_COMPLETED);
|
||||
} else {
|
||||
showAlert(Alert.AlertType.INFORMATION, Messages.NOTIFICATION_ANALYSIS_COMPLETED_NO_RESULTS);
|
||||
}
|
||||
} catch (UnsupportedEncodingException e1) {
|
||||
showAlert(Alert.AlertType.ERROR, ERROR_WHILE_SAVING_RESULTS_TO_CSV);
|
||||
logger.error("Error while saving", e1);
|
||||
}
|
||||
|
||||
ngramProgressBar.progressProperty().unbind();
|
||||
ngramProgressBar.setStyle(Settings.FX_ACCENT_OK);
|
||||
progressLabel.textProperty().unbind();
|
||||
progressLabel.setText("");
|
||||
});
|
||||
|
||||
task.setOnFailed(e -> {
|
||||
showAlert(Alert.AlertType.ERROR, ERROR_WHILE_EXECUTING);
|
||||
logger.error("Error while executing", e);
|
||||
ngramProgressBar.progressProperty().unbind();
|
||||
ngramProgressBar.setProgress(0.0);
|
||||
ngramProgressBar.setStyle(Settings.FX_ACCENT_NOK);
|
||||
progressLabel.textProperty().unbind();
|
||||
progressLabel.setText("");
|
||||
});
|
||||
|
||||
final Thread thread = new Thread(task, "task");
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
private void logAlert(String alert) {
|
||||
logger.info("alert: " + alert);
|
||||
}
|
||||
|
||||
|
||||
public void setCorpus(Corpus corpus) {
|
||||
this.corpus = corpus;
|
||||
|
||||
if (corpus.getCorpusType() != CorpusType.SOLAR) {
|
||||
setSelectedFiltersLabel(null);
|
||||
} else {
|
||||
setSelectedFiltersLabel("/");
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelectedFiltersLabel(String content) {
|
||||
if (content != null) {
|
||||
solarFilters.setVisible(true);
|
||||
selectedFiltersLabel.setVisible(true);
|
||||
selectedFiltersLabel.setText(content);
|
||||
} else {
|
||||
solarFilters.setVisible(false);
|
||||
selectedFiltersLabel.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSolarFiltersMap(HashMap<String, HashSet<String>> solarFiltersMap) {
|
||||
this.solarFiltersMap = solarFiltersMap;
|
||||
}
|
||||
|
||||
public void setHostServices(HostServices hostServices){
|
||||
this.hostService = hostServices;
|
||||
}
|
||||
}
|
||||
207
src/main/java/gui/WordLevelTab.java
Normal file
207
src/main/java/gui/WordLevelTab.java
Normal file
@@ -0,0 +1,207 @@
|
||||
package gui;
|
||||
|
||||
import static alg.XML_processing.*;
|
||||
import static gui.GUIController.*;
|
||||
import static gui.Messages.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
import javafx.application.HostServices;
|
||||
import javafx.scene.control.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.controlsfx.control.CheckComboBox;
|
||||
|
||||
import data.*;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
|
||||
@SuppressWarnings("Duplicates")
|
||||
public class WordLevelTab {
|
||||
public final static Logger logger = LogManager.getLogger(WordLevelTab.class);
|
||||
|
||||
public AnchorPane wordLevelAnalysisTabPane;
|
||||
|
||||
@FXML
|
||||
public Label selectedFiltersLabel;
|
||||
@FXML
|
||||
public Label solarFilters;
|
||||
|
||||
@FXML
|
||||
private CheckComboBox<String> taxonomyCCB;
|
||||
private ArrayList<String> taxonomy;
|
||||
|
||||
@FXML
|
||||
private Button computeB;
|
||||
|
||||
@FXML
|
||||
public ProgressBar ngramProgressBar;
|
||||
@FXML
|
||||
public Label progressLabel;
|
||||
|
||||
@FXML
|
||||
private Hyperlink helpH;
|
||||
|
||||
private Corpus corpus;
|
||||
private HashMap<String, HashSet<String>> solarFiltersMap;
|
||||
private HostServices hostService;
|
||||
|
||||
// after header scan
|
||||
private ObservableList<String> taxonomyCCBValues;
|
||||
private CorpusType currentCorpusType;
|
||||
private boolean useDb;
|
||||
|
||||
|
||||
public void init() {
|
||||
// taxonomy
|
||||
if (Tax.getCorpusTypesWithTaxonomy().contains(corpus.getCorpusType())) {
|
||||
taxonomyCCB.getItems().removeAll();
|
||||
taxonomyCCB.getItems().setAll(corpus.getTaxonomy());
|
||||
taxonomyCCB.getCheckModel().getCheckedItems().addListener((ListChangeListener<String>) c -> {
|
||||
taxonomy = new ArrayList<>();
|
||||
ObservableList<String> checkedItems = taxonomyCCB.getCheckModel().getCheckedItems();
|
||||
taxonomy.addAll(checkedItems);
|
||||
logger.info(String.format("Selected taxonomy: %s", StringUtils.join(checkedItems, ",")));
|
||||
});
|
||||
taxonomyCCB.getCheckModel().clearChecks();
|
||||
} else {
|
||||
taxonomyCCB.setDisable(true);
|
||||
}
|
||||
|
||||
computeB.setOnAction(e -> {
|
||||
compute();
|
||||
logger.info("compute button");
|
||||
});
|
||||
|
||||
helpH.setOnAction(e -> openHelpWebsite());
|
||||
}
|
||||
|
||||
private void openHelpWebsite(){
|
||||
hostService.showDocument(Messages.HELP_URL);
|
||||
}
|
||||
private void compute() {
|
||||
Filter filter = new Filter();
|
||||
filter.setNgramValue(1);
|
||||
filter.setCalculateFor(CalculateFor.WORD);
|
||||
filter.setTaxonomy(Tax.getTaxonomyCodes(taxonomy, corpus.getCorpusType()));
|
||||
filter.setAl(AnalysisLevel.WORD_LEVEL);
|
||||
filter.setSkipValue(0);
|
||||
filter.setMsd(new ArrayList<>());
|
||||
filter.setIsCvv(false);
|
||||
filter.setSolarFilters(solarFiltersMap);
|
||||
|
||||
String message = Validation.validateForStringLevel(filter);
|
||||
if (message == null) {
|
||||
// no errors
|
||||
logger.info("Executing: ", filter.toString());
|
||||
StatisticsNew statistic = new StatisticsNew(corpus, filter, useDb);
|
||||
execute(statistic);
|
||||
} else {
|
||||
logAlert(message);
|
||||
showAlert(Alert.AlertType.ERROR, "Prosim izpolnite polja:", message);
|
||||
}
|
||||
}
|
||||
|
||||
private void execute(StatisticsNew statistic) {
|
||||
logger.info("Started execution: ", statistic.getFilter());
|
||||
|
||||
Collection<File> corpusFiles = statistic.getCorpus().getDetectedCorpusFiles();
|
||||
|
||||
final Task<Void> task = new Task<Void>() {
|
||||
@SuppressWarnings("Duplicates")
|
||||
@Override
|
||||
protected Void call() throws Exception {
|
||||
long i = 0;
|
||||
for (File f : corpusFiles) {
|
||||
readXML(f.toString(), statistic);
|
||||
i++;
|
||||
this.updateProgress(i, corpusFiles.size());
|
||||
this.updateMessage(String.format(ONGOING_NOTIFICATION_ANALYZING_FILE_X_OF_Y, i, corpusFiles.size(), f.getName()));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
ngramProgressBar.progressProperty().bind(task.progressProperty());
|
||||
progressLabel.textProperty().bind(task.messageProperty());
|
||||
|
||||
task.setOnSucceeded(e -> {
|
||||
try {
|
||||
// first, we have to recalculate all occurrences to detailed statistics
|
||||
boolean successullySaved = statistic.saveResultNestedToDisk();
|
||||
|
||||
if (successullySaved) {
|
||||
showAlert(Alert.AlertType.INFORMATION, Messages.NOTIFICATION_ANALYSIS_COMPLETED);
|
||||
} else {
|
||||
showAlert(Alert.AlertType.INFORMATION, Messages.NOTIFICATION_ANALYSIS_COMPLETED_NO_RESULTS);
|
||||
}
|
||||
} catch (UnsupportedEncodingException e1) {
|
||||
showAlert(Alert.AlertType.ERROR, ERROR_WHILE_SAVING_RESULTS_TO_CSV);
|
||||
logger.error("Error while saving", e1);
|
||||
}
|
||||
|
||||
ngramProgressBar.progressProperty().unbind();
|
||||
ngramProgressBar.setStyle(Settings.FX_ACCENT_OK);
|
||||
progressLabel.textProperty().unbind();
|
||||
progressLabel.setText("");
|
||||
});
|
||||
|
||||
task.setOnFailed(e -> {
|
||||
showAlert(Alert.AlertType.ERROR, ERROR_WHILE_EXECUTING);
|
||||
logger.error("Error while executing", e);
|
||||
ngramProgressBar.progressProperty().unbind();
|
||||
ngramProgressBar.setProgress(0.0);
|
||||
ngramProgressBar.setStyle(Settings.FX_ACCENT_NOK);
|
||||
progressLabel.textProperty().unbind();
|
||||
progressLabel.setText("");
|
||||
});
|
||||
|
||||
final Thread thread = new Thread(task, "task");
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
private void logAlert(String alert) {
|
||||
logger.info("alert: " + alert);
|
||||
}
|
||||
|
||||
|
||||
public void setCorpus(Corpus corpus) {
|
||||
this.corpus = corpus;
|
||||
|
||||
if (corpus.getCorpusType() != CorpusType.SOLAR) {
|
||||
setSelectedFiltersLabel(null);
|
||||
} else {
|
||||
setSelectedFiltersLabel("/");
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelectedFiltersLabel(String content) {
|
||||
if (content != null) {
|
||||
solarFilters.setVisible(true);
|
||||
selectedFiltersLabel.setVisible(true);
|
||||
selectedFiltersLabel.setText(content);
|
||||
} else {
|
||||
solarFilters.setVisible(false);
|
||||
selectedFiltersLabel.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSolarFiltersMap(HashMap<String, HashSet<String>> solarFiltersMap) {
|
||||
this.solarFiltersMap = solarFiltersMap;
|
||||
}
|
||||
|
||||
public void setHostServices(HostServices hostServices){
|
||||
this.hostService = hostServices;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user