Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException
Сделал приложение для анализа места на диске по обучающему видео. Которое позволяет выбрать нужную папку, и посмотреть данные в ней в виде диаграммы. Все хорошо работало, но после добавление кнопки для возращения в предыдущую директорию, стало выводить - Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException
. Как исправить данную ошибку?
фрагмент после добавления которого стало выходить исключение:
BorderPane pane = new BorderPane();
pane.setTop(button);
pane.setCenter(pieChart);
class Analyzer:
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map;
public class Analyzer {
private HashMap<String, Long> sizes;
public Map<String, Long> calculateDirectorySize(Path path) {
try {
sizes = new HashMap<>();
Files.walkFileTree(
path,
new SimpleFileVisitor<>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
long size = Files.size(file);
updateDirSize(file, size);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
return FileVisitResult.SKIP_SUBTREE;
}
}
);
return sizes;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void updateDirSize(Path file, Long size) {
String key = file.toString();
sizes.put(key, size + sizes.getOrDefault(key, 0L));
Path parent = file.getParent();
if (parent != null) {
updateDirSize(parent, size);
}
}
}
class Starter:
import DiskAnylizer.ApplicationLogic.Analyzer;
import javafx.application.Application;
import javafx.beans.Observable;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;
import java.io.File;
import java.nio.file.Path;
import java.util.Map;
import java.util.stream.Collectors;
public class Starter extends Application {
private Stage stage;
private Map<String, Long> sizes;
private ObservableList<PieChart.Data> pieChartDate = FXCollections.observableArrayList();
private PieChart pieChart;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
this.stage = stage;
stage.setTitle("Disk Analyzer");
Button button = new Button("Choose directory");
button.setOnAction(event -> {
File file = new DirectoryChooser().showDialog(stage);
String absolutePath = file.getAbsolutePath();
sizes = new Analyzer().calculateDirectorySize(Path.of(absolutePath));
buildChart(absolutePath);
});
StackPane pane = new StackPane();
pane.getChildren().add(button);
stage.setScene(new Scene(pane, 300, 250));
stage.show();
}
private void buildChart(String absolutePath) {
pieChart = new PieChart(pieChartDate);
refillChart(absolutePath);
Button button = new Button(absolutePath);
button.setOnAction(event -> refillChart(absolutePath));
BorderPane pane = new BorderPane();
pane.setTop(button);
pane.setCenter(pieChart);
stage.setScene(new Scene(pieChart, 900, 600));
stage.show();
}
private void refillChart(String absolutePath) {
pieChartDate.clear();
pieChartDate.addAll(
sizes.entrySet()
.parallelStream()
.filter(entry -> {
Path parent = Path.of(entry.getKey()).getParent();
return parent != null && parent.toString().equals(absolutePath);
})
.map(entry -> new PieChart.Data(entry.getKey(), entry.getValue()))
.collect(Collectors.toList())
);
pieChart.getData().forEach(data -> {
data
.getNode()
.addEventHandler(
MouseEvent.MOUSE_PRESSED,
event -> refillChart(data.getName())
);
});
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>Desktop-disk-analyzer</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<configuration>
<mainClass>DiskAnylizer.Starter</mainClass>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>20</version>
</dependency>
</dependencies>
</project>
stack trace:
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------< org.example:Desktop-disk-analyzer >------------------
[INFO] Building Desktop-disk-analyzer 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] >>> javafx-maven-plugin:0.0.8:run (default-cli) > process-classes @ Desktop-disk-analyzer >>>
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ Desktop-disk-analyzer ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ Desktop-disk-analyzer ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] <<< javafx-maven-plugin:0.0.8:run (default-cli) < process-classes @ Desktop-disk-analyzer <<<
[INFO]
[INFO]
[INFO] --- javafx-maven-plugin:0.0.8:run (default-cli) @ Desktop-disk-analyzer ---
Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: PieChart@5dda5c5e[styleClass=chart]is already inside a scene-graph and cannot be set as root
at javafx.graphics@20/javafx.scene.Scene$8.invalidated(Scene.java:1224)
at javafx.base@20/javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.base@20/javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:147)
at javafx.graphics@20/javafx.scene.Scene.setRoot(Scene.java:1196)
at javafx.graphics@20/javafx.scene.Scene.<init>(Scene.java:360)
at javafx.graphics@20/javafx.scene.Scene.<init>(Scene.java:240)
at DiskAnylizer.Starter.buildChart(Starter.java:66)
at DiskAnylizer.Starter.lambda$start$0(Starter.java:41)
at javafx.base@20/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at javafx.base@20/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:232)
at javafx.base@20/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:189)
at javafx.base@20/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base@20/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base@20/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base@20/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base@20/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base@20/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base@20/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base@20/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base@20/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.base@20/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics@20/javafx.scene.Node.fireEvent(Node.java:8944)
at javafx.controls@20/javafx.scene.control.Button.fire(Button.java:203)
at javafx.controls@20/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:207)
at javafx.controls@20/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
at javafx.base@20/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
at javafx.base@20/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at javafx.base@20/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:232)
at javafx.base@20/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:189)
at javafx.base@20/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base@20/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base@20/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base@20/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base@20/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base@20/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base@20/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base@20/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base@20/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.base@20/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics@20/javafx.scene.Scene$MouseHandler.process(Scene.java:3980)
at javafx.graphics@20/javafx.scene.Scene.processMouseEvent(Scene.java:1890)
at javafx.graphics@20/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2704)
at javafx.graphics@20/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
at javafx.graphics@20/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at javafx.graphics@20/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
at javafx.graphics@20/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
at javafx.graphics@20/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
at javafx.graphics@20/com.sun.glass.ui.View.handleMouseEvent(View.java:551)
at javafx.graphics@20/com.sun.glass.ui.View.notifyMouse(View.java:937)
at javafx.graphics@20/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics@20/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:185)
at java.base/java.lang.Thread.run(Thread.java:833)
Источник: Stack Overflow на русском