package mj.ocraptor.javafx.controllers;
import static mj.ocraptor.events.ProgressType.COUNTING_FILES;
import static mj.ocraptor.events.ProgressType.COUNTING_FILES_FINISHED;
import static mj.ocraptor.events.ProgressType.INDEX_FINISHED;
import static mj.ocraptor.events.ProgressType.KNOWN_FILE;
import static mj.ocraptor.events.ProgressType.MODIFIED_FILE;
import static mj.ocraptor.events.ProgressType.NEW_FILE_FOUND;
import static mj.ocraptor.events.ProgressType.PAUSED;
import static mj.ocraptor.events.ProgressType.STARTING;
import static mj.ocraptor.events.ProgressType.THREAD_LIST_ONLY;
import static mj.ocraptor.events.ProgressType.UPDATING_FILE_LIST;
import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.ToggleButton;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import mj.ocraptor.MainController;
import mj.ocraptor.MainController.Status;
import mj.ocraptor.configuration.Config;
import mj.ocraptor.configuration.properties.ConfigString;
import mj.ocraptor.events.ProgressType;
import mj.ocraptor.events.ProgressUpdate;
import mj.ocraptor.events.QueueMonitor;
import mj.ocraptor.events.RingBuffer;
import mj.ocraptor.javafx.GUIController;
import mj.ocraptor.javafx.GUITemplate;
import mj.ocraptor.javafx.Icon;
import mj.ocraptor.rmi_server.RMIServerImpl;
import mj.ocraptor.tools.SystemTools;
import mj.ocraptor.tools.St;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoadingScreen extends GUITemplate {
// *INDENT-OFF*
public static double INIT_WIDTH = 550,
INIT_HEIGHT = 400;
private static final String
STARTING_FOLDER_TEXT_CLASS = "startingFolderText",
STARTING_FOLDER_LABEL_CLASS = "startingFolderLabel",
FINISHED_TEXT_CLASS = "allJobsFinishedText",
FINISHED_FOLDER_TEXT_CLASS = "folderIndexedText",
LOOKING_LABEL_CLASS = "lookingAtLabelText",
LOOKING_TEXT_CLASS = "lookingAtFolderText",
OLD_MESSAGE_CLASS = "oldMessage";
private static final int
REFRESH_TIME_TEXT_IN_MS = 300,
REFRESH_TIME_LABEL_IN_MS = 300,
MESSAGE_RINGBUFFER_SIZE = 3,
HUNDRED_PERCENT = 100,
LOADING = -1;
// *INDENT-ON*
public static final String FXML = "LoadingScreen.fxml";
private final Logger LOG = LoggerFactory.getLogger(getClass());
private Config config;
private static final DecimalFormat PERCENTAGE_FORMAT = new DecimalFormat("#.00");
private String currentFolder;
private int currentFolderIndex, folderCount;
private boolean finished;
private MainController controller;
private long indexingStartTime;
// ------------------------------------------------ //
@FXML
private Button cancelButton;
@FXML
private ToggleButton pauseButton;
@FXML
private ProgressBar progressBar;
@FXML
private ProgressBar folderProgressBar;
@FXML
private ProgressIndicator rightIndicator;
@FXML
private Label percentageLabel;
@FXML
private Label loadingScreenCounter;
@FXML
private Label cpu;
@FXML
private Label ram;
@FXML
private Label timeLabel;
@FXML
private TextFlow progressText;
@FXML
private VBox overlayLabelVbox;
@FXML
private HBox overlayLabelHbox;
@FXML
private Label overlayLabel;
@FXML
private Label overlayDetailsLabel;
// ------------------------------------------------ //
@FXML
void cancelButtonClicked(ActionEvent event) {
EventHandler<ActionEvent> handler = new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
executeWorker(shutdownWorker());
}
};
if (!finished) {
this.g.showConfirmationDialog(g.getText("LOADING_SCREEN.CANCEL_JOBS"), handler);
} else {
this.gotoPage(EditDatabase.FXML, EditDatabase.INIT_WIDTH, EditDatabase.INIT_HEIGHT);
g.getParentController().shutdown(false);
}
}
@FXML
void pauseButtonClicked(ActionEvent event) {
this.pane.requestFocus();
if (!finished) {
this.executeWorker(pauseWorker());
this.changeButtonImageColor();
this.executeWorker(disableButtonWorker(pauseButton));
} else {
this.gotoPage(SearchDialog.FXML, SearchDialog.INIT_WIDTH, SearchDialog.INIT_HEIGHT);
g.getParentController().shutdown(false);
}
}
// ------------------------------------------------ //
// --
// ------------------------------------------------ //
@Override
protected void initEventHandlers() {
this.overlayLabelVbox.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
if (!controller.paused()) {
overlayLabelVbox.setVisible(false);
}
}
});
}
@Override
protected void initVisibility() {
this.pauseButton.setDisable(false);
this.folderProgressBar.setVisible(false);
}
@Override
protected void initLabels() {
this.title.setText(g.getText("LOADING_SCREEN.TITLE"));
this.cancelButton.setText(g.getText("CANCEL"));
this.pauseButton.setText(g.getText("LOADING_SCREEN.PAUSE"));
this.addTooltip(this.rightIndicator, g.getText("LOADING_SCREEN.INDICATOR_INFO"), -205, 0);
this.addTooltip(this.loadingScreenCounter, "test", -205, 0);
}
@Override
public void initCustomComponents() {
this.controller.setStatus(Status.INDEXING);
this.g.setMessageQueue(new QueueMonitor<ProgressUpdate>(10));
this.cfg.setProp(ConfigString.LAST_TIME_MODIFIED, String.valueOf(new Date().getTime()));
Task<Object> indexWorker = indexWorker();
folderProgressBar.progressProperty().bind(indexWorker.progressProperty());
executeWorker(indexWorker);
Task<Object> progressLabelWorker = progressWorker();
progressBar.progressProperty().bind(progressLabelWorker.progressProperty());
percentageLabel.textProperty().bind(progressLabelWorker.messageProperty());
executeWorker(progressLabelWorker);
Task<Object> cpuLabelWorker = cpuWorker();
cpu.textProperty().bind(cpuLabelWorker.messageProperty());
executeWorker(cpuLabelWorker);
Task<Object> ramLabelWorker = ramWorker();
ram.textProperty().bind(ramLabelWorker.messageProperty());
executeWorker(ramLabelWorker);
Task<Object> indicatorWorker = indicatorWorker();
rightIndicator.progressProperty().bind(indicatorWorker.progressProperty());
loadingScreenCounter.textProperty().bind(indicatorWorker.messageProperty());
executeWorker(indicatorWorker);
Task<Object> visibilityWorker = visibilityWorker();
executeWorker(visibilityWorker);
Task<Object> timeLabelWorker = timeWorker();
timeLabel.textProperty().bind(timeLabelWorker.messageProperty());
executeWorker(timeLabelWorker);
}
@Override
protected void initListeners() {
// TODO Auto-generated method stub
}
@Override
protected void asserts() {
// TODO Auto-generated method stub
}
@Override
protected double getWindowWidth() {
return INIT_WIDTH;
}
@Override
protected double getWindowHeight() {
return INIT_HEIGHT;
}
// ------------------------------------------------ //
// --
// ------------------------------------------------ //
private GUIController gui;
/**
*
*
*/
public void pauseProcess() {
if (this.controller.getStatus() != Status.PAUSED) {
this.pauseButtonClicked(null);
}
}
/**
*
*/
public LoadingScreen() {
this.config = Config.inst();
this.gui = GUIController.instance();
this.controller = MainController.inst();
config.setShowProgress(true);
config.setVerbose(true);
}
/**
*
*
* @return
*/
private Task<Object> pauseWorker() {
return new Task<Object>() {
@Override
protected Object call() throws Exception {
try {
g.getParentController().pauseToggle();
Platform.runLater(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName(Config.APP_NAME + "JavaFX: pausing indexing");
if (controller.getStatus() == Status.PAUSED) {
overlayLabelVbox.setVisible(true);
overlayLabel.setText(gui.getText("LOADING_SCREEN.PAUSED"));
overlayDetailsLabel.setText(gui.getText("LOADING_SCREEN.CLICK_RESUME"));
pauseButton.setText(gui.getText("LOADING_SCREEN.RESUME"));
} else {
overlayLabelVbox.setVisible(false);
pauseButton.setText(gui.getText("LOADING_SCREEN.PAUSE"));
}
}
});
} catch (Exception e) {
// TODO: logging
e.printStackTrace();
}
return true;
}
};
}
/**
*
*
* @return
*/
private Task<Object> shutdownWorker() {
return new Task<Object>() {
@Override
protected Object call() throws Exception {
try {
g.getParentController().shutdown(false);
Platform.runLater(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName(Config.APP_NAME + "JavaFX: shutdown indexing");
gotoPage(EditDatabase.FXML, EditDatabase.INIT_WIDTH, EditDatabase.INIT_HEIGHT);
}
});
} catch (Exception e) {
// TODO: logging
e.printStackTrace();
}
return true;
}
};
}
/**
*
*
* @return
*/
private Task<Object> timeWorker() {
return new Task<Object>() {
@Override
protected Object call() throws Exception {
try {
while (!controller.stopped() && !finished && !Thread.currentThread().isInterrupted()) {
if (controller.getStatus() == Status.PAUSED) {
indexingStartTime += 1000;
} else {
final long pastTime = (System.currentTimeMillis() - indexingStartTime) / 1000;
String display = String.format("%02d:%02d:%02d", pastTime / 3600,
(pastTime % 3600) / 60, (pastTime % 60));
while (display.startsWith("00:")) {
display = display.replaceFirst("00:", "");
}
if (display.length() == 2) {
display += "s";
}
String timeLabel = gui.getText("LOADING_SCREEN.TIME", display);
updateMessage(timeLabel);
}
if (controller.getStatus() == Status.STOPPED) {
break;
}
Thread.sleep(1000);
}
if (controller.getStatus() == Status.STOPPED) {
updateMessage("... " + gui.getText("LOADING_SCREEN.PLEASE_WAIT"));
}
} catch (Exception e) {
// TODO: logging
e.printStackTrace();
}
return true;
}
};
}
/**
*
*
* @return
*/
private Task<Object> disableButtonWorker(final ToggleButton button) {
return new Task<Object>() {
@Override
protected Object call() throws Exception {
try {
// ------------------------------------------------ //
Platform.runLater(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName(Config.APP_NAME + "JavaFX: temporary disable pause button");
button.setDisable(true);
}
});
Thread.sleep(3000);
Platform.runLater(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName(Config.APP_NAME + "JavaFX: enable pause button");
button.setDisable(false);
}
});
// ------------------------------------------------ //
} catch (Exception e) {
// TODO: logging
e.printStackTrace();
}
return true;
}
};
}
/**
*
*
* @return
*/
private Task<Object> indicatorWorker() {
return new Task<Object>() {
@Override
protected Object call() throws Exception {
Thread.currentThread().setName(Config.APP_NAME + "JavaFX: Enable upper right indexing indicator");
try {
int i = 0, waitTime = 100;
final Random random = new Random();
updateProgress(0, 100);
if (!rightIndicator.isVisible()) {
Platform.runLater(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName(
"JavaFX: Enable upper right indexing indicator - sub");
rightIndicator.setVisible(true);
}
});
}
while (!controller.stopped() && !Thread.currentThread().isInterrupted()) {
// ------------------------------------------------ //
final RMIServerImpl server = g.getParentController().getServer();
if (server != null && loadingScreenCounter.isVisible()) {
updateMessage(server.getImageOCRCount() + " - "
+ St.format(server.getAllFulltextLength()));
}
if (rightIndicator.isVisible()) {
if (i++ > 98) {
i = 0;
waitTime = random.nextInt(100);
}
if (random.nextInt(10) > 8) {
if (waitTime > 5) {
waitTime = (int) ((double) waitTime / (double) 2);
}
}
if (random.nextInt(10) > 7) {
Thread.sleep(random.nextInt(500));
}
updateProgress(i, 100);
}
// ------------------------------------------------ //
Thread.sleep(waitTime);
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
};
}
/**
*
*
* @return
*/
private Task<Object> visibilityWorker() {
return new Task<Object>() {
@Override
protected Object call() throws Exception {
Thread.currentThread().setName(Config.APP_NAME + "JavaFX: Upper right indicator - visibility worker");
try {
// ------------------------------------------------ //
int waitTime = 100;
final int maxClients = g.getParentController().getNumThreads();
String progressIndicatorStyle = "";
boolean showIndicator = false;
boolean firstStart = true;
while (!controller.stopped() && !Thread.currentThread().isInterrupted()) {
final ObservableList<String> styleClasses = rightIndicator.getStyleClass();
final RMIServerImpl server = g.getParentController().getServer();
int clients = 0;
if (server != null) {
clients = server.getConnectedClientsSize();
}
String changeToStyle = null;
if (server == null) {
changeToStyle = "rightIndicatorNoServer";
} else if (clients == maxClients) {
changeToStyle = "rightIndicatorWorking";
} else if (clients == 0) {
changeToStyle = "rightIndicatorStopped";
} else {
changeToStyle = "rightIndicatorStarting";
}
// ------------------------------------------------ //
if (!progressIndicatorStyle.equals(changeToStyle)) {
if (!styleClasses.contains(changeToStyle)) {
final String styleToRemove = progressIndicatorStyle;
final String styleToAdd = changeToStyle;
Platform.runLater(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName(
"JavaFX: Upper right indicator - visibility worker - sub2");
styleClasses.remove(styleToRemove);
styleClasses.add(styleToAdd);
}
});
progressIndicatorStyle = changeToStyle;
}
}
// ------------------------------------------------ //
// -- show short start screen across the screen
// ------------------------------------------------ //
if (firstStart) {
Platform.runLater(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName(
"JavaFX: Upper right indicator - visibility worker - sub2");
overlayLabelVbox.setVisible(true);
overlayLabel.setText(gui.getText("LOADING_SCREEN.STARTING"));
overlayDetailsLabel.setText(gui.getText("LOADING_SCREEN.CAN_TAKE_A_WHILE"));
}
});
Thread.sleep(2000);
Platform.runLater(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName(
"JavaFX: Upper right indicator - visibility worker - sub3");
overlayLabelVbox.setVisible(false);
}
});
firstStart = false;
}
// ------------------------------------------------ //
if (controller.paused() || controller.finished()) {
if (showIndicator) {
showIndicator = !showIndicator;
Platform.runLater(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName(
"JavaFX: Upper right indicator - visibility worker - sub3");
rightIndicator.setVisible(false);
if (controller.finished()) {
overlayLabelVbox.setVisible(true);
overlayLabel.setText(gui.getText("LOADING_SCREEN.FINISHED"));
overlayDetailsLabel.setText(gui.getText("LOADING_SCREEN.CLOSE_OVERLAY"));
}
}
});
}
} else {
if (!showIndicator) {
showIndicator = !showIndicator;
Platform.runLater(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName(
"JavaFX: Upper right indicator - visibility worker - sub4");
rightIndicator.setVisible(true);
overlayLabelVbox.setVisible(false);
}
});
}
}
// ------------------------------------------------ //
Thread.sleep(waitTime);
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
};
}
/**
*
*
* @return
*/
private Task<Object> cpuWorker() {
return new Task<Object>() {
@Override
protected Object call() throws Exception {
try {
final SystemTools sigar = new SystemTools();
while (!controller.stopped() && !Thread.currentThread().isInterrupted()) {
DecimalFormat df = new DecimalFormat("#.00");
double percent = sigar.getCpuPercent();
String cpuLabel = "CPU: " + df.format(percent) + "%";
updateMessage(cpuLabel);
Platform.runLater(new Runnable() {
@Override
public void run() {
if (percent > 90) {
cpu.setTextFill(Color.DARKRED);
} else if (percent > 50) {
cpu.setTextFill(Color.BLACK);
} else {
cpu.setTextFill(Color.DARKGREEN);
}
}
});
if (controller.getStatus() == Status.STOPPED) {
break;
}
Thread.sleep(1000);
}
Platform.runLater(new Runnable() {
@Override
public void run() {
cpu.setTextFill(Color.BLACK);
}
});
} catch (Exception e) {
}
return true;
}
};
}
/**
*
*
* @return
*/
private Task<Object> ramWorker() {
return new Task<Object>() {
@Override
protected Object call() throws Exception {
try {
final SystemTools sigar = new SystemTools();
while (!controller.stopped() && !Thread.currentThread().isInterrupted()) {
final String freeRam = sigar.getUsedRamInReadable();
final String maxRam = sigar.getMaxRamInReadable();
final long freeRamMB = sigar.getFreeRamInMB();
Platform.runLater(new Runnable() {
@Override
public void run() {
if (freeRamMB > 2000) {
ram.setTextFill(Color.GREEN);
} else if (freeRamMB > 1000) {
ram.setTextFill(Color.BLACK);
} else {
ram.setTextFill(Color.DARKRED);
}
}
});
updateMessage("RAM: " + freeRam + "/" + maxRam);
Thread.sleep(1000);
}
} catch (Exception e) {
}
return true;
}
};
}
/**
*
*
* @param visible
*/
private void toggleProgressBarVisibility(boolean visible) {
Platform.runLater(new Runnable() {
@Override
public void run() {
folderProgressBar.setVisible(visible);
}
});
}
/**
*
*
* @return
*/
private Task<Object> indexWorker() {
return new Task<Object>() {
@Override
protected Object call() throws Exception {
Thread.currentThread().setName(Config.APP_NAME + "JavaFX: indexWorker");
try {
indexingStartTime = System.currentTimeMillis();
// amount of folders to index
folderCount = config.getExistingFoldersToIndex().size();
// iterate through given directories
for (int i = 0; i < folderCount; i++) {
// if more than one directory, make second progressbar visible {{{
if (i > 0) {
toggleProgressBarVisibility(true);
updateProgress(i, folderCount);
}
// }}}
// get and set path of current folder {{{
currentFolder = config.getExistingFoldersToIndex().get(i);
currentFolderIndex = i;
config.setDirectoryToIndex(currentFolder);
// }}}
// 'starting to index'-message
g.getMessageQueue().put(startingToIndexIndicator());
// 'scan database for missing files on start'
if (i == 0) {
g.getParentController().removeMissingFiles();
}
// start to index current folder:
MainController.inst().startIndexing();
if (controller.getStatus() == Status.STOPPED) {
break;
}
// 'folder(s) indexing finished'-message {{{
updateProgress(folderCount, folderCount);
boolean allDirectoriesIndexed = (i == folderCount - 1);
g.getMessageQueue().put(finishedToIndexIndicator(allDirectoriesIndexed));
if (allDirectoriesIndexed) {
// everything is done
}
// }}
}
controller.setStatus(Status.INDEXING_FINISHED);
// update buttons {{{
if (!controller.stopped()) {
finished = true;
updateProgress(folderCount, folderCount);
changeButtonsToFinishedState();
}
// }}}
} catch (Exception e) {
LOG.error("Index worker exception", e);
} finally {
finished = true;
}
return true;
}
};
}
/**
*
*
*/
private void changeButtonImageColor() {
Platform.runLater(new Runnable() {
@Override
public void run() {
ImageView image = null;
if (controller.getStatus() == Status.PAUSED) {
image = new ImageView(this.getClass().getResource(Icon.PLAY.toString()).toString());
} else {
image = new ImageView(this.getClass().getResource(Icon.PAUSE.toString()).toString());
}
image.setFitHeight(13);
image.setFitWidth(13);
image.setTranslateX(1);
pauseButton.setGraphic(image);
}
});
}
/**
*
*
*/
private void changeButtonsToFinishedState() {
Platform.runLater(new Runnable() {
@Override
public void run() {
cancelButton.setText(gui.getText("BACK_BUTTON"));
pauseButton.setText(gui.getText("SEARCH_BUTTON"));
ImageView image = new ImageView(this.getClass().getResource(Icon.SEARCH.toString())
.toString());
image.setFitHeight(14);
image.setTranslateX(1);
pauseButton.setGraphic(image);
}
});
}
/**
*
*
* @return
*/
private ProgressUpdate startingToIndexIndicator() throws Exception {
final String startText = gui.getText("LOADING_SCREEN.STARTING_TO_INDEX", String
.valueOf(currentFolderIndex + 1), String.valueOf(folderCount))
+ "\n";
final String folder = St.trimToLengthIndicatorLeft(St
.shortenHomePathInDirectory(currentFolder), 100)
+ "\n";
final List<Node> progressText = new ArrayList<Node>();
final Text startingFolderLabel = new Text(startText);
startingFolderLabel.getStyleClass().add(STARTING_FOLDER_LABEL_CLASS);
final Text startingFolderText = new Text(folder);
startingFolderText.getStyleClass().add(STARTING_FOLDER_TEXT_CLASS);
progressText.add(startingFolderLabel);
progressText.add(startingFolderText);
final ProgressUpdate ind = new ProgressUpdate(progressText, STARTING);
return ind;
}
/**
*
*
* @param folderOnly
* @return
*/
private ProgressUpdate finishedToIndexIndicator(boolean allDirectoriesIndexed) throws Exception {
final List<Node> progressText = new ArrayList<Node>();
final Text folderDone = new Text(gui.getText("LOADING_SCREEN.FOLDER_INDEXED") + "\n");
folderDone.getStyleClass().add(FINISHED_FOLDER_TEXT_CLASS);
progressText.add(folderDone);
if (allDirectoriesIndexed) {
final Text success = new Text(gui.getText("LOADING_SCREEN.ALL_JOBS_FINISHED") + "\n");
success.getStyleClass().add(FINISHED_TEXT_CLASS);
progressText.add(success);
}
final ProgressUpdate ind = new ProgressUpdate(progressText, INDEX_FINISHED);
return ind;
}
/**
*
*
* @return
*/
private Task<Object> progressWorker() {
return new Task<Object>() {
@Override
protected Object call() throws Exception {
Thread.currentThread().setName(Config.APP_NAME + "JavaFX: progressWorker");
try {
RingBuffer<ProgressUpdate> buffer = new RingBuffer<ProgressUpdate>(
MESSAGE_RINGBUFFER_SIZE);
long currentTime = System.currentTimeMillis();
long startTimeText = currentTime + REFRESH_TIME_TEXT_IN_MS;
long startTimeLabel = currentTime + REFRESH_TIME_LABEL_IN_MS;
// {{{ updating text in the progressbar
updateMessage(gui.getText("LOADING_SCREEN.STARTING"));
updateProgress(-1, -1);
// }}}
while (!controller.stopped() && !Thread.currentThread().isInterrupted()) {
boolean showImmediately = false;
final ProgressUpdate indicator = g.getMessageQueue().get();
// @formatter:off
final ProgressType type = indicator.getProgressType();
final List<Node> texts = indicator.getProgressText();
final Long processed = indicator.getFilesProcessed();
final Long count = indicator.getFilesCount();
// @formatter:off
// @formatter:off
if (type == STARTING || type == COUNTING_FILES_FINISHED || type == PAUSED
|| type == INDEX_FINISHED || type == NEW_FILE_FOUND) {
showImmediately = true;
}
if (type == UPDATING_FILE_LIST || type == COUNTING_FILES) {
updateProgress(LOADING, LOADING);
}
// @formatter:on
if (controller.getStatus() == Status.STOPPED && !showImmediately) {
break;
}
currentTime = System.currentTimeMillis();
final boolean refreshTimePassedLabel = (currentTime - startTimeLabel) > REFRESH_TIME_LABEL_IN_MS;
if (refreshTimePassedLabel || showImmediately) {
// set label and progress of main progressbar {{{
if (controller.getStatus() != Status.PAUSED) {
if (type == INDEX_FINISHED) {
updateMessage(gui.getText("LOADING_SCREEN.PROGRESS", String
.valueOf(HUNDRED_PERCENT)));
updateProgress(HUNDRED_PERCENT, HUNDRED_PERCENT);
} else if (processed != null && count != null) {
// aaa
updateProgress(processed, count);
final double percent = (double) processed / (double) count * HUNDRED_PERCENT;
if (!Double.isNaN(percent)) {
final String label = gui.getText("LOADING_SCREEN.PROGRESS", String
.valueOf(PERCENTAGE_FORMAT.format(percent)));
updateMessage(label);
}
}
} else if (type == UPDATING_FILE_LIST) {
updateMessage(gui.getText("LOADING_SCREEN.MISSING_FILES"));
} else if (type == COUNTING_FILES) {
updateMessage(gui.getText("LOADING_SCREEN.COUNTING_FILES"));
}
// }}}
if (texts.isEmpty()) {
continue;
}
// indicate to user, which folder is going to be indexed {{{
if (folderCount > 1
&& (type == KNOWN_FILE || type == MODIFIED_FILE || type == NEW_FILE_FOUND || type == THREAD_LIST_ONLY)) {
final String currentDirPath = St.trimToLengthIndicatorLeft(new File(
currentFolder).getName(), 80);
final Text directory = new Text(currentDirPath + "\n\n");
directory.getStyleClass().add(LOOKING_TEXT_CLASS);
final String lookingAtFolderText = gui.getText("LOADING_SCREEN.LOOKING_AT_FOLDER",
String.valueOf(currentFolderIndex + 1), String.valueOf(folderCount));
final Text dirPrefix = new Text(lookingAtFolderText);
dirPrefix.getStyleClass().add(LOOKING_LABEL_CLASS);
texts.add(0, directory);
texts.add(0, dirPrefix);
}
// }}}
// add indicator to history-buffer
buffer.add(indicator);
startTimeLabel = System.currentTimeMillis();
}
// finally, update main text flow {{{
currentTime = System.currentTimeMillis();
final boolean refreshTimePassedText = (currentTime - startTimeText) > REFRESH_TIME_TEXT_IN_MS;
if (refreshTimePassedText || showImmediately) {
if (controller.getStatus() != Status.PAUSED || type == PAUSED) {
updateTextFlow(buffer);
startTimeText = System.currentTimeMillis();
}
}
// }}}
}
updateMessage(gui.getText("LOADING_SCREEN.CANCELING"));
} catch (Exception e) {
LOG.error("ProgressWorker failed", e);
}
return true;
}
};
}
/**
*
*
* @param buffer
*/
private void updateTextFlow(RingBuffer<ProgressUpdate> buffer) {
Platform.runLater(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName(Config.APP_NAME + "JavaFX: updateTextFlow");
ObservableList<Node> nodesToRemoveFirst = progressText.getChildren();
// nodesToRemoveFirst.addListener();
for (int i = nodesToRemoveFirst.size() - 1; i >= 0; i--) {
Node nodeToRemove = nodesToRemoveFirst.get(i);
progressText.getChildren().remove(nodeToRemove);
nodeToRemove = null;
}
final Iterator<ProgressUpdate> iterator = buffer.iterator();
int iteratorCount = 1;
try {
while (iterator.hasNext()) {
final ProgressUpdate indicator = iterator.next();
if (iteratorCount > 1) {
progressText.getChildren().add(new Text(" \n "));
}
progressText.getChildren().add(new Text(" \n"));
for (final Node text : indicator.getProgressText()) {
final Text txt = ((Text) text);
if (!txt.getText().trim().isEmpty()) {
if (iteratorCount > 1
&& (iteratorCount != 2 || controller.getStatus() != Status.PAUSED)) {
final ObservableList<String> classes = txt.getStyleClass();
if (!classes.contains(OLD_MESSAGE_CLASS)) {
classes.add(OLD_MESSAGE_CLASS);
}
}
progressText.getChildren().add((Text) text);
}
}
iteratorCount++;
progressText.getChildren().add(new Text(" \n "));
progressText.getChildren().add(getCustomDivider());
}
} catch (Exception e) {
// TODO: logging
e.printStackTrace();
}
}
});
}
/**
*
*
* @return
*/
private Line getCustomDivider() {
return this.getDivider("loadingScreenDivider", 1.0f, 50, 2d, 5d);
}
/**
* @return the progressBar
*/
public ProgressBar getProgressBar() {
return progressBar;
}
/**
* @return the progressText
*/
public TextFlow getProgressText() {
return progressText;
}
}