From 340f3bef9232ae18ae68b795144a0841cde0ee47 Mon Sep 17 00:00:00 2001 From: Sean Phillips Date: Tue, 14 Oct 2025 10:23:18 -0400 Subject: [PATCH 1/4] tiny tweaks to correctly name FeatureCollections derived from imported CyberReport files. --- .../trinity/javafx/components/ExportMicroToolbar.java | 8 +++++++- .../javafx/handlers/FeatureVectorEventHandler.java | 2 +- src/main/java/edu/jhuapl/trinity/utils/ResourceUtils.java | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/jhuapl/trinity/javafx/components/ExportMicroToolbar.java b/src/main/java/edu/jhuapl/trinity/javafx/components/ExportMicroToolbar.java index dd5e8a52..571334b4 100644 --- a/src/main/java/edu/jhuapl/trinity/javafx/components/ExportMicroToolbar.java +++ b/src/main/java/edu/jhuapl/trinity/javafx/components/ExportMicroToolbar.java @@ -15,6 +15,7 @@ import javafx.geometry.Bounds; import javafx.geometry.Insets; import javafx.geometry.Pos; +import javafx.scene.Scene; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.SnapshotParameters; @@ -110,12 +111,14 @@ public class ExportMicroToolbar { private Border hoverBorder; private Border pinnedBorder; + File latestDirectory = new File("."); + public ExportMicroToolbar( Pane titleBarParent, Node chromeNode, Node contentNode, Node contextTarget, - javafx.scene.Scene scene, + Scene scene, double iconFitWidth ) { this.titleBarParent = Objects.requireNonNull(titleBarParent); @@ -474,9 +477,12 @@ private void saveSnapshotToFile() { FileChooser fc = new FileChooser(); fc.getExtensionFilters().add(new FileChooser.ExtensionFilter("PNG Image", "*.png")); fc.setInitialFileName("snapshot_content-" + exportScale + "x.png"); + fc.setInitialDirectory(latestDirectory); File f = fc.showSaveDialog(scene.getWindow()); if (f == null) return; try { + if(f.getParentFile().isDirectory()) + latestDirectory = f.getParentFile(); BufferedImage bi = SwingFXUtils.fromFXImage(wi, null); ImageIO.write(bi, "png", f); toast("Saved: " + f.getName()); diff --git a/src/main/java/edu/jhuapl/trinity/javafx/handlers/FeatureVectorEventHandler.java b/src/main/java/edu/jhuapl/trinity/javafx/handlers/FeatureVectorEventHandler.java index 73f62c15..6cb87dbd 100644 --- a/src/main/java/edu/jhuapl/trinity/javafx/handlers/FeatureVectorEventHandler.java +++ b/src/main/java/edu/jhuapl/trinity/javafx/handlers/FeatureVectorEventHandler.java @@ -140,7 +140,7 @@ public void handleCyberReport(FeatureVectorEvent event) { Platform.runLater(() -> { App.getAppScene().getRoot().fireEvent( new FeatureVectorEvent( - FeatureVectorEvent.NEW_FEATURE_COLLECTION, fc)); + FeatureVectorEvent.NEW_FEATURE_COLLECTION, fc, event.object2)); }); } diff --git a/src/main/java/edu/jhuapl/trinity/utils/ResourceUtils.java b/src/main/java/edu/jhuapl/trinity/utils/ResourceUtils.java index 075360d6..1625947d 100644 --- a/src/main/java/edu/jhuapl/trinity/utils/ResourceUtils.java +++ b/src/main/java/edu/jhuapl/trinity/utils/ResourceUtils.java @@ -545,7 +545,7 @@ protected Void call() throws Exception { //convert to Feature Vector Collection for the lulz FeatureCollection fc = DataUtils.convertCdcCsv(cdcCsvFile.cdcCsvList, true); Platform.runLater(() -> scene.getRoot().fireEvent( - new FeatureVectorEvent(FeatureVectorEvent.NEW_FEATURE_COLLECTION, fc))); + new FeatureVectorEvent(FeatureVectorEvent.NEW_FEATURE_COLLECTION, fc, file.getName()))); Trajectory trajectory = new Trajectory(file.getName()); trajectory.totalStates = fc.getFeatures().size(); Platform.runLater(() -> scene.getRoot().fireEvent( @@ -629,7 +629,7 @@ protected Void call() throws Exception { } else if (CyberReporterFile.isFileType(file)) { CyberReporterFile cyberReportFile = new CyberReporterFile(file.getAbsolutePath(), true); Platform.runLater(() -> scene.getRoot().fireEvent( - new FeatureVectorEvent(FeatureVectorEvent.NEW_CYBER_REPORT, cyberReportFile.cyberReports))); + new FeatureVectorEvent(FeatureVectorEvent.NEW_CYBER_REPORT, cyberReportFile.cyberReports, file.getName()))); } } catch (IOException ex) { LOG.error(null, ex); From afe58541f5e2cb94ae7b75fe797ff03ad88c9067 Mon Sep 17 00:00:00 2001 From: Sean Phillips Date: Mon, 20 Oct 2025 11:57:28 -0400 Subject: [PATCH 2/4] fixed concurrent modification exception when loading many cyber report files --- .../trinity/javafx/javafx3d/Hyperspace3DPane.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/jhuapl/trinity/javafx/javafx3d/Hyperspace3DPane.java b/src/main/java/edu/jhuapl/trinity/javafx/javafx3d/Hyperspace3DPane.java index 3d74ca3a..dd2f1431 100644 --- a/src/main/java/edu/jhuapl/trinity/javafx/javafx3d/Hyperspace3DPane.java +++ b/src/main/java/edu/jhuapl/trinity/javafx/javafx3d/Hyperspace3DPane.java @@ -1912,7 +1912,6 @@ protected Void call() throws Exception { if (end >= queueLimit) { start = end - queueLimit; } - featureCollection.getFeatures().subList(start, end) .stream().forEach(featureVector -> { //fail safe to gaurantee 3 dimensions @@ -1950,6 +1949,8 @@ protected Void call() throws Exception { } }; task.setOnFailed(e -> { + //@DEBUG SMP useful print + //System.out.println(task.getException().getMessage()); Platform.runLater(() -> { ProgressStatus ps = new ProgressStatus("Error Adding FeatureCollection.", -1); getScene().getRoot().fireEvent( @@ -1964,9 +1965,12 @@ protected Void call() throws Exception { } public void updateMaxAndMeans() { - meanVector = FeatureVector.getMeanVector(featureVectors); - maxAbsValue = FeatureVector.getMaxAbsValue(featureVectors); - meanCenteredMaxAbsValue = FeatureVector.getMeanCenteredMaxAbsValue(featureVectors, meanVector); + // Snapshot the list at call time to avoid ConcurrentModificationException + final List snapshot = List.copyOf(featureVectors); + if (snapshot.isEmpty()) return; + meanVector = FeatureVector.getMeanVector(snapshot); + maxAbsValue = FeatureVector.getMaxAbsValue(snapshot); + meanCenteredMaxAbsValue = FeatureVector.getMeanCenteredMaxAbsValue(snapshot, meanVector); String str = "Mean Centered MaxAbsValue: " + meanCenteredMaxAbsValue; cubeWorld.meanVector.clear(); From 9849997f17043bcd560ab737ca7f0717553263bd Mon Sep 17 00:00:00 2001 From: Sean Phillips Date: Mon, 20 Oct 2025 12:52:55 -0400 Subject: [PATCH 3/4] Prevent Projections view labels from changing (they are and must be generic always) --- .../edu/jhuapl/trinity/AppAsyncManager.java | 6 ++++-- .../javafx/javafx3d/Projections3DPane.java | 20 ++++++++++++------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/main/java/edu/jhuapl/trinity/AppAsyncManager.java b/src/main/java/edu/jhuapl/trinity/AppAsyncManager.java index fac6e7ad..f617912a 100644 --- a/src/main/java/edu/jhuapl/trinity/AppAsyncManager.java +++ b/src/main/java/edu/jhuapl/trinity/AppAsyncManager.java @@ -943,7 +943,8 @@ else if (null != projections3DPane.latestUmap) } if (null != originalFC.getDimensionLabels()) { projectedFC.setDimensionLabels(originalFC.getDimensionLabels()); - projections3DPane.setDimensionLabels(originalFC.getDimensionLabels()); + //@SMP Projections are of a lower embedding and so labels are not meaningfl + //projections3DPane.setDimensionLabels(originalFC.getDimensionLabels()); } projections3DPane.setHyperDimensionFeatures(originalFC); projections3DPane.addFeatureCollection(projectedFC, false); @@ -964,7 +965,8 @@ else if (null != projections3DPane.latestUmap) } if (null != originalFC.getDimensionLabels()) { projectedFC.setDimensionLabels(originalFC.getDimensionLabels()); - projections3DPane.setDimensionLabels(originalFC.getDimensionLabels()); + //@SMP Projections are of a lower embedding and so labels are not meaningfl + //projections3DPane.setDimensionLabels(originalFC.getDimensionLabels()); } projections3DPane.setHyperDimensionFeatures(originalFC); projections3DPane.addFeatureCollection(projectedFC, false); diff --git a/src/main/java/edu/jhuapl/trinity/javafx/javafx3d/Projections3DPane.java b/src/main/java/edu/jhuapl/trinity/javafx/javafx3d/Projections3DPane.java index d80b6b5a..cc9b36da 100644 --- a/src/main/java/edu/jhuapl/trinity/javafx/javafx3d/Projections3DPane.java +++ b/src/main/java/edu/jhuapl/trinity/javafx/javafx3d/Projections3DPane.java @@ -1578,9 +1578,11 @@ private void updateDataColors() { sphereToFeatureVectorMap.forEach((s, fv) -> { if (null != fv.getLabel()) { FactorLabel fl = FactorLabel.getFactorLabel(fv.getLabel()); - s.setVisible(fl.getVisible()); - ((PhongMaterial) s.getMaterial()).setDiffuseColor(fl.getColor()); - ((PhongMaterial) s.getMaterial()).setSpecularColor(fl.getColor()); + if(null != fl) { + s.setVisible(fl.getVisible()); + ((PhongMaterial) s.getMaterial()).setDiffuseColor(fl.getColor()); + ((PhongMaterial) s.getMaterial()).setSpecularColor(fl.getColor()); + } } }); } @@ -2609,7 +2611,8 @@ public Group getManifoldViews() { @Override public void setDimensionLabels(List labelStrings) { - featureLabels = labelStrings; + //featureLabels = labelStrings; + //need to override... projections should not have specific labels. } public void setHyperDimensionFeatures(FeatureCollection originalFC) { @@ -2624,7 +2627,8 @@ public void projectFeatureCollection(FeatureCollection originalFC, PCAConfig con setHyperDimensionFeatures(originalFC); fc = (FeatureCollection) task.get(); if (null != originalFC.getDimensionLabels()) { - setDimensionLabels(originalFC.getDimensionLabels()); + //@SMP Projections are of a lower embedding and so labels are not meaningfl + //setDimensionLabels(originalFC.getDimensionLabels()); fc.setDimensionLabels(originalFC.getDimensionLabels()); } addFeatureCollection(fc, false); @@ -2742,7 +2746,8 @@ public void projectFeatureCollection(FeatureCollection originalFC, setHyperDimensionFeatures(originalFC); fc = (FeatureCollection) task.get(); if (null != originalFC.getDimensionLabels()) { - setDimensionLabels(originalFC.getDimensionLabels()); + //@SMP Projections are of a lower embedding and so labels are not meaningfl + //setDimensionLabels(originalFC.getDimensionLabels()); fc.setDimensionLabels(originalFC.getDimensionLabels()); } addFeatureCollection(fc, false); @@ -2765,7 +2770,8 @@ public void projectFeatureCollection(FeatureCollection originalFC, Umap umap) { setHyperDimensionFeatures(originalFC); fc = (FeatureCollection) task.get(); if (null != originalFC.getDimensionLabels()) { - setDimensionLabels(originalFC.getDimensionLabels()); + //@SMP Projections are of a lower embedding and so labels are not meaningfl + //setDimensionLabels(originalFC.getDimensionLabels()); fc.setDimensionLabels(originalFC.getDimensionLabels()); } addFeatureCollection(fc, false); From 198fab1192f668d8ae6e46f1858852cea95ee454 Mon Sep 17 00:00:00 2001 From: samypr100 <3933065+samypr100@users.noreply.github.com> Date: Mon, 20 Oct 2025 18:25:21 -0400 Subject: [PATCH 4/4] chore: fmt --- .../jhuapl/trinity/javafx/components/ExportMicroToolbar.java | 2 +- .../edu/jhuapl/trinity/javafx/javafx3d/Hyperspace3DPane.java | 2 +- .../edu/jhuapl/trinity/javafx/javafx3d/Projections3DPane.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/jhuapl/trinity/javafx/components/ExportMicroToolbar.java b/src/main/java/edu/jhuapl/trinity/javafx/components/ExportMicroToolbar.java index 571334b4..cb62f47f 100644 --- a/src/main/java/edu/jhuapl/trinity/javafx/components/ExportMicroToolbar.java +++ b/src/main/java/edu/jhuapl/trinity/javafx/components/ExportMicroToolbar.java @@ -481,7 +481,7 @@ private void saveSnapshotToFile() { File f = fc.showSaveDialog(scene.getWindow()); if (f == null) return; try { - if(f.getParentFile().isDirectory()) + if (f.getParentFile().isDirectory()) latestDirectory = f.getParentFile(); BufferedImage bi = SwingFXUtils.fromFXImage(wi, null); ImageIO.write(bi, "png", f); diff --git a/src/main/java/edu/jhuapl/trinity/javafx/javafx3d/Hyperspace3DPane.java b/src/main/java/edu/jhuapl/trinity/javafx/javafx3d/Hyperspace3DPane.java index dd2f1431..385de331 100644 --- a/src/main/java/edu/jhuapl/trinity/javafx/javafx3d/Hyperspace3DPane.java +++ b/src/main/java/edu/jhuapl/trinity/javafx/javafx3d/Hyperspace3DPane.java @@ -1965,7 +1965,7 @@ protected Void call() throws Exception { } public void updateMaxAndMeans() { - // Snapshot the list at call time to avoid ConcurrentModificationException + // Snapshot the list at call time to avoid ConcurrentModificationException final List snapshot = List.copyOf(featureVectors); if (snapshot.isEmpty()) return; meanVector = FeatureVector.getMeanVector(snapshot); diff --git a/src/main/java/edu/jhuapl/trinity/javafx/javafx3d/Projections3DPane.java b/src/main/java/edu/jhuapl/trinity/javafx/javafx3d/Projections3DPane.java index cc9b36da..95bcf43e 100644 --- a/src/main/java/edu/jhuapl/trinity/javafx/javafx3d/Projections3DPane.java +++ b/src/main/java/edu/jhuapl/trinity/javafx/javafx3d/Projections3DPane.java @@ -1578,7 +1578,7 @@ private void updateDataColors() { sphereToFeatureVectorMap.forEach((s, fv) -> { if (null != fv.getLabel()) { FactorLabel fl = FactorLabel.getFactorLabel(fv.getLabel()); - if(null != fl) { + if (null != fl) { s.setVisible(fl.getVisible()); ((PhongMaterial) s.getMaterial()).setDiffuseColor(fl.getColor()); ((PhongMaterial) s.getMaterial()).setSpecularColor(fl.getColor());