在javafx中是否可以使用按钮从另一个fxml打开新阶段(窗口)?感谢您的回答。
bcs 它向我显示了这个错误:
javafx.fxml.LoadException: /C:/Users/Me/Desktop/jj/target/classes/com/example/jj/path-window.fxml
这是我的代码:
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>
还有更多不重要的课程
那么为什么我会遇到这个问题:
javafx.fxml.LoadException: /C:/Users/Me/Desktop/jj/target/classes/com/example/jj/path-window.fxml
是的,可以在其他阶段打开 FXML 文件。
辅助方法:
/**
* Creates a fxml dialog.
*
* @param title The dialog title.
* @param dialogIsModal Dialog is modal or not.
* @param dialogIsResizeable Dialog is resizeable or not.
* @param absoluteFxmlFileUrl The absolut URL of the new fxml file.
* @param sceneSize The scene size.
* @param initMethodOfController A method of the new controller which shall be executed if everything is ready.
* @param callbackOnDialogClose A callback which shall be executed when the dialog closes.
* @return The stage of the created dialog.
* @throws IOException On error.
*/
public static Stage createFxmlDialog(
String title,
boolean dialogIsModal,
boolean dialogIsResizeable,
URL absoluteFxmlFileUrl,
Dimension2D sceneSize,
@SuppressWarnings("rawtypes") Consumer initMethodOfController,
Runnable callbackOnDialogClose)
throws IOException {
FXMLLoader loader = new FXMLLoader(absoluteFxmlFileUrl);
Parent root = loader.load(); // this calls the constructor and after that initialize from jfx()
Object viewController = loader.getController();
Scene scene = sceneSize == null ? new Scene(root) : new Scene(root, sceneSize.getWidth(), sceneSize.getHeight());
Stage stage = new Stage();
stage.setTitle(title);
stage.initModality(dialogIsModal ? Modality.APPLICATION_MODAL : Modality.NONE);
stage.setResizable(dialogIsResizeable);
stage.setScene(scene);
stage.setOnHidden(event -> {
event.consume();
if (callbackOnDialogClose != null) {
callbackOnDialogClose.run();
}
stage.close();
});
if (initMethodOfController != null) {
//noinspection unchecked
initMethodOfController.accept(viewController);
}
return stage;
}
使用方法:
createFxmlDialog(
"My Dialog",
true,
false,
getClass().getResource("/absolute/path/to/scene1.fxml"),
null,
null,
null).showAndWait();