Commit e947127d authored by Axel Howind's avatar Axel Howind

file chooser input

parent 6d34fd7c
package com.dua3.fx.samples;
import com.dua3.fx.util.Dialogs;
import com.dua3.fx.util.controls.InputBuilder;
import com.dua3.utility.io.CsvIo;
import javafx.application.Application;
import javafx.scene.Scene;
......@@ -65,6 +66,7 @@ public class DialogSample extends Application {
i -> i >= 4 && i <= 7 ? Optional.empty() : Optional.of(i + " is not between 4 and 7"))
.comboBox("list", "choose one", () -> "Maybe", String.class, List.of("Yes", "No", "Maybe"))
.checkBox("bool", "Yes or No:", () -> false, "yes")
.chooseFile("file", "File", () -> null, InputBuilder.FileDialogMode.OPEN)
.showAndWait();
}));
......
package com.dua3.fx.util.controls;
import com.dua3.fx.util.Dialogs;
import javafx.beans.binding.*;
import javafx.beans.property.*;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;
import java.util.function.Supplier;
public class FileInput extends HBox implements InputControl<File> {
private final ObjectProperty<File> value = new SimpleObjectProperty<>();
private final InputBuilder.FileDialogMode mode;
private final Supplier<File> dflt;
private final TextField tfFilename;
private final Button button;
private final StringProperty error = new SimpleStringProperty("");
public FileInput(InputBuilder.FileDialogMode mode, Supplier<File> dflt) {
this.mode = mode;
this.dflt = Objects.requireNonNull(dflt);
this.tfFilename = new TextField();
this.button = new Button("...");
button.setOnAction(evt -> {
File initialDir = value.get();
if (initialDir!=null && !initialDir.isDirectory()) {
initialDir = initialDir.getParentFile();
}
if (initialDir==null) {
initialDir=new File(".");
}
if (mode== InputBuilder.FileDialogMode.OPEN) {
Dialogs.chooseFile()
.initialDir(initialDir)
.showOpenDialog(null)
.ifPresent(f -> value.setValue(f));
} else {
Dialogs.chooseFile()
.initialDir(initialDir)
.showSaveDialog(null)
.ifPresent(f -> value.setValue(f));
}
});
this.getChildren().setAll(tfFilename, button);
StringBinding fname = Bindings.createStringBinding(() -> Objects.toString(value.get(), ""), value);
tfFilename.textProperty().bind(fname);
StringExpression errorText = Bindings.createStringBinding(
() -> {
File file = value.get();
if (file == null ) {
return "No file selected.";
}
if (mode==InputBuilder.FileDialogMode.OPEN && !Files.exists(file.toPath())) {
return "File does not exist: "+file;
}
return "";
},
value
);
error.bind(errorText);
}
@Override
public Node node() {
return this;
}
@Override
public void reset() {
value.setValue(dflt.get());
}
@Override
public Property<File> valueProperty() {
return value;
}
private Path getPath() {
File file = value.get();
return file == null ? null : file.toPath();
}
@Override
public ReadOnlyBooleanProperty validProperty() {
BooleanProperty valid = new SimpleBooleanProperty();
BooleanExpression isNotNull = value.isNotNull();
if (mode== InputBuilder.FileDialogMode.OPEN) {
BooleanBinding exists = Bindings.createBooleanBinding(() -> getPath()!=null && Files.exists(getPath()), value);
Bindings.and(isNotNull, exists);
} else {
valid.bind(value.isNotNull());
}
return valid;
}
@Override
public ReadOnlyStringProperty errorProperty() {
return error;
}
}
package com.dua3.fx.util.controls;
import com.dua3.utility.options.OptionSet;
import com.dua3.utility.options.OptionValues;
import java.io.File;
import java.util.Collection;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
import com.dua3.utility.io.OpenMode;
import com.dua3.utility.options.OptionSet;
import com.dua3.utility.options.OptionValues;
public interface InputBuilder<B extends InputBuilder<B>> {
/**
......@@ -253,6 +252,8 @@ public interface InputBuilder<B extends InputBuilder<B>> {
* Add File chooser.
* @param id
* the ID
* @param label
* the label text
* @param dflt
* supplier of default value
* @param mode
......@@ -260,5 +261,5 @@ public interface InputBuilder<B extends InputBuilder<B>> {
* @return
* {@code this}
*/
B chooseFile(String id, Supplier<File> dflt, FileDialogMode mode);
B chooseFile(String id, String label, Supplier<File> dflt, FileDialogMode mode);
}
\ No newline at end of file
......@@ -20,6 +20,7 @@ import javafx.beans.binding.Bindings;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import java.io.File;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
......@@ -120,4 +121,9 @@ implements InputBuilder<InputDialogBuilder> {
return this;
}
@Override
public InputDialogBuilder chooseFile(String id, String label, Supplier<File> dflt, FileDialogMode mode) {
pb.chooseFile(id, label, dflt, mode);
return this;
}
}
......@@ -21,6 +21,7 @@ import com.dua3.utility.options.OptionSet;
import com.dua3.utility.options.OptionValues;
import javafx.scene.control.ButtonType;
import java.io.File;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
......@@ -136,6 +137,11 @@ implements InputBuilder<InputPaneBuilder> {
return add(id, OptionValues.class, dflt, new OptionsPane(options, dflt));
}
@Override
public InputPaneBuilder chooseFile(String id, String label, Supplier<File> dflt, FileDialogMode mode) {
return add(id, label, File.class, dflt, new FileInput(mode, dflt));
}
// TODO: add date and time inputs
public InputPaneBuilder button(ButtonType b, Consumer<InputDialogPane> action) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment