我已成功在同一窗格上绘制两个图表(条形图和折线图)。
我正在尝试实现一个保存按钮,单击该按钮时,会将生成的图像(带轴)写入我保存的选择的 bmp 图像中。
代码运行,我收到肯定的警报,并创建了一个图像文件。然而,生成的图像文件是空的(0 字节)。
@FXML // fx:id="graph"
private Pane graph; // Value injected by FXMLLoader
@FXML // fx:id="saveButton"
private Button saveButton; // Value injected by FXMLLoader
// ...
@FXML
void clickSave(ActionEvent event) {
Stage yourStage = (Stage) saveButton.getScene().getWindow();
FileChooser fileChooser = new FileChooser();
fileChooser.setInitialDirectory(new File("Path\\With\\Spaces"));
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("BMP Files", "*.bmp"));
// Show save dialog
File file = fileChooser.showSaveDialog(yourStage);
if (file != null) {
if (!file.exists()) {
try {
Files.createFile(file.toPath());
} catch (IOException e) {
e.printStackTrace(); // Handle the exception
}
}
WritableImage writableImage = graph.snapshot(new SnapshotParameters(), null);
BufferedImage bufferedImage = SwingFXUtils.fromFXImage(writableImage, null);
try {
ImageIO.write(bufferedImage, "BMP", file);
// Inform the user about the successful save
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("File Saved");
alert.setHeaderText(null);
alert.setContentText("The file has been saved successfully.");
alert.showAndWait();
} catch (IOException e) {
e.printStackTrace();
// Inform the user about the error
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText(null);
alert.setContentText("An error occurred while saving the file.");
alert.showAndWait();
}
}
}
编辑: 按照@James_D的评论建议,我将代码更改为以下内容,但问题仍然存在。
@FXML
void clickSave(ActionEvent event) {
Stage stage = (Stage) saveButton.getScene().getWindow();
FileChooser fileChooser = new FileChooser();
fileChooser.setInitialDirectory(new File("Path\\With\\Spaces"));
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("BMP Files", "*.bmp"));
// Show save dialog
File file = fileChooser.showSaveDialog(stage);
if (file != null) {
WritableImage writableImage = graph.snapshot(new SnapshotParameters(), null);
BufferedImage bufferedImage = SwingFXUtils.fromFXImage(writableImage, null);
try {
ImageIO.write(bufferedImage, "BMP", file);
if (!file.exists()) {
Files.createFile(file.toPath());
}
// Inform the user about the successful save
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("File Saved");
alert.setHeaderText(null);
alert.setContentText("The file has been saved successfully.");
alert.showAndWait();
} catch (IOException e) {
e.printStackTrace();
// Inform the user about the error
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText(null);
alert.setContentText("An error occurred while saving the file.");
alert.showAndWait();
}
}
}
非常感谢@Slaw 和这个答案。
SwingFXUtils 函数返回
TYPE_INT_ARGB_PRE
类型的图像。只有 TYPE_INT_RGB
类型的图像才能写入 .bmp 文件,否则 ImageIO.write(bufferedImage, "BMP", file);
返回 false
。因此,必须进行从 TYPE_INT_ARGB_PRE
到 TYPE_INT_RGB
的适当转换。下面的块显示了更新后的感兴趣的代码,其中现在包括转换。
WritableImage writableImage = graph.snapshot(new SnapshotParameters(), null);
BufferedImage preBufferedImage = SwingFXUtils.fromFXImage(writableImage, null);
BufferedImage bufferedImage = new BufferedImage(
preBufferedImage.getWidth(),
preBufferedImage.getHeight(),
BufferedImage.TYPE_INT_RGB
);
bufferedImage.createGraphics().drawImage(
preBufferedImage,
0,
0,
java.awt.Color.WHITE,
null
);
try {
Boolean __ = ImageIO.write(bufferedImage, "BMP", file);
if (!file.exists()) {
Files.createFile(file.toPath());
}
...
}