diff --git a/Core/src/org/sleuthkit/autopsy/images/Throbber_allbackgrounds_cyanblue.gif b/Core/src/org/sleuthkit/autopsy/images/working_spinner.gif similarity index 100% rename from Core/src/org/sleuthkit/autopsy/images/Throbber_allbackgrounds_cyanblue.gif rename to Core/src/org/sleuthkit/autopsy/images/working_spinner.gif diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableTile.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableTile.java index 42c6a9b9eb..ef468d7172 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableTile.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableTile.java @@ -20,13 +20,14 @@ package org.sleuthkit.autopsy.imagegallery.gui.drawableviews; import java.lang.ref.SoftReference; import java.util.Objects; +import static java.util.Objects.isNull; +import static java.util.Objects.nonNull; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javafx.application.Platform; import javafx.concurrent.Task; import javafx.fxml.FXML; import javafx.scene.CacheHint; -import javafx.scene.Node; import javafx.scene.control.Control; import javafx.scene.control.ProgressIndicator; import javafx.scene.effect.DropShadow; @@ -61,7 +62,7 @@ public class DrawableTile extends DrawableTileBase { private ImageView imageView; private Task task; - private SoftReference thumbCache; + private SoftReference thumbnailCache; @Override synchronized protected void disposeContent() { @@ -69,7 +70,7 @@ public class DrawableTile extends DrawableTileBase { task.cancel(true); } task = null; - thumbCache = null; + thumbnailCache = null; } @FXML @@ -117,11 +118,66 @@ public class DrawableTile extends DrawableTileBase { @Override synchronized protected void updateContent() { - Node thumbnail = getThumbnail(); - Platform.runLater(() -> { - imageBorder.setCenter(thumbnail); - }); + if (getFile().isPresent() == false) { + thumbnailCache = null; + Platform.runLater(() -> { + imageView.setImage(null); + imageBorder.setCenter(null); + }); + } else { + Image thumbnail = isNull(thumbnailCache) ? null : thumbnailCache.get(); + if (nonNull(thumbnail)) { + setImageHelper(thumbnail); + } else if (isNull(task) || task.isDone()) { + DrawableFile file = getFile().get(); + task = new Task() { + @Override + protected Image call() throws Exception { + if (isCancelled() == false) { + return file.getThumbnail(); + } else { + return null; + } + } + + @Override + protected void failed() { + super.failed(); + } + + @Override + protected void succeeded() { + super.succeeded(); + if (isCancelled() == false) { + try { + synchronized (DrawableTile.this) { + final Image thumbnail = get(); + thumbnailCache = new SoftReference<>(thumbnail); + setImageHelper(thumbnailCache.get()); + } + } catch (InterruptedException | ExecutionException ex) { + LOGGER.log(Level.WARNING, "failed to get thumbnail for" + file.getName(), ex); + } + } + synchronized (DrawableTile.this) { + task = null; + } + } + }; + Platform.runLater(() -> { + imageBorder.setCenter(new ProgressIndicator()); + }); + new Thread(task).start(); + } + } + } + + private void setImageHelper(final Image t) { + Platform.runLater(() -> { + imageView.setImage(t); + imageBorder.setCenter(imageView); + }); } @Override @@ -129,59 +185,4 @@ public class DrawableTile extends DrawableTileBase { return getFile().map(AbstractContent::getName).orElse(""); } - synchronized private Node getThumbnail() { - if (getFile().isPresent() == false) { - return null; - } else { - Image thumbnail = (thumbCache == null) - ? null : thumbCache.get(); - - if (thumbnail != null) { - Platform.runLater(() -> { - imageView.setImage(thumbnail); - }); - return imageView; - } else { - if (task == null || task.isDone()) { - DrawableFile file = getFile().get(); - task = new Task() { - @Override - protected Image call() throws Exception { - if (isCancelled() == false) { - return file.getThumbnail(); - } else { - return null; - } - } - - @Override - protected void failed() { - super.failed(); - } - - @Override - protected void succeeded() { - super.succeeded(); - if (isCancelled() == false) { - try { - synchronized (DrawableTile.this) { - thumbCache = new SoftReference<>(get()); - } - updateContent(); - - } catch (InterruptedException | ExecutionException ex) { - LOGGER.log(Level.WARNING, "failed to get thumbnail for" + file.getName(), ex); - } - } - synchronized (DrawableTile.this) { - task = null; - } - } - }; - new Thread(task).start(); - } - return new ProgressIndicator(); - } - } - } } diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableUIBase.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableUIBase.java index 267632ed85..ae5ad9d05b 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableUIBase.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableUIBase.java @@ -19,7 +19,6 @@ package org.sleuthkit.autopsy.imagegallery.gui.drawableviews; import java.util.Objects; -import static java.util.Objects.nonNull; import java.util.Optional; import java.util.logging.Level; import javafx.scene.layout.AnchorPane; @@ -86,9 +85,11 @@ abstract public class DrawableUIBase extends AnchorPane implements DrawableView synchronized public void setFile(Long newFileID) { if (getFileID().isPresent()) { if (Objects.equals(newFileID, getFileID().get()) == false) { - setFileHelper(newFileID); + if (Objects.nonNull(newFileID)) { + setFileHelper(newFileID); + } } - } else if (nonNull(newFileID)) { + } else if (Objects.nonNull(newFileID)) { setFileHelper(newFileID); } } diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/GroupPane.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/GroupPane.java index c33793ce4d..6e72f1c731 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/GroupPane.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/GroupPane.java @@ -219,7 +219,7 @@ public class GroupPane extends BorderPane { private final InvalidationListener filesSyncListener = (observable) -> { final String header = getHeaderString(); - final List fileIds = getGrouping().fileIds(); + final List fileIds = getGroup().fileIds(); Platform.runLater(() -> { slideShowToggle.setDisable(fileIds.isEmpty()); gridView.getItems().setAll(fileIds); @@ -245,8 +245,8 @@ public class GroupPane extends BorderPane { } //assign last selected file or if none first file in group - if (slideShowFileID == null || getGrouping().fileIds().contains(slideShowFileID) == false) { - slideShowPane.setFile(getGrouping().fileIds().get(0)); + if (slideShowFileID == null || getGroup().fileIds().contains(slideShowFileID) == false) { + slideShowPane.setFile(getGroup().fileIds().get(0)); } else { slideShowPane.setFile(slideShowFileID); } @@ -267,7 +267,7 @@ public class GroupPane extends BorderPane { this.scrollToFileID(globalSelectionModel.lastSelectedProperty().get()); } - public DrawableGroup getGrouping() { + public DrawableGroup getGroup() { return grouping.get(); } @@ -276,7 +276,7 @@ public class GroupPane extends BorderPane { menuItem.setOnAction(new EventHandler() { @Override public void handle(ActionEvent t) { - Set fileIdSet = new HashSet<>(getGrouping().fileIds()); + Set fileIdSet = new HashSet<>(getGroup().fileIds()); new CategorizeAction(controller).addTagsToFiles(controller.getTagsManager().getTagName(cat), "", fileIdSet); grpCatSplitMenu.setText(cat.getDisplayName()); @@ -291,7 +291,7 @@ public class GroupPane extends BorderPane { menuItem.setOnAction(new EventHandler() { @Override public void handle(ActionEvent t) { - Set fileIdSet = new HashSet<>(getGrouping().fileIds()); + Set fileIdSet = new HashSet<>(getGroup().fileIds()); new AddDrawableTagAction(controller).addTagsToFiles(tn, "", fileIdSet); grpTagSplitMenu.setText(tn.getDisplayName()); @@ -302,14 +302,14 @@ public class GroupPane extends BorderPane { } private void selectAllFiles() { - globalSelectionModel.clearAndSelectAll(getGrouping().fileIds()); + globalSelectionModel.clearAndSelectAll(getGroup().fileIds()); } /** create the string to display in the group header */ protected String getHeaderString() { - return isNull(getGrouping()) ? "" - : StringUtils.defaultIfBlank(getGrouping().getGroupByValueDislpayName(), DrawableGroup.getBlankGroupName()) + " -- " - + getGrouping().getHashSetHitsCount() + " hash set hits / " + getGrouping().getSize() + " files"; + return isNull(getGroup()) ? "" + : StringUtils.defaultIfBlank(getGroup().getGroupByValueDislpayName(), DrawableGroup.getBlankGroupName()) + " -- " + + getGroup().getHashSetHitsCount() + " hash set hits / " + getGroup().getSize() + " files"; } ContextMenu getContextMenu() { @@ -579,11 +579,11 @@ public class GroupPane extends BorderPane { * @param grouping the new grouping assigned to this group */ void setViewState(GroupViewState viewState) { - if (nonNull(getGrouping())) { - getGrouping().fileIds().removeListener(filesSyncListener); - } if (isNull(viewState) || isNull(viewState.getGroup())) { + if (nonNull(getGroup())) { + getGroup().fileIds().removeListener(filesSyncListener); + } this.grouping.set(null); Platform.runLater(() -> { @@ -599,15 +599,18 @@ public class GroupPane extends BorderPane { }); } else { - if (this.grouping.get() != viewState.getGroup()) { + if (getGroup() != viewState.getGroup()) { + if (nonNull(getGroup())) { + getGroup().fileIds().removeListener(filesSyncListener); + } this.grouping.set(viewState.getGroup()); - this.getGrouping().fileIds().addListener(filesSyncListener); + getGroup().fileIds().addListener(filesSyncListener); final String header = getHeaderString(); - gridView.getItems().setAll(getGrouping().fileIds()); Platform.runLater(() -> { + gridView.getItems().setAll(getGroup().fileIds()); slideShowToggle.setDisable(gridView.getItems().isEmpty()); groupLabel.setText(header); resetScrollBar(); @@ -686,6 +689,7 @@ public class GroupPane extends BorderPane { @Override protected void updateItem(Long item, boolean empty) { super.updateItem(item, empty); + tile.setFile(item); } diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/SlideShowView.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/SlideShowView.java index 40d6124df8..7e5737637c 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/SlideShowView.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/SlideShowView.java @@ -195,8 +195,8 @@ public class SlideShowView extends DrawableTileBase { getGroupPane().grouping().addListener((Observable observable) -> { syncButtonVisibility(); - if (getGroupPane().getGrouping() != null) { - getGroupPane().getGrouping().fileIds().addListener((Observable observable1) -> { + if (getGroupPane().getGroup() != null) { + getGroupPane().getGroup().fileIds().addListener((Observable observable1) -> { syncButtonVisibility(); }); } @@ -206,7 +206,7 @@ public class SlideShowView extends DrawableTileBase { @ThreadConfined(type = ThreadType.ANY) private void syncButtonVisibility() { try { - final boolean hasMultipleFiles = getGroupPane().getGrouping().fileIds().size() > 1; + final boolean hasMultipleFiles = getGroupPane().getGroup().fileIds().size() > 1; Platform.runLater(() -> { rightButton.setVisible(hasMultipleFiles); leftButton.setVisible(hasMultipleFiles); @@ -288,12 +288,12 @@ public class SlideShowView extends DrawableTileBase { @ThreadConfined(type = ThreadType.JFX) synchronized private void cycleSlideShowImage(int direction) { stopVideo(); - final int groupSize = getGroupPane().getGrouping().fileIds().size(); + final int groupSize = getGroupPane().getGroup().fileIds().size(); final Integer nextIndex = getFileID().map(fileID -> { - final int currentIndex = getGroupPane().getGrouping().fileIds().indexOf(fileID); + final int currentIndex = getGroupPane().getGroup().fileIds().indexOf(fileID); return (currentIndex + direction + groupSize) % groupSize; }).orElse(0); - setFile(getGroupPane().getGrouping().fileIds().get(nextIndex) + setFile(getGroupPane().getGroup().fileIds().get(nextIndex) ); } @@ -302,7 +302,7 @@ public class SlideShowView extends DrawableTileBase { * of y" */ private String getSupplementalText() { - final ObservableList fileIds = getGroupPane().getGrouping().fileIds(); + final ObservableList fileIds = getGroupPane().getGroup().fileIds(); return getFileID().map(fileID -> " ( " + (fileIds.indexOf(fileID) + 1) + " of " + fileIds.size() + " in group )") .orElse("");