package ch.retorte.intervalmusiccompositor.ui.debuglog; import ch.retorte.intervalmusiccompositor.commons.MessageFormatBundle; import ch.retorte.intervalmusiccompositor.spi.ProgramControl; import javafx.application.Platform; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.TextArea; import javafx.stage.Stage; import java.io.IOException; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; /** * The debug log window shows the current debug log in a text area. */ public class DebugLogWindow { //---- Static private static final String LAYOUT_FILE = "/layouts/DebugLogWindow.fxml"; //---- Fields @FXML private TextArea logField; @FXML private Button closeButton; private Parent parent; private MessageFormatBundle messageFormatBundle; private ProgramControl programControl; private ScheduledExecutorService executorService; private AtomicBoolean recentUpdate = new AtomicBoolean(false); //---- Constructor public DebugLogWindow(MessageFormatBundle messageFormatBundle, ProgramControl programControl, ScheduledExecutorService executorService) { this.messageFormatBundle = messageFormatBundle; this.programControl = programControl; this.executorService = executorService; loadFXML(); bindLogData(); bindButton(); } private void loadFXML() { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(LAYOUT_FILE), messageFormatBundle.getBundle()); fxmlLoader.setController(this); try { parent = fxmlLoader.load(); } catch (IOException exception) { throw new RuntimeException(exception); } } private void bindLogData() { logField.setText(programControl.getLogBuffer().toString()); programControl.getLogBuffer().addObserver((logBuffer, arg) -> { if (recentUpdate.compareAndSet(false, true)) { updateLogContent(); scheduleFlagUpdate(); } }); } private void scheduleFlagUpdate() { if (!executorService.isTerminated()) { executorService.schedule(() -> { recentUpdate.set(false); updateLogContent(); }, 1, TimeUnit.SECONDS); } } private void updateLogContent () { Platform.runLater(() -> { logField.setText(programControl.getLogBuffer().toString() + "\n\n"); logField.setScrollTop(Double.MAX_VALUE); }); } private void bindButton() { closeButton.setOnAction(event -> hide()); } public void show() { Stage stage = new Stage(); stage.setTitle(messageFormatBundle.getString("ui.debugLog.title")); stage.setScene(new Scene(parent, 800, 600)); stage.setResizable(true); stage.show(); } private void hide() { parent.getScene().getWindow().hide(); } }