Deleting a file(s) through FileChooser? - javafx

I have a JavaFX app using JRE1.8.0 u40. I converted my Swing JFileChooser Open and Save to the newer JavaFX FileChooser Open and Save, Windows7 style Dialog box. But I have not found an equivalent JavaFX FileChooser method to replace the JFileChooser method I'm using for deleting a file(s) as shown below:
public static void deleteFile() throws IOException {
JFileChooser fileDialog = new JFileChooser("C:\\ProgramData\\L1 Art Files\\");
File[] selectedFiles;
fileDialog.setSelectedFiles(null);
// Set frame properties
fileDialog.setDialogTitle("Delete Pixel Art File(s)");
//fileDialog.setLayout(new FlowLayout());
fileDialog.setSize(400, 400);
fileDialog.setVisible(true);
fileDialog.setMultiSelectionEnabled(true); // Allow multiple selection
fileDialog.setVisible(true);
int option = fileDialog.showDialog(null, "Delete");
if (option != JFileChooser.APPROVE_OPTION)
return; //user canceled the
selectedFiles = fileDialog.getSelectedFiles();
if (selectedFiles != null) { //ask the user to replace this file
int response = JOptionPane.showConfirmDialog(null, "Are you sure want to delete this file?",
"Confirm Delete",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE);
if (response != JOptionPane.YES_OPTION) return;
}
for (File f : selectedFiles) {
Files.delete(f.toPath());
}
Is there a similar solution to the above for JavaFX using FileChooser or do I use the showOpenDialog(null) with setTitle("Delete Pixel Art File")?

You can easily perform that task using javafx like below :
#FXML
private void onDeleteAction(ActionEvent event) {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Your_title_here");
List<File> selectedFiles = fileChooser.showOpenMultipleDialog(null);
if (selectedFiles != null) {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setTitle("Confirmation Dialog");
alert.setHeaderText("Warning !");
alert.setContentText("Are you sure you want to delete these files ?");
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == ButtonType.OK) {
for (File selectedFile : selectedFiles) {
selectedFile.delete();
}
}
} else {
System.out.println("Error Selection");
}
}

The above code was very helpful and works best with the other suggestion of checking for null and adding throws IOException to the deleteFile() method.

Related

How to stay in the same fxml when calling an Alert Class?

I have created this methode for Email validation
The issue is that the Alert displayed goes on the top of the previous fxml instead of the same and the user have to fulfill all the fields again
I have this method
public boolean validateEmail() {
Pattern p = Pattern.compile("[a-zA-Z0-9][a-zA-Z0-9._]*#[a-zA-Z0-9]+([.][a-zA-Z]+)+");
Matcher m = p.matcher(emailField.getText());
if (m.find() && m.group().equals(emailField.getText())) {
return true;
} else {
Alert alert = new Alert(Alert.AlertType.WARNING);
alert.setTitle("Validation of Email");
alert.setHeaderText(null);
alert.setContentText("Please enter a valid Email");
alert.showAndWait();
return false;
}
}
I have a button which onAction calls the method below
public void showSubscription() throws IOException {
Dialog<ButtonType> dialog = new Dialog<>();
dialog.setTitle("New Subscription");
dialog.setHeaderText("Please Fulfill your information to subscribe");
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("Registration.fxml"));
try {
dialog.getDialogPane().setContent(fxmlLoader.load());
} catch (IOException e) {
System.out.println("Couldn't load the Dialog");
e.printStackTrace();
return;
}
dialog.getDialogPane().getButtonTypes().add(ButtonType.OK);
dialog.getDialogPane().getButtonTypes().add(ButtonType.CANCEL);
Optional<ButtonType> result = dialog.showAndWait();
if (result.isPresent() && result.get()==ButtonType.OK) {
RegistrationController controller = fxmlLoader.getController();
if (controller.validateEmail()) {
controller.loadRegistration();
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Information");
alert.setHeaderText(null);
alert.setContentText("Subscription Done Correctly");
alert.showAndWait();
}
}
else {
System.out.println("CANCEL pressed");
}
}
I don't know what to add to make this Alert popup in the same Registration.fxml and not go back to the previous one.
Alert inherits an initOwner(Window) method from Dialog. So you can call initOwner(...) and pass in the window responsible for showing the dialog. There's no direct reference to this, but you can get it from the scene containing the dialog's dialog pane:
alert.initOwner(dialog.getDialogPane().getScene().getWindow());
This line just needs to be called sometime before alert.showAndWait().
If you need the Alert created in the validateEmail() method to have the same owner, just pass a reference to the appropriate window to that method:
public boolean validateEmail(Window mainWindow) {
// ...
Alert alert = new Alert(Alert.AlertType.WARNING);
alert.initOwner(mainWindow);
// ...
alert.showAndWait();
// ...
}
and
RegistrationController controller = fxmlLoader.getController();
if (controller.validateEmail(dialog.getDialogPane().getScene().getWindow())) {
// ...
}

