Is it possible in javafx to open new stages (windows) from another fxml with a button? Thanks for the answers.
Because I got this error :
javafx.fxml.LoadException:
/C:/Users/Me/Desktop/jj/target/classes/com/example/jj/path-window.fxml
This is my code :
package com.example.jj;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 520, 440);
stage.setTitle("Download Files");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(new String[0]);
}
}
package com.example.jj;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Paths;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class HelloController {
@FXML
public TextField downloadUrl;
@FXML
public TextField pathUrl;
@FXML
public Button downloadButton;
@FXML
public Button DownloadAll;
@FXML
public Button btnInsert;
@FXML
public Button btnn1;
@FXML
public ProgressBar progressBar;
@FXML
public Label progressLabel;
@FXML
public TableView<Url> table;
@FXML
public TableColumn<Url,String> FileName;
@FXML
public TableColumn<Url,String> Size;
@FXML
public TableColumn<Url,String> Status;
@FXML
public TableColumn<Url,String> Progress;
@FXML
public TableColumn<Url,String> Urltext;
ExecutorService executor = Executors.newFixedThreadPool(4); // Limit to 4 threads
public void initialize() throws MalformedURLException {
downloadButton.setOnAction(e -> downloadFile());
FileName.setCellValueFactory(new PropertyValueFactory<>("FileName"));
Size.setCellValueFactory(new PropertyValueFactory<>("Size"));
Status.setCellValueFactory(new PropertyValueFactory<>("Status"));
Progress.setCellValueFactory(new PropertyValueFactory<>("Progress"));
// String urlText = this.downloadUrl.getText().trim(); // Trim to remove leading/trailing spaces
//
// // Check if the provided text is a valid URL
// URL url = new URL(urlText);
//
// // Get the file name from the URL
// String fileName = Paths.get(url.getFile()).getFileName().toString();
// String extension = fileName.substring(fileName.lastIndexOf(".") + 1);
// System.out.println("File extension: " + extension);
//
// FileChooser fileChooser = new FileChooser();
// fileChooser.setTitle("Save As");
// fileChooser.setInitialFileName(fileName + "." + extension); // Set the initial file name
// this.pathUrl.setText("C:\\Users\\Me\\Desktop\\Down test");
}
@FXML
public void btnPath (ActionEvent event){
String pathText = this.pathUrl.getText().trim();
}
@FXML
public void btnDownloadAll (ActionEvent event){
// Assuming your TableView contains a list of strings (file URLs)
// ObservableList<Url> urlList = table.getItems();
ObservableList<Url> urlList = table.getItems()
.filtered(url -> "waiting".equals(url.getStatus()));
for (Url url : urlList) {
String urlText = url.getUrltext();
String status = url.getStatus();
if (status.equals("waiting")) {
System.out.println("Downloading: " + urlText);
executor.submit(() -> {
DownloadAll.setOnAction(e -> downloadFile());
});
}
}
}
@FXML
public void updateStatus(int rowIndex, String newStatus) {
if (rowIndex >= 0 && rowIndex < table.getItems().size()) {
Url url = table.getItems().get(rowIndex);
url.setStatus(newStatus); // Update the status
table.refresh(); // Refresh the table to reflect changes
}
}
@FXML
public void btnn1(ActionEvent event) throws IOException {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("path-window.fxml"));
Parent root = loader.load();
Stage secondaryStage = new Stage();
secondaryStage.setScene(new Scene(root));
secondaryStage.setTitle("Secondary Window");
secondaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
@FXML
public void btnInsert (ActionEvent event) throws IOException {
// try {
// FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("path-window.fxml"));
// Parent root1 = (Parent) fxmlLoader.load();
// Stage stage = new Stage();
// stage.initModality(Modality.APPLICATION_MODAL);
// stage.initStyle(StageStyle.UNDECORATED);
// stage.setTitle("ABC");
// stage.setScene(new Scene(root1));
// stage.show();
// } catch(Exception e) {
// e.printStackTrace();
// }
String urlText = this.downloadUrl.getText().trim(); // Trim to remove leading/trailing spaces
URL url = null;
try {
url = new URL(urlText);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
String fileName = Paths.get(url.getFile()).getFileName().toString();
long fileSize = 0;
try {
fileSize = url.openConnection().getContentLengthLong();
} catch (IOException e) {
throw new RuntimeException(e);
}
String path = null;
Url obj = new Url(fileName,fileSize,"waiting","0.0",urlText, path);
table.getItems().add(obj);
}
private void downloadFile() {
this.progressBar.setVisible(true);
this.progressLabel.setVisible(true);
String urlText = this.downloadUrl.getText().trim(); // Trim to remove leading/trailing spaces
if (urlText.isEmpty()) {
// Alert user if URL is empty
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("URL not found!");
alert.setHeaderText("Please provide the URL!");
alert.show();
} else {
try {
// Check if the provided text is a valid URL
URL url = new URL(urlText);
// Get the file name from the URL
String fileName = Paths.get(url.getFile()).getFileName().toString();
String extension = fileName.substring(fileName.lastIndexOf(".") + 1);
System.out.println("File extension: " + extension);
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Save As");
fileChooser.setInitialFileName(fileName + "." + extension); // Set the initial file name
// Set the default directory
File defaultDirectory = new File("C:\\Users\\Me\\Desktop\\Down test");
fileChooser.setInitialDirectory(defaultDirectory);
File selectedFile = fileChooser.showSaveDialog(this.downloadButton.getScene().getWindow());
if (selectedFile == null) {
System.out.println("Selection canceled");
} else {
String downloadPath = selectedFile.getAbsolutePath();
DownloadFile downloadFile = new DownloadFile(urlText, downloadPath, this.progressLabel);
Thread downloadThread = new Thread(downloadFile);
this.progressBar.progressProperty().unbind();
this.progressBar.progressProperty().bind(downloadFile.progressProperty());
downloadThread.start();
this.downloadUrl.clear();
downloadThread.join();
updateStatus(0,downloadFile.getStatus());
}
} catch (MalformedURLException e) {
// Handle invalid URL format
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Invalid URL!");
alert.setHeaderText("Please provide a valid URL!");
alert.show();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.collections.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<VBox alignment="CENTER" prefHeight="420.0" prefWidth="429.0" spacing="20.0" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.jj.HelloController">
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
<Label text="Enter the URL">
<font>
<Font size="16.0" />
</font></Label>
<BorderPane prefHeight="65.0" prefWidth="389.0">
<center>
<TextField fx:id="downloadUrl" prefWidth="379.0" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
<Button fx:id="downloadButton" text="Download" />
<StackPane prefHeight="57.0" prefWidth="389.0">
<children>
<ProgressBar fx:id="progressBar" prefWidth="200.0" progress="0.0" />
<Label fx:id="progressLabel" text="0%" />
</children>
</StackPane>
<Button mnemonicParsing="false" onAction="#btnn1" text="Button" />
<Button mnemonicParsing="false" onAction="#btnInsert" text="Insert URL" />
<HBox alignment="TOP_RIGHT" prefHeight="100.0" prefWidth="200.0">
<children>
<Button fx:id="DownloadAll" mnemonicParsing="false" onAction="#btnDownloadAll" text="Download All">
<HBox.margin>
<Insets right="110.0" />
</HBox.margin></Button>
<ChoiceBox value="1">
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:value="2" />
<String fx:value="3" />
<String fx:value="4" />
</FXCollections>
</items>
</ChoiceBox>
</children></HBox>
<TableView fx:id="table" prefHeight="200.0" prefWidth="200.0">
<columns>
<TableColumn fx:id="FileName" prefWidth="103.0" text="File Name" />
<TableColumn fx:id="Size" text="Size" />
<TableColumn fx:id="Status" prefWidth="76.0" text="Status" />
<TableColumn fx:id="Progress" prefWidth="129.0" text="progress" />
<TableColumn fx:id="Urltext" prefWidth="75.0" text="Column X" visible="false" />
</columns>
</TableView>
</VBox>
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.collections.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<VBox fx:id="mainVBox" alignment="CENTER" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.jj.HelloController">
<!-- <Button fx:id="openButton" text="Open Secondary Window" onAction="#btnn"/>-->
</VBox>
There are more classes that are not important.
So why did I face this problem? :
javafx.fxml.LoadException:
/C:/Users/Me/Desktop/jj/target/classes/com/example/jj/path-window.fxml
Yes it is possible to open FXML files in another stages.
Helper method:
How to use for a simple modal:
Additional information:
For more infos take a look at the according library at https://github.com/davidweber411/javafx-SimpleJavaFxApplicationBase.
To that, you can take a look at the documentation at https://wedasoft.com/projects/simple-java-fx-application-base/sjfxab-version-2-0-0/. You will find this functionality under "Dialog API > Individual FXML Dialogs".