From 11fee59984d0242f86c6d5141e446720c9d47cfc Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 19 Jan 2021 18:08:18 -0500 Subject: [PATCH] 7229 modifications to redirect focus when a tab is selected --- .../discovery/search/DiscoveryEventUtils.java | 41 ++++++++++++++++--- .../autopsy/discovery/ui/ArtifactsWorker.java | 15 ++++--- .../discovery/ui/DomainArtifactsTabPanel.java | 11 +++++ .../discovery/ui/DomainDetailsPanel.java | 30 ++++++++++---- .../discovery/ui/MiniTimelinePanel.java | 13 +++++- .../discovery/ui/MiniTimelineWorker.java | 17 +++++--- 6 files changed, 102 insertions(+), 25 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryEventUtils.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryEventUtils.java index e228ce5f21..919c84f8ec 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryEventUtils.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryEventUtils.java @@ -135,6 +135,9 @@ public final class DiscoveryEventUtils { /** * Construct a new PopulateDomainTabsEvent. + * + * @param domain The domain this event is for, or empty if no domain is + * selected. */ public PopulateDomainTabsEvent(String domain) { this.domain = domain; @@ -236,6 +239,7 @@ public final class DiscoveryEventUtils { private final List listOfArtifacts = new ArrayList<>(); private final BlackboardArtifact.ARTIFACT_TYPE artifactType; + private final boolean grabFocus; /** * Construct a new ArtifactSearchResultEvent with a list of specified @@ -243,12 +247,15 @@ public final class DiscoveryEventUtils { * * @param artifactType The type of results in the list. * @param listOfArtifacts The list of results retrieved. + * @param shouldGrabFocus True if the list of artifacts should have + * focus, false otherwise. */ - public ArtifactSearchResultEvent(BlackboardArtifact.ARTIFACT_TYPE artifactType, List listOfArtifacts) { + public ArtifactSearchResultEvent(BlackboardArtifact.ARTIFACT_TYPE artifactType, List listOfArtifacts, boolean shouldGrabFocus) { if (listOfArtifacts != null) { this.listOfArtifacts.addAll(listOfArtifacts); } this.artifactType = artifactType; + this.grabFocus = shouldGrabFocus; } /** @@ -268,6 +275,17 @@ public final class DiscoveryEventUtils { public BlackboardArtifact.ARTIFACT_TYPE getArtifactType() { return artifactType; } + + /** + * Get whether or not the artifacts list should grab focus. + * + * @return True if the list of artifacts should have focus, false + * otherwise. + */ + public boolean shouldGrabFocus() { + return grabFocus; + } + } /** @@ -278,18 +296,22 @@ public final class DiscoveryEventUtils { private final List results = new ArrayList<>(); private final String domain; + private final boolean grabFocus; /** * Construct a new MiniTimelineResultEvent. * - * @param results The list of MiniTimelineResults contained in this - * event. - * @param domain The domain the results are for. + * @param results The list of MiniTimelineResults contained in + * this event. + * @param domain The domain the results are for. + * @param shouldGrabFocus True if the list of dates should have focus, + * false otherwise. */ - public MiniTimelineResultEvent(List results, String domain) { + public MiniTimelineResultEvent(List results, String domain, boolean shouldGrabFocus) { if (results != null) { this.results.addAll(results); } + this.grabFocus = shouldGrabFocus; this.domain = domain; } @@ -310,6 +332,15 @@ public final class DiscoveryEventUtils { public String getDomain() { return domain; } + + /** + * Get whether or not the dates list should grab focus. + * + * @return True if the list of dates should have focus, false otherwise. + */ + public boolean shouldGrabFocus() { + return grabFocus; + } } /** diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactsWorker.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactsWorker.java index 1202f20647..8226776cd7 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactsWorker.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactsWorker.java @@ -41,16 +41,21 @@ class ArtifactsWorker extends SwingWorker, Void> { private final BlackboardArtifact.ARTIFACT_TYPE artifactType; private final static Logger logger = Logger.getLogger(ArtifactsWorker.class.getName()); private final String domain; + private final boolean grabFocus; /** * Construct a new ArtifactsWorker. * - * @param artifactType The type of artifact being retrieved. - * @param domain The domain the artifacts should have as an attribute. + * @param artifactType The type of artifact being retrieved. + * @param domain The domain the artifacts should have as an + * attribute. + * @param shouldGrabFocus True if the list of artifacts should have focus, + * false otherwise. */ - ArtifactsWorker(BlackboardArtifact.ARTIFACT_TYPE artifactType, String domain) { + ArtifactsWorker(BlackboardArtifact.ARTIFACT_TYPE artifactType, String domain, boolean shouldGrabFocus) { this.artifactType = artifactType; this.domain = domain; + this.grabFocus = shouldGrabFocus; } @Override @@ -61,7 +66,7 @@ class ArtifactsWorker extends SwingWorker, Void> { return domainSearch.getArtifacts(new DomainSearchArtifactsRequest(Case.getCurrentCase().getSleuthkitCase(), domain, artifactType)); } catch (DiscoveryException ex) { if (ex.getCause() instanceof InterruptedException) { - this.cancel(true); + this.cancel(true); //ignore the exception as it was cancelled while the cache was performing its get and we support cancellation } else { throw ex; @@ -77,7 +82,7 @@ class ArtifactsWorker extends SwingWorker, Void> { if (!isCancelled()) { try { listOfArtifacts.addAll(get()); - DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.ArtifactSearchResultEvent(artifactType, listOfArtifacts)); + DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.ArtifactSearchResultEvent(artifactType, listOfArtifacts, grabFocus)); } catch (InterruptedException | ExecutionException ex) { logger.log(Level.SEVERE, "Exception while trying to get list of artifacts for Domain details for artifact type: " + artifactType.getDisplayName() + " and domain: " + domain, ex); diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainArtifactsTabPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainArtifactsTabPanel.java index 1cc29aef1d..e344e2787b 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainArtifactsTabPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainArtifactsTabPanel.java @@ -95,6 +95,14 @@ final class DomainArtifactsTabPanel extends JPanel { } } + /** + * Assign the focus to this panel's list. + */ + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) + void focusList() { + listPanel.grabFocus(); + } + /** * Get the status of the panel which indicates if it is populated. * @@ -144,6 +152,9 @@ final class DomainArtifactsTabPanel extends JPanel { listPanel.selectFirst(); removeAll(); add(mainSplitPane); + if (artifactresultEvent.shouldGrabFocus()) { + focusList(); + } revalidate(); repaint(); try { diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainDetailsPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainDetailsPanel.java index df77f939fb..c50ab50020 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainDetailsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainDetailsPanel.java @@ -81,9 +81,9 @@ final class DomainDetailsPanel extends JPanel { selectedTabName = newTabTitle; Component selectedComponent = jTabbedPane1.getSelectedComponent(); if (selectedComponent instanceof DomainArtifactsTabPanel) { - runDomainWorker((DomainArtifactsTabPanel) selectedComponent); + runDomainWorker((DomainArtifactsTabPanel) selectedComponent, true); } else if (selectedComponent instanceof MiniTimelinePanel) { - runMiniTimelineWorker((MiniTimelinePanel) selectedComponent); + runMiniTimelineWorker((MiniTimelinePanel) selectedComponent, true); } } } @@ -122,17 +122,24 @@ final class DomainDetailsPanel extends JPanel { /** * Run the worker which retrieves the list of artifacts for the domain to * populate the details area. + * + * @param domainArtifactsTabPanel The DomainArtifactsTabPanel which has been + * selected. + * @param shouldGrabFocus True if the list of artifacts should have + * focus, false otherwise. */ @ThreadConfined(type = ThreadConfined.ThreadType.AWT) - private void runDomainWorker(DomainArtifactsTabPanel domainArtifactsTabPanel) { + private void runDomainWorker(DomainArtifactsTabPanel domainArtifactsTabPanel, boolean shouldGrabFocus) { if (singleArtifactDomainWorker != null && !singleArtifactDomainWorker.isDone()) { singleArtifactDomainWorker.cancel(true); } if (domainArtifactsTabPanel.getStatus() == DomainArtifactsTabPanel.ArtifactRetrievalStatus.UNPOPULATED) { DiscoveryEventUtils.getDiscoveryEventBus().register(domainArtifactsTabPanel); domainArtifactsTabPanel.setStatus(DomainArtifactsTabPanel.ArtifactRetrievalStatus.POPULATING); - singleArtifactDomainWorker = new ArtifactsWorker(domainArtifactsTabPanel.getArtifactType(), domain); + singleArtifactDomainWorker = new ArtifactsWorker(domainArtifactsTabPanel.getArtifactType(), domain, shouldGrabFocus); singleArtifactDomainWorker.execute(); + } else if (domainArtifactsTabPanel.getStatus() == DomainArtifactsTabPanel.ArtifactRetrievalStatus.POPULATED) { + domainArtifactsTabPanel.focusList(); } } @@ -140,11 +147,17 @@ final class DomainDetailsPanel extends JPanel { /** * Run the worker which retrieves the list of MiniTimelineResults for the * mini timeline view to populate. + * + * @param miniTimelinePanel The MiniTimelinePanel which has been selected. + * @param shouldGrabFocus True if the list of dates should have focus, + * false otherwise. */ - private void runMiniTimelineWorker(MiniTimelinePanel miniTimelinePanel) { + private void runMiniTimelineWorker(MiniTimelinePanel miniTimelinePanel, boolean shouldGrabFocus) { if (miniTimelinePanel.getStatus() == DomainArtifactsTabPanel.ArtifactRetrievalStatus.UNPOPULATED) { miniTimelinePanel.setStatus(DomainArtifactsTabPanel.ArtifactRetrievalStatus.POPULATING, domain); - new MiniTimelineWorker(domain).execute(); + new MiniTimelineWorker(domain, shouldGrabFocus).execute(); + } else if (miniTimelinePanel.getStatus() == DomainArtifactsTabPanel.ArtifactRetrievalStatus.POPULATED) { + miniTimelinePanel.focusList(); } } @@ -162,12 +175,13 @@ final class DomainDetailsPanel extends JPanel { //send fade out event DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.DetailsVisibleEvent(false)); } else { + resetTabsStatus(); domain = populateEvent.getDomain(); Component selectedComponent = jTabbedPane1.getSelectedComponent(); if (selectedComponent instanceof DomainArtifactsTabPanel) { - runDomainWorker((DomainArtifactsTabPanel) selectedComponent); + runDomainWorker((DomainArtifactsTabPanel) selectedComponent, false); } else if (selectedComponent instanceof MiniTimelinePanel) { - runMiniTimelineWorker((MiniTimelinePanel) selectedComponent); + runMiniTimelineWorker((MiniTimelinePanel) selectedComponent, false); } //send fade in event DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.DetailsVisibleEvent(true)); diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/MiniTimelinePanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/MiniTimelinePanel.java index 32c9e6bf6c..2a3248e0bb 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/MiniTimelinePanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/MiniTimelinePanel.java @@ -101,11 +101,19 @@ final class MiniTimelinePanel extends javax.swing.JPanel { return status; } + /** + * Assign the focus to this panel's list. + */ + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) + void focusList() { + dateListPanel.grabFocus(); + } + /** * Manually set the status of the panel. * * @param status The ArtifactRetrievalStatus of the panel - * @param domain The domain the panel is currently reflecting. + * @param domain The domain the panel is currently reflecting. */ @ThreadConfined(type = ThreadConfined.ThreadType.AWT) void setStatus(DomainArtifactsTabPanel.ArtifactRetrievalStatus status, String domain) { @@ -143,6 +151,9 @@ final class MiniTimelinePanel extends javax.swing.JPanel { dateListPanel.addSelectionListener(dateListener); artifactListPanel.addSelectionListener(artifactListener); dateListPanel.selectFirst(); + if (miniTimelineResultEvent.shouldGrabFocus()) { + focusList(); + } removeAll(); add(mainSplitPane); revalidate(); diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/MiniTimelineWorker.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/MiniTimelineWorker.java index 7ef49ca5d1..b047f4392f 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/MiniTimelineWorker.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/MiniTimelineWorker.java @@ -33,21 +33,26 @@ import org.sleuthkit.autopsy.discovery.search.DiscoveryException; import org.sleuthkit.autopsy.discovery.search.DomainSearch; /** - * SwingWorker to retrieve a list of artifacts for a specified type and domain. + * SwingWorker to retrieve a list of artifacts organized by date for the + * miniTimelinePanel for a specific domain. */ class MiniTimelineWorker extends SwingWorker { private final static Logger logger = Logger.getLogger(MiniTimelineWorker.class.getName()); private final String domain; + private final boolean grabFocus; /** - * Construct a new ArtifactsWorker. + * Construct a new MiniTimelineWorker. * - * @param artifactType The type of artifact being retrieved. - * @param domain The domain the artifacts should have as an attribute. + * @param domain The domain the artifacts should have as an + * attribute. + * @param shouldGrabFocus True if the list of artifacts should have focus, + * false otherwise. */ - MiniTimelineWorker(String domain) { + MiniTimelineWorker(String domain, boolean shouldGrabFocus) { this.domain = domain; + this.grabFocus = shouldGrabFocus; } @Override @@ -57,7 +62,7 @@ class MiniTimelineWorker extends SwingWorker { DomainSearch domainSearch = new DomainSearch(); try { results.addAll(domainSearch.getAllArtifactsForDomain(Case.getCurrentCase().getSleuthkitCase(), domain)); - DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.MiniTimelineResultEvent(results, domain)); + DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.MiniTimelineResultEvent(results, domain, grabFocus)); } catch (DiscoveryException ex) { if (ex.getCause() instanceof InterruptedException) { this.cancel(true);