6305 animation tools

This commit is contained in:
William Schaefer 2020-05-12 01:09:47 -04:00
parent 6fa370a782
commit c3156be65b
7 changed files with 509 additions and 24 deletions

View File

@ -139,7 +139,6 @@ FileSearchFiltering.TagsFilter.or=\ or
FileSearchFiltering.UserCreatedFilter.desc=Files that contain EXIF data
FileSearchPanel.dialogTitle.text=Test file search
FileSearchPanel.sortingPanel.border.title=Grouping
FileSearchPanel.searchButton.text=Show
FileSearchPanel.addButton.text=Add
FileSearchPanel.steptwo.documents=Step 2: Filter which documents to show
FileSearchPanel.steptwo.images=Step 2: Filter which images to show
@ -165,7 +164,6 @@ FileSearchDialog.objCheckBox.text=Objects
FileSearchDialog.exifCheckBox.text=Must contain EXIF data
FileSearchDialog.notableCheckBox.text=Must have been tagged as notable
FileSearchDialog.scoreCheckBox.text=Has score
FileSearchPanel.cancelButton.text=Cancel
FileSearchPanel.hashSetCheckbox.text=Hash Set:
FileSearchPanel.tagsCheckbox.text=Tag:
FileSearchPanel.interestingItemsCheckbox.text=Interesting Item:
@ -209,16 +207,17 @@ FileSearchPanel.excludeRadioButton.text=Exclude
FileSearchPanel.knownFilesCheckbox.toolTipText=
FileSearchPanel.knownFilesCheckbox.text=Hide known files
GroupListPanel.groupKeyList.border.title=Groups
DiscoveryTopComponent.imagesButton.text=Images
DiscoveryTopComponent.videosButton.text=Videos
ResultsPanel.resultsSplitPane.toolTipText=
FileSearchPanel.stepThreeLabel.text=Step 3: Choose display settings
DiscoveryTopComponent.stepOneLabel.text=Step 1: Pick File Type
DiscoveryTopComponent.documentsButton.text=Documents
DocumentPanel.fileSizeLabel.toolTipText=
DocumentPanel.isDeletedLabel.toolTipText=
ImageThumbnailPanel.isDeletedLabel.toolTipText=
FileSearchPanel.userCreatedCheckbox.text=Possibly User Created
DiscoveryDialog.documentsButton.text=Documents
DiscoveryDialog.videosButton.text=Videos
DiscoveryDialog.imagesButton.text=Images
DiscoveryDialog.searchButton.text=Show
DiscoveryDialog.cancelButton.text=Cancel
ResultsPanel.unableToCreate.text=Unable to create summary.
ResultsPanel.viewFileInDir.name=View File in Directory
VideoThumbnailPanel.bytes.text=bytes

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="667" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Component id="detailsSplitPane" alignment="0" pref="667" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="402" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Component id="detailsSplitPane" alignment="0" pref="402" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JSplitPane" name="detailsSplitPane">
<Properties>
<Property name="orientation" type="int" value="0"/>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
</Container>
</SubComponents>
</Form>

View File

