Allows setting max lines and max line length, enables DeepL, adds user setup bridge

This commit is contained in:
Guillaume Tâche
2024-08-20 21:31:10 +02:00
parent 273a6e996f
commit 44c317f207
49 changed files with 752 additions and 298 deletions

View File

@@ -12,7 +12,7 @@ public abstract class AbstractFXController {
/**
* @return the current window
*/
protected abstract Window window();
public abstract Window window();
/**
* Show an error dialog

View File

@@ -42,7 +42,7 @@ public class FXMainController extends AbstractFXController implements MainContro
}
@Override
protected Window window() {
public Window window() {
return tabPane.getScene().getWindow();
}
}

View File

@@ -37,6 +37,10 @@ public class FXParametersController extends AbstractFXController implements Para
private PrefixSelectionComboBox<String> fontFamilyCombobox;
@FXML
private TextField fontSizeField;
@FXML
private TextField maxLengthField;
@FXML
private TextField maxLinesField;
private final FXParametersModel model;
private final Preferences preferences;
@@ -68,8 +72,12 @@ public class FXParametersController extends AbstractFXController implements Para
return null;
};
fontSizeField.setTextFormatter(new TextFormatter<>(new IntegerStringConverter(), 0, integerFilter));
maxLengthField.setTextFormatter(new TextFormatter<>(new IntegerStringConverter(), 0, integerFilter));
maxLinesField.setTextFormatter(new TextFormatter<>(new IntegerStringConverter(), 0, integerFilter));
fontSizeField.textProperty().bindBidirectional(model.fontSizeProperty(), new NumberStringConverter());
maxLengthField.textProperty().bindBidirectional(model.maxLineLengthProperty(), new NumberStringConverter());
maxLinesField.textProperty().bindBidirectional(model.maxLinesProperty(), new NumberStringConverter());
loadPreferences();
}
@@ -79,11 +87,15 @@ public class FXParametersController extends AbstractFXController implements Para
final var outputFormat = preferences.get("outputFormat", model.outputFormat().name());
final var fontFamily = preferences.get("fontFamily", model.fontFamily());
final var fontSize = preferences.getInt("fontSize", model.fontSize());
final var maxLineLength = preferences.getInt("maxLineLength", model.maxLineLength());
final var maxLines = preferences.getInt("maxLines", model.maxLines());
model.setExtractionModel(extractionModelProvider.getExtractionModel(extractionModel));
model.setOutputFormat(OutputFormat.valueOf(outputFormat));
model.setFontFamily(fontFamily);
model.setFontSize(fontSize);
model.setMaxLineLength(maxLineLength);
model.setMaxLines(maxLines);
logger.info("Loaded preferences");
}
@@ -95,6 +107,8 @@ public class FXParametersController extends AbstractFXController implements Para
preferences.put("outputFormat", model.outputFormat().name());
preferences.put("fontFamily", model.fontFamily());
preferences.putInt("fontSize", model.fontSize());
preferences.putInt("maxLineLength", model.maxLineLength());
preferences.putInt("maxLines", model.maxLines());
try {
preferences.flush();
logger.info("Preferences saved");
@@ -124,7 +138,7 @@ public class FXParametersController extends AbstractFXController implements Para
}
@Override
protected Window window() {
public Window window() {
return extractionModelCombobox.getScene().getWindow();
}
}

View File

@@ -3,6 +3,8 @@ package com.github.gtache.autosubtitle.gui.fx;
import com.github.gtache.autosubtitle.gui.ParametersModel;
import com.github.gtache.autosubtitle.modules.gui.impl.FontFamily;
import com.github.gtache.autosubtitle.modules.gui.impl.FontSize;
import com.github.gtache.autosubtitle.modules.impl.MaxLineLength;
import com.github.gtache.autosubtitle.modules.impl.MaxLines;
import com.github.gtache.autosubtitle.subtitle.OutputFormat;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModelProvider;
@@ -31,9 +33,12 @@ public class FXParametersModel implements ParametersModel {
private final ObservableList<String> availableFontFamilies;
private final StringProperty fontFamily;
private final IntegerProperty fontSize;
private final IntegerProperty maxLineLength;
private final IntegerProperty maxLines;
@Inject
FXParametersModel(final ExtractionModelProvider extractionModelProvider, @FontFamily final String defaultFontFamily, @FontSize final int defaultFontSize) {
FXParametersModel(final ExtractionModelProvider extractionModelProvider, @FontFamily final String defaultFontFamily,
@FontSize final int defaultFontSize, @MaxLineLength final int defaultMaxLineLength, @MaxLines final int defaultMaxLines) {
this.availableExtractionModels = FXCollections.unmodifiableObservableList(FXCollections.observableArrayList(extractionModelProvider.getAvailableExtractionModels()));
this.extractionModel = new SimpleObjectProperty<>(extractionModelProvider.getDefaultExtractionModel());
this.availableOutputFormats = FXCollections.unmodifiableObservableList(FXCollections.observableArrayList(OutputFormat.SRT));
@@ -41,6 +46,8 @@ public class FXParametersModel implements ParametersModel {
this.availableFontFamilies = FXCollections.unmodifiableObservableList(FXCollections.observableArrayList("Arial"));
this.fontFamily = new SimpleStringProperty(defaultFontFamily);
this.fontSize = new SimpleIntegerProperty(defaultFontSize);
this.maxLineLength = new SimpleIntegerProperty(defaultMaxLineLength);
this.maxLines = new SimpleIntegerProperty(defaultMaxLines);
}
@Override
@@ -113,4 +120,32 @@ public class FXParametersModel implements ParametersModel {
IntegerProperty fontSizeProperty() {
return fontSize;
}
@Override
public int maxLineLength() {
return maxLineLength.get();
}
@Override
public void setMaxLineLength(final int maxLineLength) {
this.maxLineLength.set(maxLineLength);
}
IntegerProperty maxLineLengthProperty() {
return maxLineLength;
}
@Override
public int maxLines() {
return maxLines.get();
}
@Override
public void setMaxLines(final int maxLines) {
this.maxLines.set(maxLines);
}
IntegerProperty maxLinesProperty() {
return maxLines;
}
}

View File

@@ -314,7 +314,7 @@ public class FXSetupController extends AbstractFXController implements SetupCont
}
@Override
protected Window window() {
public Window window() {
return converterNameLabel.getScene().getWindow();
}
}

View File

@@ -1,7 +1,6 @@
package com.github.gtache.autosubtitle.gui.fx;
import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.Translator;
import com.github.gtache.autosubtitle.gui.SubtitlesController;
import com.github.gtache.autosubtitle.gui.TimeFormatter;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
@@ -9,6 +8,8 @@ import com.github.gtache.autosubtitle.subtitle.SubtitleImporterExporter;
import com.github.gtache.autosubtitle.subtitle.converter.ParseException;
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl;
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleImpl;
import com.github.gtache.autosubtitle.translation.TranslationException;
import com.github.gtache.autosubtitle.translation.Translator;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleObjectProperty;
@@ -39,6 +40,7 @@ import java.util.Comparator;
import java.util.List;
import java.util.ResourceBundle;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import static java.util.Objects.requireNonNull;
@@ -129,19 +131,30 @@ public class FXSubtitlesController extends AbstractFXController implements Subti
}
});
translationsCombobox.valueProperty().addListener((observable, oldValue, newValue) -> {
if (newValue != null && !model.collections().containsKey(newValue)) {
translationsCombobox.setOnAction(e -> {
final var value = translationsCombobox.getValue();
if (value != null && !model.collections().containsKey(value)) {
model.setTranslating(true);
CompletableFuture.supplyAsync(() -> translator.translate(model.collections().get(model.videoLanguage()), newValue))
.whenCompleteAsync((r, t) -> {
if (t == null) {
loadCollection(r);
model.setSelectedCollection(model.collections().get(newValue));
} else {
logger.error("Error while translating to {}", newValue, t);
}
model.setTranslating(false);
}, Platform::runLater);
CompletableFuture.supplyAsync(() -> {
final var mainCollection = model.collections().get(model.videoLanguage());
try {
if (mainCollection == null) {
return translator.translate(model.selectedCollection(), value);
} else {
return translator.translate(mainCollection, value);
}
} catch (final TranslationException ex) {
throw new CompletionException(ex);
}
}).whenCompleteAsync((r, t) -> {
if (t == null) {
loadCollection(r);
model.setSelectedCollection(model.collections().get(value));
} else {
logger.error("Error while translating to {}", value, t);
}
model.setTranslating(false);
}, Platform::runLater);
}
});
binder.createBindings();
@@ -197,7 +210,7 @@ public class FXSubtitlesController extends AbstractFXController implements Subti
final var toRemove = new ArrayList<Tab>();
final var toAdd = new ArrayList<Tab>();
tabPane.getTabs().forEach(tab -> {
if (!model.collections().containsKey(Language.getLanguage(tab.getText()))) {
if (tab != mainSubtitlesTab && !model.collections().containsKey(Language.getLanguage(tab.getText()))) {
toRemove.add(tab);
}
});
@@ -237,7 +250,9 @@ public class FXSubtitlesController extends AbstractFXController implements Subti
filePicker.getExtensionFilters().addAll(archiveFilter, allSupportedFilter);
filePicker.setSelectedExtensionFilter(allSupportedFilter);
final var file = filePicker.showOpenDialog(window());
loadSubtitles(file.toPath());
if (file != null) {
loadSubtitles(file.toPath());
}
}
@FXML
@@ -283,10 +298,11 @@ public class FXSubtitlesController extends AbstractFXController implements Subti
public void loadSubtitles(final Path file) {
try {
final var map = importerExporter.importSubtitles(file);
map.values().forEach(this::loadCollection);
if (model.videoLanguage() == Language.AUTO) {
model.setVideoLanguage(map.keySet().stream().findFirst().orElse(Language.AUTO));
}
map.values().forEach(this::loadCollection);
model.setSelectedCollection(model.collections().get(map.keySet().iterator().next()));
} catch (final IOException | ParseException e) {
logger.error("Error loading subtitles {}", file, e);
showErrorDialog(resources.getString("subtitles.load.error.title"), MessageFormat.format(resources.getString("subtitles.load.error.label"), file));
@@ -316,7 +332,7 @@ public class FXSubtitlesController extends AbstractFXController implements Subti
}
@Override
protected Window window() {
public Window window() {
return saveButton.getScene().getWindow();
}
}

View File

@@ -10,6 +10,7 @@ import com.github.gtache.autosubtitle.gui.fx.FXSubtitlesController;
import com.github.gtache.autosubtitle.gui.fx.FXWorkController;
import com.github.gtache.autosubtitle.modules.gui.impl.Pause;
import com.github.gtache.autosubtitle.modules.gui.impl.Play;
import com.github.gtache.autosubtitle.modules.setup.gui.fx.FXSetupModule;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
@@ -19,12 +20,11 @@ import javafx.scene.image.Image;
import javax.inject.Singleton;
import java.io.ByteArrayInputStream;
import java.util.ResourceBundle;
import java.util.prefs.Preferences;
/**
* Dagger module for FX
*/
@Module
@Module(includes = FXSetupModule.class)
public abstract class FXModule {
@Binds
@@ -69,10 +69,4 @@ public abstract class FXModule {
static Image providesPauseImage(@Pause final byte[] pauseImage) {
return new Image(new ByteArrayInputStream(pauseImage));
}
@Provides
@Singleton
static Preferences providesPreferences() {
return Preferences.userNodeForPackage(FXParametersController.class);
}
}

View File

@@ -0,0 +1,19 @@
package com.github.gtache.autosubtitle.modules.setup.gui.fx;
import com.github.gtache.autosubtitle.setup.SetupUserBridge;
import com.github.gtache.autosubtitle.setup.gui.fx.FXSetupUserBridge;
import dagger.Binds;
import dagger.Module;
/**
* Dagger module for FX setup
*/
@Module
public abstract class FXSetupModule {
private FXSetupModule() {
}
@Binds
abstract SetupUserBridge bindsSetupUserBridge(final FXSetupUserBridge setupUserBridge);
}

View File

@@ -0,0 +1,64 @@
package com.github.gtache.autosubtitle.setup.gui.fx;
import com.github.gtache.autosubtitle.gui.fx.FXMainController;
import com.github.gtache.autosubtitle.setup.SetupUserBridge;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ChoiceDialog;
import javafx.scene.control.TextInputDialog;
import javax.inject.Inject;
import java.util.List;
import java.util.Objects;
/**
* FX implementation of {@link SetupUserBridge}
*/
public class FXSetupUserBridge implements SetupUserBridge {
private final FXMainController controller;
@Inject
FXSetupUserBridge(final FXMainController mainController) {
this.controller = Objects.requireNonNull(mainController);
}
@Override
public boolean askForUserConfirmation(final String question) {
return showConfirmationDialog("Confirmation", question);
}
@Override
public <T> T askForUserChoice(final String question, final List<T> choices) {
return showChoiceDialog("Choice", question, choices);
}
@Override
public String askForUserInput(final String question) {
return showInputDialog("Input", question);
}
private <T> T showChoiceDialog(final String title, final String message, final List<T> choices) {
final var dialog = new ChoiceDialog<>(choices.getFirst(), choices);
dialog.initOwner(controller.window());
dialog.setHeaderText(message);
dialog.setTitle(title);
return dialog.showAndWait().orElse(null);
}
private String showInputDialog(final String title, final String message) {
final var dialog = new TextInputDialog();
dialog.initOwner(controller.window());
dialog.setHeaderText(message);
dialog.setTitle(title);
return dialog.showAndWait().orElse(null);
}
private boolean showConfirmationDialog(final String title, final String message) {
final var alert = new Alert(Alert.AlertType.CONFIRMATION, message, ButtonType.YES, ButtonType.NO);
alert.initOwner(controller.window());
alert.setHeaderText(null);
alert.setTitle(title);
return alert.showAndWait().map(bt -> bt == ButtonType.YES).orElse(false);
}
}

View File

@@ -13,7 +13,8 @@ module com.github.gtache.autosubtitle.gui.fx {
requires transitive java.prefs;
exports com.github.gtache.autosubtitle.gui.fx;
exports com.github.gtache.autosubtitle.modules.gui.fx;
exports com.github.gtache.autosubtitle.setup.gui.fx;
exports com.github.gtache.autosubtitle.subtitle.gui.fx;
exports com.github.gtache.autosubtitle.modules.gui.fx;
opens com.github.gtache.autosubtitle.gui.fx to javafx.fxml;
}

View File

@@ -4,37 +4,42 @@
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import org.controlsfx.control.PrefixSelectionComboBox?>
<GridPane hgap="10.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" vgap="10.0"
xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.github.gtache.autosubtitle.gui.fx.FXParametersController">
<GridPane hgap="10.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" vgap="10.0" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.github.gtache.autosubtitle.gui.fx.FXParametersController">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES"/>
<ColumnConstraints hgrow="SOMETIMES"/>
<ColumnConstraints hgrow="SOMETIMES" />
<ColumnConstraints hgrow="SOMETIMES" />
</columnConstraints>
<rowConstraints>
<RowConstraints vgrow="SOMETIMES"/>
<RowConstraints vgrow="SOMETIMES"/>
<RowConstraints vgrow="SOMETIMES"/>
<RowConstraints vgrow="SOMETIMES"/>
<RowConstraints vgrow="SOMETIMES"/>
<RowConstraints vgrow="SOMETIMES" />
<RowConstraints vgrow="SOMETIMES" />
<RowConstraints vgrow="SOMETIMES" />
<RowConstraints vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="%parameters.extraction.model.label"/>
<PrefixSelectionComboBox fx:id="extractionModelCombobox" GridPane.columnIndex="1"/>
<PrefixSelectionComboBox fx:id="extractionOutputFormat" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
<Label text="%parameters.subtitles.output.format" GridPane.rowIndex="1"/>
<Label text="%parameters.subtitles.font.size" GridPane.rowIndex="3"/>
<Label text="%parameters.subtitles.font.family" GridPane.rowIndex="2"/>
<PrefixSelectionComboBox fx:id="fontFamilyCombobox" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
<TextField fx:id="fontSizeField" GridPane.columnIndex="1" GridPane.rowIndex="3"/>
<Button mnemonicParsing="false" onAction="#savePressed" text="%parameters.button.save.label"
GridPane.columnIndex="1" GridPane.rowIndex="4"/>
<Button mnemonicParsing="false" onAction="#resetPressed" text="%parameters.button.reset.label"
GridPane.rowIndex="4"/>
<Label text="%parameters.extraction.model.label" />
<PrefixSelectionComboBox fx:id="extractionModelCombobox" GridPane.columnIndex="1" />
<PrefixSelectionComboBox fx:id="extractionOutputFormat" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Label text="%parameters.subtitles.output.format" GridPane.rowIndex="1" />
<Label text="%parameters.subtitles.font.size" GridPane.rowIndex="3" />
<Label text="%parameters.subtitles.font.family" GridPane.rowIndex="2" />
<PrefixSelectionComboBox fx:id="fontFamilyCombobox" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<TextField fx:id="fontSizeField" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<Button mnemonicParsing="false" onAction="#savePressed" text="%parameters.button.save.label" GridPane.columnIndex="1" GridPane.rowIndex="6" />
<Button mnemonicParsing="false" onAction="#resetPressed" text="%parameters.button.reset.label" GridPane.rowIndex="6" />
<Label text="%parameters.subtitles.max.length.label" GridPane.rowIndex="4" />
<Label text="%parameters.subtitles.max.lines.label" GridPane.rowIndex="5" />
<TextField fx:id="maxLengthField" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<TextField fx:id="maxLinesField" GridPane.columnIndex="1" GridPane.rowIndex="5" />
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</GridPane>

View File

@@ -1,6 +1,5 @@
package com.github.gtache.autosubtitle.gui.fx;
import com.github.gtache.autosubtitle.Translator;
import com.github.gtache.autosubtitle.VideoConverter;
import com.github.gtache.autosubtitle.VideoLoader;
import com.github.gtache.autosubtitle.gui.TimeFormatter;
@@ -8,6 +7,7 @@ import com.github.gtache.autosubtitle.modules.gui.fx.DaggerResourceComponent;
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModelProvider;
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractor;
import com.github.gtache.autosubtitle.translation.Translator;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
@@ -51,7 +51,7 @@ class TestFXParametersController extends FxRobot {
this.videoConverter = requireNonNull(videoConverter);
this.translator = requireNonNull(translator);
this.timeFormatter = requireNonNull(timeFormatter);
this.model = spy(new FXParametersModel(mock(ExtractionModelProvider.class), "Arial", 12));
this.model = spy(new FXParametersModel(mock(ExtractionModelProvider.class), "Arial", 12, 40, 1));
this.binder = requireNonNull(binder);
this.window = FxToolkit.registerPrimaryStage();
this.controller = spy(FXParametersController.class);

View File

@@ -21,6 +21,8 @@ class TestFXParametersModel {
private static final String DEFAULT_FONT_FAMILY = "Arial";
private static final int DEFAULT_FONT_SIZE = 12;
private static final int DEFAULT_MAX_LINE_LENGTH = 40;
private static final int DEFAULT_MAX_LINES = 2;
private final List<ExtractionModel> availableExtractionModels;
private final ExtractionModel defaultExtractionModel;
private final ExtractionModelProvider provider;
@@ -34,7 +36,7 @@ class TestFXParametersModel {
when(provider.getDefaultExtractionModel()).thenReturn(defaultExtractionModel);
this.availableExtractionModels = List.of(defaultExtractionModel, extractionModel);
when(provider.getAvailableExtractionModels()).thenReturn(availableExtractionModels);
model = new FXParametersModel(extractionModelProvider, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE);
model = new FXParametersModel(extractionModelProvider, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_MAX_LINE_LENGTH, DEFAULT_MAX_LINES);
}
@Test

View File

@@ -1,12 +1,12 @@
package com.github.gtache.autosubtitle.gui.fx;
import com.github.gtache.autosubtitle.Translator;
import com.github.gtache.autosubtitle.VideoConverter;
import com.github.gtache.autosubtitle.VideoLoader;
import com.github.gtache.autosubtitle.gui.TimeFormatter;
import com.github.gtache.autosubtitle.modules.gui.fx.DaggerResourceComponent;
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractor;
import com.github.gtache.autosubtitle.translation.Translator;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;

View File

@@ -1,12 +1,12 @@
package com.github.gtache.autosubtitle.gui.fx;
import com.github.gtache.autosubtitle.Translator;
import com.github.gtache.autosubtitle.VideoConverter;
import com.github.gtache.autosubtitle.VideoLoader;
import com.github.gtache.autosubtitle.gui.TimeFormatter;
import com.github.gtache.autosubtitle.modules.gui.fx.DaggerResourceComponent;
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractor;
import com.github.gtache.autosubtitle.translation.Translator;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;

View File

@@ -12,7 +12,7 @@ class TestFXWorkBinder {
@Test
void testBindings() {
final var workModel = new FXWorkModel();
final var parametersModel = new FXParametersModel(mock(ExtractionModelProvider.class), "Arial", 12);
final var parametersModel = new FXParametersModel(mock(ExtractionModelProvider.class), "Arial", 12, 40, 1);
final var binder = new FXWorkBinder(workModel, parametersModel);
binder.createBindings();
assertNull(workModel.extractionModel());

View File

@@ -11,7 +11,6 @@ import javafx.scene.image.Image;
import org.junit.jupiter.api.Test;
import java.util.ResourceBundle;
import java.util.prefs.Preferences;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.mockito.Mockito.mock;
@@ -36,8 +35,4 @@ class TestFXModule {
assertInstanceOf(Image.class, FXModule.providesPauseImage(IMAGE));
}
@Test
void testPreferences() {
assertInstanceOf(Preferences.class, FXModule.providesPreferences());
}
}