6305 fix wait cursor

This commit is contained in:
William Schaefer 2020-06-04 10:00:35 -04:00
parent b356d93dac
commit 535d3869f4
10 changed files with 171 additions and 87 deletions

View File

@ -24,7 +24,9 @@ import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.event.ListSelectionListener;
/**
* Abstract class extending JPanel for filter controls.
*/
abstract class AbstractDiscoveryFilterPanel extends javax.swing.JPanel {
private static final long serialVersionUID = 1L;
@ -40,20 +42,44 @@ abstract class AbstractDiscoveryFilterPanel extends javax.swing.JPanel {
*/
abstract void configurePanel(boolean selected, int[] indicesSelected);
/**
* Get the checkbox which enables and disables this filter.
*
* @return The JCheckBox which enables and disables this filter.
*/
abstract JCheckBox getCheckbox();
/**
* Get the list of values associated with this filter if one exists. If one
* does not exist this should return null.
*
* @return The JList which contains the values available for selection for
* this filter.
*/
abstract JList<?> getList();
/**
* Get any additional text that should be displayed under the checkbox. If
* no text should be displayed this should return null.
*
* @return The JLabel to display under the JCheckBox.
*/
abstract JLabel getAdditionalLabel();
/**
* Check if this filter is configured to valid settings.
*
* @return True if the filter is configured with valid search settings,
* false otherwise.
*/
abstract String checkForError();
/**
* Add listeners to the checkbox/list set if listeners have not already been
* added.
*
* @param listener
* @param listListener
* @param actionlistener The listener for the checkbox selection events.
* @param listListener The listener for the list selection events.
*/
void addListeners(ActionListener actionListener, ListSelectionListener listListener) {
if (getCheckbox() != null) {
@ -64,8 +90,17 @@ abstract class AbstractDiscoveryFilterPanel extends javax.swing.JPanel {
}
}
/**
* Get the FileFilter which is represented by this Panel.
*
* @return The FileFilter for the selected settings, null if the settings
* are not in use.
*/
abstract FileSearchFiltering.FileFilter getFilter();
/**
* Remove listeners from the checkbox and the list if they exist.
*/
void removeListeners() {
if (getCheckbox() != null) {
for (ActionListener listener : getCheckbox().getActionListeners()) {
@ -79,6 +114,12 @@ abstract class AbstractDiscoveryFilterPanel extends javax.swing.JPanel {
}
}
/**
* Return whether or not this filter has a panel.
*
* @return True if there is a panel to display associated with this filter,
* return false if the filter only has a checkbox.
*/
boolean hasPanel() {
return true;
}

View File

@ -31,7 +31,10 @@ import javax.swing.JSplitPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
/**
* Abstract class extending JPanel for displaying all the filters associated
* with a type.
*/
abstract class AbstractFiltersPanel extends JPanel implements ActionListener, ListSelectionListener {
private boolean isInitialized = false;
@ -49,13 +52,32 @@ abstract class AbstractFiltersPanel extends JPanel implements ActionListener, Li
private int firstColumnY = 0;
private int secondColumnY = 0;
/**
* Setup necessary for implementations of this abstract class.
*/
AbstractFiltersPanel() {
firstColumnPanel.setLayout(new GridBagLayout());
secondColumnPanel.setLayout(new GridBagLayout());
}
/**
* Get the type of results this filters panel is for.
*
* @return The type of results this panel filters.
*/
abstract FileSearchData.FileType getFileType();
/**
* Add a DiscoveryFilterPanel to the specified column with the specified
* settings.
*
* @param filterPanel The DiscoveryFilterPanel to add to this panel.
* @param isSelected True if the checkbox should be selected, false
* otherwise.
* @param indicesSelected The array of indices that are selected in the
* list, null if none are selected.
* @param column The column to add the DiscoveryFilterPanel to.
*/
final synchronized void addFilter(AbstractDiscoveryFilterPanel filterPanel, boolean isSelected, int[] indicesSelected, int column) {
if (!isInitialized) {
constraints.gridy = 0;
@ -98,6 +120,11 @@ abstract class AbstractFiltersPanel extends JPanel implements ActionListener, Li
}
}
/**
* Add the panels representing the two columns to the specified JSplitPane.
*
* @param splitPane The JSplitPane which the columns are added to.
*/
final void addPanelsToScrollPane(JSplitPane splitPane) {
splitPane.setLeftComponent(firstColumnPanel);
splitPane.setRightComponent(secondColumnPanel);
@ -105,6 +132,9 @@ abstract class AbstractFiltersPanel extends JPanel implements ActionListener, Li
repaint();
}
/**
* Clear the filters from the panel
*/
final synchronized void clearFilters() {
for (AbstractDiscoveryFilterPanel filterPanel : filters) {
filterPanel.removeListeners();

View File

@ -136,6 +136,7 @@ final class DataSourceFilterPanel extends AbstractDiscoveryFilterPanel {
try {
DefaultListModel<DataSourceItem> dsListModel = (DefaultListModel<DataSourceItem>) dataSourceList.getModel();
dsListModel.removeAllElements();
System.out.println("CASE: " + Case.getCurrentCase().getName());
for (DataSource ds : Case.getCurrentCase().getSleuthkitCase().getDataSources()) {
dsListModel.add(count, new DataSourceItem(ds));
}

View File

@ -22,9 +22,12 @@ import static java.awt.BorderLayout.CENTER;
import java.awt.Color;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import org.apache.commons.lang.StringUtils;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -34,6 +37,8 @@ import org.sleuthkit.autopsy.discovery.FileSorter.SortingMethod;
final class DiscoveryDialog extends javax.swing.JDialog {
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE,
Case.Events.DATA_SOURCE_ADDED, Case.Events.DATA_SOURCE_DELETED);
private static final long serialVersionUID = 1L;
private final static Logger logger = Logger.getLogger(DiscoveryDialog.class.getName());
private ImageFilterPanel imageFilterPanel = new ImageFilterPanel();
@ -83,12 +88,14 @@ final class DiscoveryDialog extends javax.swing.JDialog {
groupSortingComboBox.addItem(groupSortAlgorithm);
}
updateSearchSettings();
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this.new CasePropertyChangeListener());
}
/**
* Update the search settings to a default state.
*/
void updateSearchSettings() {
System.out.println("UPDATE CALLED");
imageFilterPanel = new ImageFilterPanel();
videoFilterPanel = new VideoFilterPanel();
documentFilterPanel = new DocumentFilterPanel();
@ -487,4 +494,30 @@ final class DiscoveryDialog extends javax.swing.JDialog {
private javax.swing.JButton searchButton;
private javax.swing.JButton videosButton;
// End of variables declaration//GEN-END:variables
private class CasePropertyChangeListener implements PropertyChangeListener {
@Override
@SuppressWarnings("fallthrough")
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("EVENT RECEIVED");
switch (Case.Events.valueOf(evt.getPropertyName())) {
case CURRENT_CASE: {
if (evt.getNewValue() == null) {
//do not refresh when a case is closed only when it is opened.
break;
}
//else fallthrough
}
case DATA_SOURCE_ADDED:
//fallthrough
case DATA_SOURCE_DELETED:
updateSearchSettings();
break;
default:
//do nothing if the event is not one of the above events.
break;
}
}
}
}

View File

@ -50,15 +50,12 @@ final class GroupListPanel extends javax.swing.JPanel {
*/
GroupListPanel() {
initComponents();
SwingUtilities.invokeLater(() -> {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
});
}
/**
* Subscribe to and reset the panel in response to SearchStartedEvents
* Subscribe to and reset the panel in response to SearchStartedEvents.
*
* @param searchStartedEvent the SearchStartedEvent which was received
* @param searchStartedEvent The SearchStartedEvent which was received.
*/
@Subscribe
void handleSearchStartedEvent(DiscoveryEventUtils.SearchStartedEvent searchStartedEvent) {
@ -70,9 +67,9 @@ final class GroupListPanel extends javax.swing.JPanel {
"GroupsListPanel.noResults.title.text=No results found"})
/**
* Subscribe to and update list of groups in response to
* SearchCompleteEvents
* SearchCompleteEvents.
*
* @param searchCompleteEvent the SearchCompleteEvent which was received
* @param searchCompleteEvent The SearchCompleteEvent which was received.
*/
@Subscribe
void handleSearchCompleteEvent(DiscoveryEventUtils.SearchCompleteEvent searchCompleteEvent) {
@ -95,6 +92,18 @@ final class GroupListPanel extends javax.swing.JPanel {
});
}
/**
* Subscribe to SearchCancelledEvent and reset the panel in response to it.
*
* @param searchCancelledEvent The SearchCancelledEvent which was received.
*/
@Subscribe
void handleSearchCancelledEvent(DiscoveryEventUtils.SearchCancelledEvent searchCancelledEvent) {
SwingUtilities.invokeLater(() -> {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
});
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
@ -138,6 +147,9 @@ final class GroupListPanel extends javax.swing.JPanel {
* Reset the group list to be empty.
*/
void resetGroupList() {
SwingUtilities.invokeLater(() -> {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
});
groupKeyList.setListData(new GroupKey[0]);
}
@ -160,6 +172,7 @@ final class GroupListPanel extends javax.swing.JPanel {
}
} else {
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.NoResultsEvent());
}
}
}//GEN-LAST:event_groupSelected

View File

@ -34,7 +34,7 @@ final class ImageFilterPanel extends AbstractFiltersPanel {
SizeFilterPanel sizeFilterPanel = new SizeFilterPanel(FILE_TYPE);
int[] sizeIndicesSelected = {1, 2, 3, 4, 5};
addFilter(sizeFilterPanel, true, sizeIndicesSelected, 0);
addFilter(new ObjectDetectedFilterPanel(), false, null, 0);
addFilter(new DataSourceFilterPanel(), false, null, 0);
int[] pastOccurrencesIndices;
if (!CentralRepository.isEnabled()) {
pastOccurrencesIndices = new int[]{0};
@ -45,7 +45,7 @@ final class ImageFilterPanel extends AbstractFiltersPanel {
addFilter(new UserCreatedFilterPanel(), false, null, 1);
addFilter(new HashSetFilterPanel(), false, null, 1);
addFilter(new InterestingItemsFilterPanel(), false, null, 1);
addFilter(new DataSourceFilterPanel(), false, null, 1);
addFilter(new ObjectDetectedFilterPanel(), false, null, 1);
addFilter(new ParentFolderFilterPanel(), false, null, 1);
addPanelsToScrollPane(imageFiltersSplitPane);

View File

@ -132,7 +132,6 @@ public final class OpenDiscoveryAction extends CallableSystemAction implements P
@Override
public void setEnabled(boolean value) {
super.setEnabled(value);
DiscoveryDialog.getDiscoveryDialogInstance().updateSearchSettings();
toolbarButton.setEnabled(value);
}

View File

@ -108,9 +108,6 @@ final class ResultsPanel extends javax.swing.JPanel {
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.ClearInstanceSelectionEvent());
}
}
});
SwingUtilities.invokeLater(() -> {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
});
}
@ -137,6 +134,18 @@ final class ResultsPanel extends javax.swing.JPanel {
return new ArrayList<>();
}
/**
* Subscribe to and reset the panel in response to SearchStartedEvents
*
* @param searchStartedEvent the SearchStartedEvent which was received
*/
@Subscribe
void handleSearchStartedEvent(DiscoveryEventUtils.SearchStartedEvent searchStartedEvent) {
SwingUtilities.invokeLater(() -> {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
});
}
/**
* Subscribe and respond to PageRetrievedEvents.
*
@ -145,6 +154,7 @@ final class ResultsPanel extends javax.swing.JPanel {
@Subscribe
void handlePageRetrievedEvent(DiscoveryEventUtils.PageRetrievedEvent pageRetrievedEvent) {
SwingUtilities.invokeLater(() -> {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
//send populateMesage
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.PopulateInstancesListEvent(getInstancesForSelected()));
@ -257,7 +267,6 @@ final class ResultsPanel extends javax.swing.JPanel {
resultType = groupSelectedEvent.getResultType();
groupSize = groupSelectedEvent.getGroupSize();
setPage(0);
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
});
}
@ -270,6 +279,7 @@ final class ResultsPanel extends javax.swing.JPanel {
@Subscribe
void handleNoResultsEvent(DiscoveryEventUtils.NoResultsEvent noResultsEvent) {
SwingUtilities.invokeLater(() -> {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
groupSize = 0;
currentPage = 0;
updateControls();
@ -281,6 +291,8 @@ final class ResultsPanel extends javax.swing.JPanel {
});
}
@Subscribe
/**
* Set the page number and retrieve its contents.
*

View File

@ -24,13 +24,11 @@ import javax.swing.Timer;
/**
*
* Class to animate Layouts and Fades for a given component.
* Class to animate Layouts for a given component.
*
* @author Greg Cope
* https://www.algosome.com/articles/java-swing-panel-animation.html
*
*
*
*/
final class SwingAnimator {
@ -41,77 +39,38 @@ final class SwingAnimator {
private Timer timer = null;
//duration in milliseconds betweeen each firing of the Timer
private static final int INITIAL_DURATION = 10;
private static int duration = INITIAL_DURATION;
private static final int INITIAL_TIMING = 10;
private static int timing = INITIAL_TIMING;
/**
*
* Constructs a new SwingAnimator.
*
*
* @param callback The object to callback to
* @param callback The SwingAnimatorCallback to call.
*
*/
SwingAnimator(SwingAnimatorCallback callback) {
this(callback, false);
this(callback, INITIAL_TIMING);
}
/**
*
* Constructs a new SwingAnimator.
*
*
* @param callback The object to callback to
*
* @param start true to automatically start the animation, false
* otherwise
*
*/
SwingAnimator(SwingAnimatorCallback callback, boolean start) {
this(callback, INITIAL_DURATION, start);
}
/**
*
*
*
* @param callback The object to callback to
*
* @param frameTiming Timing between each call to callback.
*
* @param start true to automatically start the animation, false
* otherwise
*
*/
SwingAnimator(SwingAnimatorCallback callback, int frameTiming, boolean start) {
this.callback = callback;
duration = frameTiming;
if (start) {
start();
}
}
/**
*
*
*
* @param callback The object to callback to
*
* @param callback The SwingAnimatorCallback to call.
* @param frameTiming Timing between each call to callback.
*
*/
SwingAnimator(SwingAnimatorCallback callback, int frameTiming) {
this(callback, frameTiming, false);
this.callback = callback;
timing = frameTiming;
}
/**
*
* Checks if this animator is running.
*
* @return
* @return True if the animator is running, false otherwise.
*
*/
boolean isRunning() {
@ -135,26 +94,19 @@ final class SwingAnimator {
/**
*
* Starts the timer to fire. If the current timer is non-null and running,
* this method will first
*
* stop the timer before beginning a new one. *
* this method will first stop the timer before beginning a new one.
*/
void start() {
if (timer != null && timer.isRunning()) {
stop();
}
timer = new Timer(duration, new CallbackListener());
timer = new Timer(timing, new CallbackListener());
timer.start();
}
/**
*
* ActionListener implements to be passed to the internal timer instance
*
* @author Greg Cope
*
*
* ActionListener implements to be passed to the internal timer instance.
*
*/
private class CallbackListener implements ActionListener {

View File

@ -20,7 +20,9 @@ package org.sleuthkit.autopsy.discovery;
/**
*
* Callback interface to be notified by a SwingAnimator of a new time frame. *
* Callback interface to be notified by a SwingAnimator of a new time frame.
*
*
* @author Greg Cope
* https://www.algosome.com/articles/java-swing-panel-animation.html
*
@ -29,17 +31,18 @@ interface SwingAnimatorCallback {
/**
*
* Callback method for the SwingAnimator
* Callback method for the SwingAnimator.
*
* @param caller
* @param caller The object which is calling the Callback.
*
*/
void callback(Object caller);
/**
*
* Returns true if the SwingAnimator should terminate. *
* @return
* Returns true if the SwingAnimator has terminated.
*
* @return True if the animator has terminated, false otherwise.
*
*/
boolean hasTerminated();