@ -0,0 +1,60 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.sleuthkit.autopsy.discovery;
import org.sleuthkit.autopsy.corecomponents.DataContentPanel;
/**
*
* @author wschaefer
*/
public class DetailsPanel extends javax.swing.JPanel {
private final DataContentPanel dataContentPanel;
/**
* Creates new form DetailsPanel
*/
public DetailsPanel() {
initComponents();
dataContentPanel = DataContentPanel.createInstance();
detailsSplitPane.setBottomComponent(dataContentPanel);
}
/**
* 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
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
detailsSplitPane = new javax.swing.JSplitPane();
detailsSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 667, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(detailsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 667, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 402, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(detailsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 402, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JSplitPane detailsSplitPane;
// End of variables declaration//GEN-END:variables
}

View File

@ -30,7 +30,7 @@
<Group type="102" alignment="1" attributes="0">
<Component id="pagingPanel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
<Component id="resultsSplitPane" pref="436" max="32767" attributes="0"/>
<Component id="resultsSplitPane" pref="34" max="32767" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
</Group>
</Group>
@ -312,22 +312,16 @@
</Container>
<Container class="javax.swing.JSplitPane" name="resultsSplitPane">
<Properties>
<Property name="dividerLocation" type="int" value="380"/>
<Property name="orientation" type="int" value="0"/>
<Property name="resizeWeight" type="double" value="1.0"/>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ResultsPanel.resultsSplitPane.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="lastDividerLocation" type="int" value="180"/>
<Property name="opaque" type="boolean" value="false"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[777, 440]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
<SubComponents>
@ -358,11 +352,11 @@
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="68" max="32767" attributes="0"/>
<EmptySpace min="0" pref="433" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
<Component id="instancesScrollPane" max="32767" attributes="0"/>
<Component id="instancesScrollPane" pref="433" max="32767" attributes="0"/>
</Group>
</Group>
</Group>

View File

@ -56,10 +56,11 @@ import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.textsummarizer.TextSummary;
import java.awt.Graphics;
/**
* Panel for displaying of Discovery results and handling the paging of
* those results.
* Panel for displaying of Discovery results and handling the paging of those
* results.
*/
public class ResultsPanel extends javax.swing.JPanel {
@ -82,6 +83,14 @@ public class ResultsPanel extends javax.swing.JPanel {
private final DefaultListModel<AbstractFile> instancesListModel = new DefaultListModel<>();
private ListSelectionListener listener = null;
private int dividerLocation = 1;
private static final int ANIMATION_INCREMENT = 10;
private SwingAnimator fadeInAnimator = null;
private SwingAnimator fadeOutAnimator = null;
/**
* Creates new form ResultsPanel.
*/
@ -164,6 +173,7 @@ public class ResultsPanel extends javax.swing.JPanel {
if (files.isEmpty()) {
//if there are no files currently remove the current items without removing listener to cause content viewer to reset
instancesListModel.removeAllElements();
fadeOut();
} else {
//remove listener so content viewer node is not set multiple times
instancesList.removeListSelectionListener(listener);
@ -176,10 +186,12 @@ public class ResultsPanel extends javax.swing.JPanel {
if (!instancesListModel.isEmpty()) {
instancesList.setSelectedIndex(0);
}
fadeIn();
}
});
}
/**
* Get the AbstractFile for the item currently selected in the instances
* list.
@ -425,7 +437,7 @@ public class ResultsPanel extends javax.swing.JPanel {
javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
javax.swing.Box.Filler filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
javax.swing.Box.Filler filler4 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
javax.swing.JSplitPane resultsSplitPane = new javax.swing.JSplitPane();
resultsSplitPane = new javax.swing.JSplitPane();
javax.swing.JPanel instancesPanel = new javax.swing.JPanel();
javax.swing.JScrollPane instancesScrollPane = new javax.swing.JScrollPane();
instancesList = new javax.swing.JList<>();
@ -580,11 +592,9 @@ public class ResultsPanel extends javax.swing.JPanel {
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
pagingPanel.add(filler4, gridBagConstraints);
resultsSplitPane.setDividerLocation(380);
resultsSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
resultsSplitPane.setResizeWeight(1.0);
resultsSplitPane.setToolTipText(org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.resultsSplitPane.toolTipText")); // NOI18N
resultsSplitPane.setLastDividerLocation(180);
resultsSplitPane.setOpaque(false);
resultsSplitPane.setPreferredSize(new java.awt.Dimension(777, 440));
@ -609,11 +619,11 @@ public class ResultsPanel extends javax.swing.JPanel {
);
instancesPanelLayout.setVerticalGroup(
instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 68, Short.MAX_VALUE)
.addGap(0, 433, Short.MAX_VALUE)
.addGroup(instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, instancesPanelLayout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(instancesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addComponent(instancesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 433, Short.MAX_VALUE)))
);
resultsSplitPane.setRightComponent(instancesPanel);
@ -627,14 +637,14 @@ public class ResultsPanel extends javax.swing.JPanel {
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(pagingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addComponent(resultsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(resultsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 29, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(pagingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0)
.addComponent(resultsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 436, Short.MAX_VALUE)
.addComponent(resultsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 34, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
}// </editor-fold>//GEN-END:initComponents
@ -723,6 +733,7 @@ public class ResultsPanel extends javax.swing.JPanel {
private javax.swing.JButton nextPageButton;
private javax.swing.JComboBox<Integer> pageSizeComboBox;
private javax.swing.JButton previousPageButton;
private javax.swing.JSplitPane resultsSplitPane;
private javax.swing.JPanel resultsViewerPanel;
// End of variables declaration//GEN-END:variables
@ -878,4 +889,154 @@ public class ResultsPanel extends javax.swing.JPanel {
}
}
/**
*
* Sets the alpha value
*
* @param a
*
*/
public void setDividerLocation(int a) {
this.dividerLocation = a;
}
/**
*
* Fades this JPanel in. *
*/
public void fadeIn() {
stop();
fadeInAnimator = new SwingAnimator(new FadeInCallback());
fadeInAnimator.start();
}
/**
*
* Fades this JPanel out
*
*/
public void fadeOut() {
stop();
fadeOutAnimator = new SwingAnimator(new FadeOutCallback());
fadeOutAnimator.start();
}
/**
*
* Stops all animators. *
*/
private void stop() {
if (fadeOutAnimator != null && fadeOutAnimator.isRunning()) {
fadeOutAnimator.stop();
}
if (fadeInAnimator != null && fadeInAnimator.isRunning()) {
fadeInAnimator.stop();
}
}
@Override
public void paintComponent(Graphics g) {
if (dividerLocation <= resultsSplitPane.getHeight() && dividerLocation >= (resultsSplitPane.getHeight() - 100)) {
resultsSplitPane.setDividerLocation(dividerLocation);
}
super.paintComponent(g);
}
/**
*
* Callback implementation for fading in
*
* @author Greg Cope
*
*
*
*/
private class FadeInCallback implements SwingAnimatorCallback {
@Override
public void callback(Object caller) {
dividerLocation -= ANIMATION_INCREMENT;
repaint();
}
@Override
public boolean hasTerminated() {
if (dividerLocation <= (resultsSplitPane.getHeight() - 100)) {
dividerLocation = resultsSplitPane.getHeight() - 100;
System.out.println("FADE IN COMPLETE");
return true;
}
return false;
}
}
/**
*
* Callback implementation to fade out
*
* @author Greg Cope
*
*
*
*/
private class FadeOutCallback implements SwingAnimatorCallback {
@Override
public void callback(Object caller) {
dividerLocation += ANIMATION_INCREMENT;
repaint();
}
@Override
public boolean hasTerminated() {
if (dividerLocation >= resultsSplitPane.getHeight()) {
dividerLocation = resultsSplitPane.getHeight();
System.out.println("FADE OUT COMPLETE");
return true;
}
return false;
}
}
}

View File

@ -0,0 +1,193 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.sleuthkit.autopsy.discovery;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
/**
*
* Class to animate Layouts and Fades for a given component.
*
*
* @author Greg Cope
*
*
*
*/
public final class SwingAnimator {
//callback object
private final SwingAnimatorCallback callback;
//Timer to animate on the EDT
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;
/**
*
* Constructs a new SwingAnimator.
*
*
* @param callback The object to callback to
*
*/
public SwingAnimator(SwingAnimatorCallback callback) {
this(callback, false);
}
/**
*
*
*
* @param callback The object to callback to
*
* @param start true to automatically start the animation, false
* otherwise
*
*/
public 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
*
*/
public SwingAnimator(SwingAnimatorCallback callback, int frameTiming, boolean start) {
this.callback = callback;
duration = frameTiming;
if (start) {
start();
}
}
/**
*
*
*
* @param callback The object to callback to
*
* @param frameTiming Timing between each call to callback.
*
*/
public SwingAnimator(SwingAnimatorCallback callback, int frameTiming) {
this(callback, frameTiming, false);
}
/**
*
* Checks if this animator is running.
*
* @return
*
*/
public boolean isRunning() {
if (timer == null) {
return false;
}
return timer.isRunning();
}
/**
*
* Stops the timer
*
*/
public void stop() {
if (timer != null) {
timer.stop();
}
}
/**
*
* 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. *
*/
public void start() {
if (timer != null && timer.isRunning()) {
stop();
}
timer = new Timer(duration, new CallbackListener());
timer.start();
}
/**
*
* ActionListener implements to be passed to the internal timer instance
*
* @author Greg Cope
*
*
*
*/
private class CallbackListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (callback.hasTerminated()) {
if (timer == null) {
throw new IllegalStateException("Callback listener should not be fired outside of SwingAnimator timer control");
}
timer.stop();
}
callback.callback(SwingAnimator.this);
}
}
}

View File

@ -0,0 +1,35 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.sleuthkit.autopsy.discovery;
/**
*
* Callback interface to be notified by a SwingAnimator of a new time frame. *
* @author Greg Cope
*
*
*
*/
public interface SwingAnimatorCallback {
/**
*
* Callback method for the SwingAnimator
*
* @param caller
*
*/
public void callback(Object caller);
/**
*
* Returns true if the SwingAnimator should terminate. *
* @return
*
*/
public boolean hasTerminated();
}