How can i make JavaFX filechooser alwaysonTop of window?

How can i make JavaFX filechooser is always on top?
In my application some other dialogs call filechooser and that dialog is set as alwaysonTop, so the filechooser dialog is located behind that dialog.
How can i make the filechooser dialog is alwaysonTop of the window?
I made filechooser like this code.
public static File getSaveFileFX(final String suffix, String title) {
File[] selectedFile = {null};
FileChooser fc = new FileChooser();
fc.setTitle(title);
String root = "*" + suffix;
String fileFormat = suffix + " files";
fc.getExtensionFilters().addAll(new ExtensionFilter(fileFormat, root));
fc.setInitialDirectory(new File(getRecentDirectoryPath()));
PlatformImpl.runAndWait(new Runnable() {
#Override
public void run() {
selectedFile[0] = fc.showSaveDialog(null);
if(selectedFile[0] != null && !title.equals("Sava To .CSV file")) {
//filtering with title
mPreferences.put(RECENT_FILE_PATH, selectedFile[0].getAbsolutePath());
mPreferences.put(RECENT_DIRECTORY_PATH, selectedFile[0].getParent());
}
}
});
if(selectedFile[0] != null && !selectedFile[0].getName().endsWith(suffix)) {
return new File(selectedFile[0].getAbsolutePath()+"."+suffix);
}else {
return selectedFile[0];
}
}
and the other dialog is set as
dialog.alwaysOnTop(true);
You have to set main dialog alwaysOnTop(false);
And the dialog of FileChooser alwaysOnTop(true);
Check this sample, its work.
public void initializationDialog(Stage stage) {
stage.resizableProperty().setValue(false);
stage.setAlwaysOnTop(false);
stage.toBack();
openFile();
}
public File openFile(String descriptionOfFile, String extensionOfFile) {
FileChooser fileChooser = new FileChooser();
Stage stage2 = new Stage();
stage2.initOwner(stage);
stage2.initModality(Modality.WINDOW_MODAL);
stage2.setAlwaysOnTop(true);
FileChooser.ExtensionFilter filter = new FileChooser.ExtensionFilter(descriptionOfFile, extensionOfFile);
fileChooser.getExtensionFilters().add(filter);
return fileChooser.showOpenDialog(stage2);
}

Issue relating to JavaFX GUI event handling and updating

