/*
* Copyright (C) 2016 Patrick Favre-Bulle
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package at.favre.tools.dconvert.ui;
import at.favre.tools.dconvert.DConvert;
import at.favre.tools.dconvert.arg.*;
import at.favre.tools.dconvert.converters.postprocessing.MozJpegProcessor;
import at.favre.tools.dconvert.converters.postprocessing.PngCrushProcessor;
import at.favre.tools.dconvert.converters.postprocessing.WebpProcessor;
import at.favre.tools.dconvert.exceptions.InvalidArgumentException;
import at.favre.tools.dconvert.util.MiscUtil;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.*;
import java.util.List;
/**
* JavaFx main controller for GUI
*/
public class GUIController {
public VBox vboxOptionsCheckboxes;
public VBox vboxPostProcessors;
public Label labelRounding;
public Label labelThreads;
public HBox hboxWhy;
public VBox vboxFillFreeSpace;
public CheckBox cbCleanBeforeConvert;
public Label labelDownScale;
public ChoiceBox choiceDownScale;
public Label labelUpScale;
public ChoiceBox choiceUpScale;
private IPreferenceStore preferenceStore;
private final FileChooser srcFileChooser = new FileChooser();
private final DirectoryChooser srcDirectoryChooser = new DirectoryChooser();
private ResourceBundle bundle;
public Label labelPostProcessor;
public TextField textFieldSrcPath;
public Button btnSrcFile;
public Button btnSrcFolder;
public ProgressBar progressBar;
public Button btnConvert;
public TextField textFieldDstPath;
public Button btnDstFolder;
public ChoiceBox choiceCompression;
public ChoiceBox choiceCompressionQuality;
public ChoiceBox choiceRounding;
public ChoiceBox choiceThreads;
public CheckBox cbSkipExisting;
public CheckBox cbSkipUpscaling;
public CheckBox cbAndroidIncludeLdpiTvdpi;
public CheckBox cbHaltOnError;
public CheckBox cbEnablePngCrush;
public CheckBox cbEnableMozJpeg;
public CheckBox cbKeepUnoptimized;
public Slider scaleSlider;
public Label labelScale;
public Label labelResult;
public TextArea textFieldConsole;
public CheckBox cbPostConvertWebp;
public CheckBox cbMipmapInsteadDrawable;
public Label labelVersion;
public GridPane gridPaneChoiceBoxes;
public GridPane gridPanePostProcessors;
public GridPane gridPaneOptionsCheckboxes;
public Label labelScaleSubtitle;
public CheckBox cbAntiAliasing;
public Button btnReset;
public TextField textFieldDp;
public Label labelDpWidth;
public Label labelDpHeight;
public ToggleGroup scaleTypeToggleGroup;
public RadioButton rbFactor;
public RadioButton rbDpWidth;
public RadioButton rbDpHeight;
public GridPane gridPaneScaleFactorLabel;
public Label labelDpPostFix;
public CheckBox cbDryRun;
public GridPane rootGridPane;
public Label labelWhyPP;
public Button btnDstFolderOpen;
public CheckBox cbIosCreateImageset;
public GridPane gridPaneToggleGroup;
public ToggleButton tgAndroid;
public ToggleButton tgIos;
public ToggleButton tgWindows;
public ToggleButton tgWeb;
public RadioButton rbOptSimple;
public RadioButton rbOptAdvanced;
public ToggleGroup optionTypeToggleGroup;
public void onCreate(final Stage stage, IPreferenceStore store, ResourceBundle bundle) {
this.bundle = bundle;
this.preferenceStore = store;
setupLayout();
btnSrcFile.setOnAction(event -> {
srcFileChooser.setTitle(bundle.getString("main.filechooser.titel"));
File file = new File(textFieldSrcPath.getText());
if (file != null && file.isFile()) {
file = file.getParentFile();
}
if (file == null || textFieldSrcPath.getText().isEmpty() || !file.exists() || !file.isDirectory()) {
srcFileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
} else {
srcFileChooser.setInitialDirectory(file);
}
srcFileChooser.setSelectedExtensionFilter(new FileChooser.ExtensionFilter("Images", "*.jpg", "*.jpeg", "*.png", "*.gif", "*.psd", "*.svg"));
File srcFile = srcFileChooser.showOpenDialog(btnSrcFile.getScene().getWindow());
if (srcFile != null) {
textFieldSrcPath.setText(srcFile.getAbsolutePath());
if ((textFieldDstPath.getText() == null || textFieldDstPath.getText().trim().isEmpty())) {
textFieldDstPath.setText(srcFile.getParentFile().getAbsolutePath());
}
}
});
btnSrcFolder.setOnAction(new FolderPicker(srcDirectoryChooser, textFieldSrcPath, textFieldDstPath, bundle));
btnDstFolder.setOnAction(new FolderPicker(srcDirectoryChooser, textFieldDstPath, null, bundle));
btnConvert.setOnAction(event -> {
WinTaskbarProgress winTaskbarProgress = new WinTaskbarProgress();
try {
Arguments arg = getFromUI(false);
saveToPrefs(arg);
btnConvert.setDisable(true);
labelResult.setText("");
textFieldConsole.setText("");
textFieldConsole.setDisable(true);
progressBar.setProgress(0);
btnConvert.setText("");
new DConvert().execute(arg, false, new DConvert.HandlerCallback() {
@Override
public void onProgress(float progress) {
Platform.runLater(() -> {
progressBar.setProgress(progress);
winTaskbarProgress.updateProgress(progress);
});
}
@Override
public void onFinished(int finishedJobs, List<Exception> exceptions, long time, boolean haltedDuringProcess, String log) {
Platform.runLater(() -> {
resetUIAfterExecution();
labelResult.setText(
MessageFormat.format(bundle.getString("main.label.finish"), finishedJobs, exceptions.size(), MiscUtil.duration(time)));
textFieldConsole.setText(log);
textFieldConsole.appendText("");
if (!exceptions.isEmpty()) {
winTaskbarProgress.error();
Alert alert = new Alert(Alert.AlertType.WARNING);
alert.setTitle(bundle.getString("main.alert.title"));
alert.setHeaderText(null);
alert.setContentText(MessageFormat.format(bundle.getString("main.alert.content"), exceptions.size()));
alert.showAndWait();
} else {
winTaskbarProgress.finish();
}
});
}
});
} catch (Exception e) {
resetUIAfterExecution();
String stacktrace = MiscUtil.getStackTrace(e);
labelResult.setText("Error: " + e.getClass().getSimpleName());
Alert alert = new Alert(Alert.AlertType.WARNING);
alert.setTitle(e.getClass().getSimpleName());
alert.setHeaderText(e.getMessage());
alert.setContentText(stacktrace.length() > 600 ? stacktrace.substring(0, 600) + "..." : stacktrace);
alert.showAndWait();
}
});
btnDstFolder.setGraphic(new ImageView(new Image("img/folder-symbol.png")));
btnSrcFolder.setGraphic(new ImageView(new Image("img/folder-symbol.png")));
btnSrcFile.setGraphic(new ImageView(new Image("img/file-symbol.png")));
btnDstFolderOpen.setGraphic(new ImageView(new Image("img/eye.png")));
btnReset.setOnAction(event -> {
saveToPrefs(new Arguments());
loadPrefs();
});
scaleTypeToggleGroup.selectedToggleProperty().addListener((ov, old_toggle, new_toggle) -> {
scaleSlider.setVisible(!rbDpWidth.isSelected() && !rbDpHeight.isSelected());
gridPaneScaleFactorLabel.setVisible(!rbDpWidth.isSelected() && !rbDpHeight.isSelected());
textFieldDp.setVisible(rbDpWidth.isSelected() || rbDpHeight.isSelected());
labelDpPostFix.setVisible(rbDpWidth.isSelected() || rbDpHeight.isSelected());
labelDpWidth.setVisible(rbDpWidth.isSelected());
labelDpHeight.setVisible(rbDpHeight.isSelected());
});
optionTypeToggleGroup.selectedToggleProperty().addListener((observable, oldValue, newValue) -> {
if (rbOptAdvanced.isSelected()) {
if (stage.getHeight() < GUI.MIN_HEIGHT) {
stage.setHeight(GUI.MIN_HEIGHT);
}
}
});
gridPaneOptionsCheckboxes.managedProperty().bind(rbOptAdvanced.selectedProperty());
gridPaneOptionsCheckboxes.visibleProperty().bind(rbOptAdvanced.selectedProperty());
gridPanePostProcessors.managedProperty().bind(rbOptAdvanced.selectedProperty());
gridPanePostProcessors.visibleProperty().bind(rbOptAdvanced.selectedProperty());
labelPostProcessor.managedProperty().bind(rbOptAdvanced.selectedProperty());
labelPostProcessor.visibleProperty().bind(rbOptAdvanced.selectedProperty());
hboxWhy.managedProperty().bind(rbOptAdvanced.selectedProperty());
hboxWhy.visibleProperty().bind(rbOptAdvanced.selectedProperty());
vboxOptionsCheckboxes.managedProperty().bind(rbOptAdvanced.selectedProperty());
vboxOptionsCheckboxes.visibleProperty().bind(rbOptAdvanced.selectedProperty());
vboxPostProcessors.managedProperty().bind(rbOptAdvanced.selectedProperty());
vboxPostProcessors.visibleProperty().bind(rbOptAdvanced.selectedProperty());
gridPaneChoiceBoxes.managedProperty().bind(rbOptAdvanced.selectedProperty());
gridPaneChoiceBoxes.visibleProperty().bind(rbOptAdvanced.selectedProperty());
textFieldConsole.managedProperty().bind(rbOptAdvanced.selectedProperty());
textFieldConsole.visibleProperty().bind(rbOptAdvanced.selectedProperty());
vboxFillFreeSpace.managedProperty().bind(rbOptSimple.selectedProperty());
vboxFillFreeSpace.visibleProperty().bind(rbOptSimple.selectedProperty());
scaleSlider.valueProperty().addListener((observable, oldValue, newValue) -> {
labelScale.setText(
MessageFormat.format(bundle.getString("main.label.factor"), String.format(Locale.US, "%.2f", Math.round(scaleSlider.getValue() * 4f) / 4f)));
labelScaleSubtitle.setText(getNameForScale((float) scaleSlider.getValue()));
});
scaleSlider.setValue(Arguments.DEFAULT_SCALE);
setPlatformToogles(Arguments.DEFAULT_PLATFORM);
choiceCompression.setConverter(new StringConverter() {
@Override
public String toString(Object object) {
return bundle.getString(((EOutputCompressionMode) object).rbKey);
}
@Override
public Object fromString(String string) {
return EOutputCompressionMode.getFromString(string, bundle);
}
});
choiceCompression.setItems(FXCollections.observableArrayList(
EOutputCompressionMode.SAME_AS_INPUT_PREF_PNG, EOutputCompressionMode.SAME_AS_INPUT_STRICT, new Separator(), EOutputCompressionMode.AS_JPG,
EOutputCompressionMode.AS_PNG, EOutputCompressionMode.AS_GIF, EOutputCompressionMode.AS_BMP, EOutputCompressionMode.AS_JPG_AND_PNG));
choiceCompression.getSelectionModel().select(Arguments.DEFAULT_OUT_COMPRESSION);
choiceCompressionQuality.setItems(FXCollections.observableArrayList(
toJpgQ(0f), toJpgQ(0.1f), toJpgQ(0.2f), toJpgQ(0.3f), toJpgQ(0.4f), toJpgQ(0.5f), toJpgQ(0.6f), toJpgQ(0.7f), toJpgQ(0.75f), toJpgQ(0.8f), toJpgQ(0.85f), toJpgQ(0.9f), toJpgQ(0.95f), toJpgQ(1.0f)));
choiceCompressionQuality.getSelectionModel().select(toJpgQ(Float.valueOf(Arguments.DEFAULT_COMPRESSION_QUALITY)));
choiceRounding.setItems(FXCollections.observableArrayList(
RoundingHandler.Strategy.ROUND_HALF_UP, RoundingHandler.Strategy.CEIL, RoundingHandler.Strategy.FLOOR));
choiceRounding.getSelectionModel().select(Arguments.DEFAULT_ROUNDING_STRATEGY);
choiceThreads.setItems(FXCollections.observableArrayList(
1, 2, 3, 4, 5, 6, 7, 8));
choiceThreads.getSelectionModel().select(Arguments.DEFAULT_THREAD_COUNT - 1);
choiceDownScale.setItems(FXCollections.observableArrayList(EScalingAlgorithm.getForType(EScalingAlgorithm.Type.DOWNSCALING)));
choiceDownScale.getSelectionModel().select(Arguments.DEFAULT_DOWNSCALING_QUALITY);
choiceUpScale.setItems(FXCollections.observableArrayList(EScalingAlgorithm.getForType(EScalingAlgorithm.Type.UPSCALING)));
choiceUpScale.getSelectionModel().select(Arguments.DEFAULT_UPSCALING_QUALITY);
labelVersion.setText("v" + GUIController.class.getPackage().getImplementationVersion());
textFieldDp.textProperty().addListener((observable, oldValue, newValue) -> {
if (!newValue.matches("\\d*")) {
textFieldDp.setText(newValue.replaceAll("[^\\d]", ""));
}
if (textFieldDp.getText().length() > 10) {
String s = textFieldDp.getText().substring(0, 10);
textFieldDp.setText(s);
}
});
labelWhyPP.setOnMouseClicked(event -> {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Info");
alert.setHeaderText(bundle.getString("alert.whypp.title"));
alert.setContentText(bundle.getString("alert.whypp.text"));
alert.showAndWait();
});
btnDstFolderOpen.setOnAction(event -> {
try {
Desktop.getDesktop().open(new File(textFieldDstPath.getText()));
} catch (IOException e) {
e.printStackTrace();
}
});
textFieldDstPath.textProperty().addListener(observable -> {
if (textFieldDstPath != null) {
File dstFolder = new File(textFieldDstPath.getText());
if (dstFolder.exists() && dstFolder.isDirectory()) {
btnDstFolderOpen.setDisable(false);
return;
}
}
btnDstFolderOpen.setDisable(true);
});
loadPrefs();
new Thread(new PostProcessorChecker()).start();
}
public static String toJpgQ(Float floatQuality) {
return String.format(Locale.US, "%.0f", floatQuality * 100f) + "%";
}
private void setPlatformToogles(Set<EPlatform> platformSet) {
tgAndroid.setSelected(platformSet.contains(EPlatform.ANDROID));
tgIos.setSelected(platformSet.contains(EPlatform.IOS));
tgWindows.setSelected(platformSet.contains(EPlatform.WINDOWS));
tgWeb.setSelected(platformSet.contains(EPlatform.WEB));
}
private void setupLayout() {
ColumnConstraints column1M = new ColumnConstraints();
column1M.setPercentWidth(20);
ColumnConstraints column2M = new ColumnConstraints();
column2M.setPercentWidth(56);
ColumnConstraints column3M = new ColumnConstraints();
column3M.setPercentWidth(12);
ColumnConstraints column4M = new ColumnConstraints();
column4M.setPercentWidth(12);
rootGridPane.getColumnConstraints().addAll(column1M, column2M, column3M, column4M);
ColumnConstraints column1 = new ColumnConstraints();
column1.setPercentWidth(20);
ColumnConstraints column2 = new ColumnConstraints();
column2.setPercentWidth(30);
ColumnConstraints column3 = new ColumnConstraints();
column3.setPercentWidth(20);
ColumnConstraints column4 = new ColumnConstraints();
column4.setPercentWidth(30);
gridPaneChoiceBoxes.getColumnConstraints().addAll(column1, column2, column3, column4);
ColumnConstraints column1C = new ColumnConstraints();
column1C.setPercentWidth(50);
ColumnConstraints column2C = new ColumnConstraints();
column2C.setPercentWidth(50);
gridPaneOptionsCheckboxes.getColumnConstraints().addAll(column1C, column2C);
gridPanePostProcessors.getColumnConstraints().addAll(column1C, column2C);
ColumnConstraints column1D = new ColumnConstraints();
column1D.setPercentWidth(25);
ColumnConstraints column2D = new ColumnConstraints();
column2D.setPercentWidth(25);
ColumnConstraints column3D = new ColumnConstraints();
column3D.setPercentWidth(25);
ColumnConstraints column4D = new ColumnConstraints();
column4D.setPercentWidth(25);
gridPaneToggleGroup.getColumnConstraints().addAll(column1D, column2D, column3D, column4D);
}
private void saveToPrefs(Arguments arg) {
preferenceStore.save(arg);
}
private void loadPrefs() {
Arguments args = preferenceStore.get();
if (args != null) {
textFieldSrcPath.setText(args.src != null ? args.src.getAbsolutePath() : "");
textFieldDstPath.setText(args.dst != null ? args.dst.getAbsolutePath() : "");
scaleSlider.setValue(Arguments.DEFAULT_SCALE);
textFieldDp.setText(String.valueOf((int) args.scale));
if (args.scaleMode == EScaleMode.FACTOR) {
rbFactor.setSelected(true);
scaleSlider.setValue(args.scale);
textFieldDp.setText("");
} else if (args.scaleMode == EScaleMode.DP_WIDTH) {
rbDpWidth.setSelected(true);
} else if (args.scaleMode == EScaleMode.DP_HEIGHT) {
rbDpHeight.setSelected(true);
}
setPlatformToogles(args.platform);
choiceCompression.getSelectionModel().select(args.outputCompressionMode);
choiceCompressionQuality.getSelectionModel().select(toJpgQ(args.compressionQuality));
choiceRounding.getSelectionModel().select(args.roundingHandler);
choiceThreads.getSelectionModel().select(Integer.valueOf(args.threadCount));
choiceDownScale.getSelectionModel().select(args.downScalingAlgorithm);
choiceUpScale.getSelectionModel().select(args.upScalingAlgorithm);
cbSkipExisting.setSelected(args.skipExistingFiles);
cbSkipUpscaling.setSelected(args.skipUpscaling);
cbAndroidIncludeLdpiTvdpi.setSelected(args.includeAndroidLdpiTvdpi);
cbAntiAliasing.setSelected(args.enableAntiAliasing);
cbMipmapInsteadDrawable.setSelected(args.createMipMapInsteadOfDrawableDir);
cbHaltOnError.setSelected(args.haltOnError);
cbDryRun.setSelected(args.dryRun);
cbEnablePngCrush.setSelected(args.enablePngCrush);
cbPostConvertWebp.setSelected(args.postConvertWebp);
cbEnableMozJpeg.setSelected(args.enableMozJpeg);
cbKeepUnoptimized.setSelected(args.keepUnoptimizedFilesPostProcessor);
cbIosCreateImageset.setSelected(args.iosCreateImagesetFolders);
cbCleanBeforeConvert.setSelected(args.clearDirBeforeConvert);
rbOptAdvanced.setSelected(args.guiAdvancedOptions);
rbOptSimple.setSelected(!args.guiAdvancedOptions);
}
}
public Arguments getFromUI(boolean skipValidation) throws InvalidArgumentException {
float scale = Arguments.DEFAULT_SCALE;
try {
scale = rbFactor.isSelected() ? (float) scaleSlider.getValue() : Float.valueOf(textFieldDp.getText());
} catch (NumberFormatException e) {
if (!skipValidation) {
throw new InvalidArgumentException(
MessageFormat.format(bundle.getString("error.parse.dp"), textFieldDp.getText()));
}
}
Set<EPlatform> platformSet = new HashSet<>();
if (tgAndroid.isSelected()) {
platformSet.add(EPlatform.ANDROID);
}
if (tgIos.isSelected()) {
platformSet.add(EPlatform.IOS);
}
if (tgWindows.isSelected()) {
platformSet.add(EPlatform.WINDOWS);
}
if (tgWeb.isSelected()) {
platformSet.add(EPlatform.WEB);
}
Arguments.Builder builder = new Arguments.Builder(new File(textFieldSrcPath.getText()), scale);
builder.dstFolder(textFieldDstPath.getText() != null && !textFieldDstPath.getText().trim().isEmpty() ? new File(textFieldDstPath.getText()) : null);
builder.scaleMode(rbFactor.isSelected() ? EScaleMode.FACTOR : rbDpWidth.isSelected() ? EScaleMode.DP_WIDTH : EScaleMode.DP_HEIGHT);
builder.platform(platformSet);
builder.compression((EOutputCompressionMode) choiceCompression.getSelectionModel().getSelectedItem(), toJpgQFloat(choiceCompressionQuality.getSelectionModel().getSelectedItem()));
builder.scaleRoundingStragy((RoundingHandler.Strategy) choiceRounding.getSelectionModel().getSelectedItem());
builder.threadCount((Integer) choiceThreads.getSelectionModel().getSelectedItem());
builder.downScaleAlgorithm((EScalingAlgorithm) choiceDownScale.getSelectionModel().getSelectedItem());
builder.upScaleAlgorithm((EScalingAlgorithm) choiceUpScale.getSelectionModel().getSelectedItem());
builder.skipExistingFiles(cbSkipExisting.isSelected());
builder.skipUpscaling(cbSkipUpscaling.isSelected());
builder.verboseLog(true);
builder.includeAndroidLdpiTvdpi(cbAndroidIncludeLdpiTvdpi.isSelected());
builder.haltOnError(cbHaltOnError.isSelected());
builder.createMipMapInsteadOfDrawableDir(cbMipmapInsteadDrawable.isSelected());
builder.antiAliasing(cbAntiAliasing.isSelected());
builder.dryRun(cbDryRun.isSelected());
builder.enablePngCrush(cbEnablePngCrush.isSelected());
builder.postConvertWebp(cbPostConvertWebp.isSelected());
builder.enableMozJpeg(cbEnableMozJpeg.isSelected());
builder.keepUnoptimizedFilesPostProcessor(cbKeepUnoptimized.isSelected());
builder.iosCreateImagesetFolders(cbIosCreateImageset.isSelected());
builder.guiAdvancedOptions(rbOptAdvanced.isSelected());
builder.clearDirBeforeConvert(cbCleanBeforeConvert.isSelected());
return builder.skipParamValidation(skipValidation).build();
}
private float toJpgQFloat(Object selectedItem) {
String raw = selectedItem.toString();
raw = raw.replace("%", "");
int rawInt = Integer.parseInt(raw);
return (float) rawInt / 100f;
}
private void resetUIAfterExecution() {
progressBar.setProgress(0);
btnConvert.setDisable(false);
textFieldConsole.setDisable(false);
btnConvert.setText(bundle.getString("main.btn.convert"));
}
public void setSrcForTest(File srcFile) {
if (srcFile != null) {
textFieldSrcPath.setText(srcFile.getAbsolutePath());
if (textFieldDstPath != null && (textFieldDstPath.getText() == null || textFieldDstPath.getText().trim().isEmpty())) {
textFieldDstPath.setText(srcFile.getAbsolutePath());
}
}
}
private static String getNameForScale(float scale) {
String scaleString = String.format(Locale.US, "%.2f", Math.round(scale * 4f) / 4f);
switch (scaleString) {
case "0.75":
return "ldpi / " + getDpi(scaleString);
case "1.00":
return "mdpi / 1x / " + getDpi(scaleString);
case "1.50":
return "hdpi / " + getDpi(scaleString);
case "2.00":
return "xhdpi / 2x / " + getDpi(scaleString);
case "3.00":
return "xxhdpi / 3x / " + getDpi(scaleString);
case "4.00":
return "xxxhdpi / " + getDpi(scaleString);
default:
return getDpi(scaleString);
}
}
private static String getDpi(String scaleString) {
return String.format(Locale.US, "%.0f", Float.valueOf(scaleString) * 160) + "dpi";
}
private static class FolderPicker implements EventHandler<ActionEvent> {
private final DirectoryChooser directoryChooser;
private final TextField textFieldPath;
private final TextField dstTextFieldPath;
private final ResourceBundle bundle;
public FolderPicker(DirectoryChooser directoryChooser, TextField textFieldPath, TextField dstTextFieldPath, ResourceBundle bundle) {
this.directoryChooser = directoryChooser;
this.textFieldPath = textFieldPath;
this.dstTextFieldPath = dstTextFieldPath;
this.bundle = bundle;
}
@Override
public void handle(ActionEvent event) {
directoryChooser.setTitle(bundle.getString("main.dirchooser.titel"));
File dir = new File(textFieldPath.getText());
if (dir != null && dir.isFile()) {
dir = dir.getParentFile();
}
while (true) {
if (dir == null || dir.isDirectory()) break;
if (!dir.exists()) {
dir = dir.getParentFile();
}
}
if (textFieldPath.getText().isEmpty() || !dir.exists() || !dir.isDirectory()) {
directoryChooser.setInitialDirectory(new File(System.getProperty("user.home")));
} else {
directoryChooser.setInitialDirectory(dir);
}
File srcFile = directoryChooser.showDialog(textFieldPath.getScene().getWindow());
if (srcFile != null) {
textFieldPath.setText(srcFile.getAbsolutePath());
if (dstTextFieldPath != null && (dstTextFieldPath.getText() == null || dstTextFieldPath.getText().trim().isEmpty())) {
dstTextFieldPath.setText(srcFile.getAbsolutePath());
}
}
}
}
private class PostProcessorChecker implements Runnable {
@Override
public void run() {
boolean pngcrushSupported = new PngCrushProcessor().isSupported();
boolean mozJpegSupported = new MozJpegProcessor().isSupported();
boolean webpSupported = new WebpProcessor().isSupported();
Platform.runLater(() -> {
cbEnablePngCrush.setDisable(!pngcrushSupported);
cbEnableMozJpeg.setDisable(!mozJpegSupported);
cbPostConvertWebp.setDisable(!webpSupported);
labelWhyPP.setVisible(!pngcrushSupported || !mozJpegSupported || !webpSupported);
});
}
}
}