apologies for the length of my code. I realized last night that I was on the wrong path and now have gotten stuck on an issue that I think relates to JavaFX event handling. Initially I had the logic functioning outside a GUI in a basic loop that depended on interaction through the console. Everything was working great. I've now tried to get this to work in a GUI with interaction from the user.
I have two main problems with the code below.
The first is that the text in textArea is not updating with additional text after the startButton executes the start of my main logic sequence. The first append starts right under the first while loop. I was hoping to have this show up in the GUI as the logic executes. I'm not sure if I need to tell the GUI to update at certain intervals or if there's something else wrong.
Second, I'm not sure how to get the program to wait for the user to type in something into textField before hitting the textButton I created to continue on. I used to have a scanner created which caused the program to wait in the console for input. I realize I need some way of telling it to wait for a button press when it's running inside JavaFX.
I chose not to include the rest of the code to make things easier to read, but I can add it on if it will help resolve this issue.
Thank you everyone for your help!
public class FxApp extends Application {
//Creates FileParser object with methods that alter the incoming Array of Strings into the format we need
FileParser fileParser = new FileParser();
Configure configure = new Configure();
private String text;
private String initialState;
private ArrayList<Machine> machines = new ArrayList<Machine>();
private Map<String, String> initialStates = new HashMap<String, String>();
private Map<String, String> states = new HashMap<String, String>();
private Map<String, ArrayDeque<String>> queues = new HashMap<String, ArrayDeque<String>>();
private Map<Integer, ArrayList<String>> parsedData = new HashMap<Integer, ArrayList<String>>();
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("File Chooser");
FileChooser fileChooser = new FileChooser();
fileChooser.getExtensionFilters().addAll(new ExtensionFilter("Text Files", "*.txt"));
Button startButton = new Button("Start");
Button openButton = new Button("Click to open a file...");
openButton.setPrefSize(200, 80);
Button textButton = new Button("Enter");
TextArea textArea = new TextArea();
textArea.setWrapText(true);
TextField textField = new TextField();
Label lbl = new Label();
VBox vbox = new VBox(lbl, openButton, startButton, textArea, textField, textButton);
vbox.setSpacing(10);
vbox.setPadding(new Insets(15));
lbl.setText("This tool creates virtual automata based \ron the file.");
Scene scene = new Scene(vbox, 640, 480);
primaryStage.setScene(scene);
primaryStage.show();
openButton.setOnAction(
new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
File file = fileChooser.showOpenDialog(primaryStage);
if (file != null) {
//Execute the method to convert to string array before sending to file parser
try {
fileParser.convertFile(file);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
});
textButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
text = textField.getText();
}
});
startButton.setOnAction(new EventHandler <ActionEvent>()
{
public void handle(ActionEvent event)
{
machineCreation();
String exit = "no";
String nextLine = null;
ArrayList<String> listOfCurrentTransitions = new ArrayList<String>();
int nextInt = 0;
states = initialStates;
while(!(exit.toLowerCase().equals("yes"))) {
textArea.appendText("Choose a state to load");
//Print out the states possible for each machine
ArrayList<String> tempTrans = machines.get(nextInt).getTransitions();
//This loops through the list of transitions of the machine and pulls possible transitions from its current state
for(int i = 0; i < tempTrans.size(); i++) {
String pull = tempTrans.get(i);
String[] apart = pull.split(" ");
pull = apart[0];
if(states.get(Integer.toString(nextInt)).equals(pull)) {
listOfCurrentTransitions.add(tempTrans.get(i));
}
}
if(!(listOfCurrentTransitions.isEmpty())) {
textArea.appendText("The following transitions are possible. Choose one: " + listOfCurrentTransitions);
}
else {
textArea.appendText("No transitions for this machine exist from its current state");
}
//Tell GUI to wait for user input in textField and execute textButton which assigns to String text. Resume on button click.
The while loop blocks the JavaFX application thread which prevents updates of the GUI and handling of events.
You need to execute the logic of a single iteration of the loop on each "text commit" instead:
private TextArea textArea;
private void activateState(int nextInt) {
ArrayList<String> listOfCurrentTransitions = new ArrayList<String>();
textArea.appendText("Choose a state to load");
//Print out the states possible for each machine
ArrayList<String> tempTrans = machines.get(nextInt).getTransitions();
//This loops through the list of transitions of the machine and pulls possible transitions from its current state
for(int i = 0; i < tempTrans.size(); i++) {
String pull = tempTrans.get(i);
String[] apart = pull.split(" ");
pull = apart[0];
if(states.get(Integer.toString(nextInt)).equals(pull)) {
listOfCurrentTransitions.add(tempTrans.get(i));
}
}
if(listOfCurrentTransitions.isEmpty()) {
textArea.appendText("No transitions for this machine exist from its current state");
} else {
textArea.appendText("The following transitions are possible. Choose one: " + listOfCurrentTransitions);
}
}
#Override
public void start(Stage primaryStage) throws Exception {
...
textArea = new TextArea();
...
startButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
machineCreation();
activateState(0);
}
});
textButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
// read input and ask for more input...
int nextState = Integer.parseInt(textField.getText()); // TODO: deal with invalid input
activateState(nextState);
}
});
You probably need to fix the logic a bit to verify a transition is valid, change the values of some fields ect...

why javafx mediaplayer status sometimes returns unknown?

First i am sorry for my poor english...
i made Media Player Application with Javafx.
this player can get mulit file media. and play files out of all limits.
it work well. but sometimes not work..
it is not media error. it is mediaplayer error.
error message is 'mediaPlayer Unknown, media Invalid..' why.??
i played same video file(1920 * 1080), sometimes work and sometimes not work..
and javafx is depend on OS ??
player works perfectly on windown7 computer
but player have this error on windown10 computer...
please give me advice..
MediaPlayer mediaPlayer = null;
Stage stage = new Stage();
AnchorPane pane = new AnchorPane();
Scene scene = new Scene(pane);
MediaView mediaView = new MediaView();
int mNextFileIndex = -1;
List<File> fileLists = new ArrayList<>();
Media media;
mediaplayer play Method
public void playNextMedia() {
if (mediaPlayer != null) {
mediaPlayer.dispose();
mediaView.setMediaPlayer(null);
}
mNextFileIndex = (mNextFileIndex + 1) % fileLists.size();
media =new Media(fileLists.get(mNextFileIndex).toURI().toString());
media.setOnError(()-> {
MainApp.makeLog("media error");
});
mediaPlayer = new MediaPlayer(media);
mediaView.setMediaPlayer(mediaPlayer);
mediaPlayer.setOnReady(() -> {
mediaPlayer.play();
});
mediaPlayer.setOnEndOfMedia(() -> {
playNextMedia();
});
mediaPlayer.setOnError(() -> {
systom.out.println("mediaPlayer error");
Systeom.out.println(mediaPlayer.getError().getMessage());
playNextMedia();
});
}
Button Method
#FXML
private void playMedia(ActionEvent event) {
mNextFileIndex = -1;
FileChooser fileChooser = new FileChooser();
fileChooser.getExtensionFilters().addAll(new
FileChooser.ExtensionFilter("Select a File (*.mp4)", "*.mp4"),
new FileChooser.ExtensionFilter("All Files", "*.*"));
List<File> list = fileChooser.showOpenMultipleDialog(null);
if (list != null) {
for (File file : list) {
fileLists.add(file)
}
playNextMedia();
pane.getChildren().add(mediaView);
stage.setScene(scene);
stage.show();
}

Screenshot saving error JavaFX

I am trying to save a screenshot of the current scene using javaFX.
saveMenuItem.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
WritableImage image = scene.snapshot(new SnapshotParameters(), null);
// TODO: probably use a file chooser here
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Save Image");
File file = fileChooser.showSaveDialog(primaryStage);
if(file != null)
{
try {
ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", file);
}
catch (IOException e) {
System.out.println("Couldn't Save.");
}
}
}
});
But my compiler NetBeans IDE 8.1 is giving an error:
incompatible types: SnapshotParameters cannot be converted to Callback<SnapshotResult, Void>
Can someone tell me what I am doing wrong?
And your compiler is right. A Scene just does not have a method like the one you are trying to call. Just use
WritableImage image = scene.snapshot(null);

Resources