Autopsy  4.15.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
DiscoveryTopComponent.java
Go to the documentation of this file.
1 /*
2  * Autopsy
3  *
4  * Copyright 2019-2020 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.discovery;
20 
21 import com.google.common.eventbus.Subscribe;
22 import java.awt.BorderLayout;
23 import java.awt.Color;
24 import java.awt.Graphics;
25 import java.util.List;
26 import java.util.stream.Collectors;
27 import javax.swing.JSplitPane;
28 import javax.swing.plaf.basic.BasicSplitPaneDivider;
29 import javax.swing.plaf.basic.BasicSplitPaneUI;
30 import org.openide.util.NbBundle;
31 import org.openide.util.NbBundle.Messages;
32 import org.openide.windows.Mode;
33 import org.openide.windows.RetainLocation;
34 import org.openide.windows.TopComponent;
35 import org.openide.windows.WindowManager;
38 
42 @TopComponent.Description(preferredID = "DiscoveryTopComponent", persistenceType = TopComponent.PERSISTENCE_NEVER)
43 @TopComponent.Registration(mode = "discovery", openAtStartup = false)
44 @RetainLocation("discovery")
45 @NbBundle.Messages("DiscoveryTopComponent.name= Discovery")
46 public final class DiscoveryTopComponent extends TopComponent {
47 
48  private static final long serialVersionUID = 1L;
49  private static final String PREFERRED_ID = "DiscoveryTopComponent"; // NON-NLS
50  private final GroupListPanel groupListPanel;
51  private final DetailsPanel detailsPanel;
52  private final ResultsPanel resultsPanel;
53  private int dividerLocation = -1;
54 
55  private static final int ANIMATION_INCREMENT = 10;
56  private static final int RESULTS_AREA_SMALL_SIZE = 250;
57 
58  private SwingAnimator animator = null;
59 
66  setName(Bundle.DiscoveryTopComponent_name());
67  groupListPanel = new GroupListPanel();
68  resultsPanel = new ResultsPanel();
69  detailsPanel = new DetailsPanel();
70  mainSplitPane.setLeftComponent(groupListPanel);
71  rightSplitPane.setTopComponent(resultsPanel);
72  rightSplitPane.setBottomComponent(detailsPanel);
73  //set color of divider
74  rightSplitPane.setUI(new BasicSplitPaneUI() {
75  @Override
76  public BasicSplitPaneDivider createDefaultDivider() {
77  return new BasicSplitPaneDividerImpl(this);
78 
79  }
80  });
81  }
82 
86  private final class BasicSplitPaneDividerImpl extends BasicSplitPaneDivider {
87 
94  BasicSplitPaneDividerImpl(BasicSplitPaneUI ui) {
95  super(ui);
96  this.setLayout(new BorderLayout());
97  this.add(new ResultsSplitPaneDivider());
98  }
99 
100  private static final long serialVersionUID = 1L;
101  }
102 
109  return (DiscoveryTopComponent) WindowManager.getDefault().findTopComponent(PREFERRED_ID);
110  }
111 
115  public void resetTopComponent() {
116  resultsPanel.resetResultViewer();
117  groupListPanel.resetGroupList();
118  }
119 
120  @Override
121  public void componentOpened() {
122  super.componentOpened();
123  WindowManager.getDefault().setTopComponentFloating(this, true);
124  DiscoveryEventUtils.getDiscoveryEventBus().register(this);
125  DiscoveryEventUtils.getDiscoveryEventBus().register(resultsPanel);
126  DiscoveryEventUtils.getDiscoveryEventBus().register(groupListPanel);
127  DiscoveryEventUtils.getDiscoveryEventBus().register(detailsPanel);
128  }
129 
130  @Override
131  protected void componentClosed() {
132  DiscoveryDialog.getDiscoveryDialogInstance().cancelSearch();
133  DiscoveryEventUtils.getDiscoveryEventBus().unregister(this);
134  DiscoveryEventUtils.getDiscoveryEventBus().unregister(groupListPanel);
135  DiscoveryEventUtils.getDiscoveryEventBus().unregister(resultsPanel);
136  DiscoveryEventUtils.getDiscoveryEventBus().unregister(detailsPanel);
137  super.componentClosed();
138  }
139 
145  @SuppressWarnings("unchecked")
146  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
147  private void initComponents() {
148 
149  mainSplitPane = new javax.swing.JSplitPane();
151  javax.swing.JPanel searchDetailsPanel = new javax.swing.JPanel();
152  newSearchButton = new javax.swing.JButton();
153  javax.swing.JScrollPane progressMessageScrollPane = new javax.swing.JScrollPane();
154  progressMessageTextArea = new javax.swing.JTextArea();
155 
156  setMinimumSize(new java.awt.Dimension(199, 200));
157  setPreferredSize(new java.awt.Dimension(1100, 700));
158  setLayout(new java.awt.BorderLayout());
159 
160  mainSplitPane.setDividerLocation(250);
161  mainSplitPane.setPreferredSize(new java.awt.Dimension(1100, 700));
162 
163  rightSplitPane.setDividerSize(35);
164  rightSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
165  rightSplitPane.setResizeWeight(1.0);
166  rightSplitPane.setPreferredSize(new java.awt.Dimension(800, 700));
167  mainSplitPane.setRightComponent(rightSplitPane);
168 
169  add(mainSplitPane, java.awt.BorderLayout.CENTER);
170 
171  org.openide.awt.Mnemonics.setLocalizedText(newSearchButton, org.openide.util.NbBundle.getMessage(DiscoveryTopComponent.class, "FileSearchDialog.cancelButton.text")); // NOI18N
172  newSearchButton.setMaximumSize(new java.awt.Dimension(110, 26));
173  newSearchButton.setMinimumSize(new java.awt.Dimension(110, 26));
174  newSearchButton.setPreferredSize(new java.awt.Dimension(110, 26));
175  newSearchButton.addActionListener(new java.awt.event.ActionListener() {
176  public void actionPerformed(java.awt.event.ActionEvent evt) {
178  }
179  });
180 
181  progressMessageScrollPane.setBorder(null);
182 
183  progressMessageTextArea.setBackground(new java.awt.Color(240, 240, 240));
184  progressMessageTextArea.setColumns(20);
185  progressMessageTextArea.setLineWrap(true);
186  progressMessageTextArea.setRows(2);
187  progressMessageTextArea.setWrapStyleWord(true);
188  progressMessageTextArea.setBorder(null);
189  progressMessageScrollPane.setViewportView(progressMessageTextArea);
190 
191  javax.swing.GroupLayout searchDetailsPanelLayout = new javax.swing.GroupLayout(searchDetailsPanel);
192  searchDetailsPanel.setLayout(searchDetailsPanelLayout);
193  searchDetailsPanelLayout.setHorizontalGroup(
194  searchDetailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
195  .addGroup(searchDetailsPanelLayout.createSequentialGroup()
196  .addContainerGap()
197  .addComponent(newSearchButton, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)
198  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
199  .addComponent(progressMessageScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 954, Short.MAX_VALUE)
200  .addContainerGap())
201  );
202  searchDetailsPanelLayout.setVerticalGroup(
203  searchDetailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
204  .addGroup(searchDetailsPanelLayout.createSequentialGroup()
205  .addGroup(searchDetailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
206  .addGroup(searchDetailsPanelLayout.createSequentialGroup()
207  .addGap(8, 8, 8)
208  .addComponent(progressMessageScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE))
209  .addGroup(searchDetailsPanelLayout.createSequentialGroup()
210  .addGap(17, 17, 17)
211  .addComponent(newSearchButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
212  .addContainerGap())
213  );
214 
215  add(searchDetailsPanel, java.awt.BorderLayout.PAGE_START);
216  }// </editor-fold>//GEN-END:initComponents
217 
218  private void newSearchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newSearchButtonActionPerformed
219  close();
220  final DiscoveryDialog discDialog = DiscoveryDialog.getDiscoveryDialogInstance();
221  discDialog.cancelSearch();
222  discDialog.setVisible(true);
223  discDialog.validateDialog();
224  }//GEN-LAST:event_newSearchButtonActionPerformed
225 
226  @Override
227  public List<Mode> availableModes(List<Mode> modes) {
228  /*
229  * This looks like the right thing to do, but online discussions seems
230  * to indicate this method is effectively deprecated. A break point
231  * placed here was never hit.
232  */
233  return modes.stream().filter(mode -> mode.getName().equals("discovery"))
234  .collect(Collectors.toList());
235  }
236 
244  @Subscribe
245  void handleDetailsVisibleEvent(DiscoveryEventUtils.DetailsVisibleEvent detailsVisibleEvent) {
246  if (animator != null && animator.isRunning()) {
247  animator.stop();
248  }
249  dividerLocation = rightSplitPane.getDividerLocation();
250  if (detailsVisibleEvent.isShowDetailsArea()) {
251  animator = new SwingAnimator(new ShowDetailsAreaCallback());
252  } else {
253  animator = new SwingAnimator(new HideDetailsAreaCallback());
254  }
255  animator.start();
256  }
257 
264  @Messages({"DiscoveryTopComponent.cancelButton.text=Cancel Search",
265  "# {0} - searchType",
266  "DiscoveryTopComponent.searchInProgress.text=Performing search for results of type {0}. Please wait."})
267  @Subscribe
268  void handleSearchStartedEvent(DiscoveryEventUtils.SearchStartedEvent searchStartedEvent) {
269  newSearchButton.setText(Bundle.DiscoveryTopComponent_cancelButton_text());
270  progressMessageTextArea.setForeground(Color.red);
271  progressMessageTextArea.setText(Bundle.DiscoveryTopComponent_searchInProgress_text(searchStartedEvent.getType().name()));
272  }
273 
280  @Subscribe
281  @Messages({"DiscoveryTopComponent.newSearch.text=New Search",
282  "# {0} - search",
283  "DiscoveryTopComponent.searchComplete.text=Results with {0}"})
284  void handleSearchCompleteEvent(DiscoveryEventUtils.SearchCompleteEvent searchCompleteEvent) {
285  newSearchButton.setText(Bundle.DiscoveryTopComponent_newSearch_text());
286  progressMessageTextArea.setForeground(Color.black);
287  progressMessageTextArea.setText(Bundle.DiscoveryTopComponent_searchComplete_text(searchCompleteEvent.getFilters().stream().map(FileFilter::getDesc).collect(Collectors.joining("; "))));
288  progressMessageTextArea.setCaretPosition(0);
289  }
290 
297  @Messages({"DiscoveryTopComponent.searchCancelled.text=Search has been cancelled."})
298  @Subscribe
299  void handleSearchCancelledEvent(DiscoveryEventUtils.SearchCancelledEvent searchCancelledEvent) {
300  newSearchButton.setText(Bundle.DiscoveryTopComponent_newSearch_text());
301  progressMessageTextArea.setForeground(Color.red);
302  progressMessageTextArea.setText(Bundle.DiscoveryTopComponent_searchCancelled_text());
303 
304  }
305 
309  private final class ShowDetailsAreaCallback implements SwingAnimatorCallback {
310 
311  @Override
312  public void callback(Object caller) {
313  dividerLocation -= ANIMATION_INCREMENT;
314  repaint();
315  }
316 
317  @Override
318  public boolean hasTerminated() {
319  if (dividerLocation != JSplitPane.UNDEFINED_CONDITION && dividerLocation < RESULTS_AREA_SMALL_SIZE) {
320  dividerLocation = RESULTS_AREA_SMALL_SIZE;
321  return true;
322  }
323  return false;
324  }
325 
326  }
327 
331  private final class HideDetailsAreaCallback implements SwingAnimatorCallback {
332 
333  @Override
334  public void callback(Object caller) {
335  dividerLocation += ANIMATION_INCREMENT;
336  repaint();
337  }
338 
339  @Override
340  public boolean hasTerminated() {
341  if (dividerLocation > rightSplitPane.getHeight() || dividerLocation == JSplitPane.UNDEFINED_CONDITION) {
342  dividerLocation = rightSplitPane.getHeight();
343  return true;
344  }
345  return false;
346  }
347 
348  }
349  // Variables declaration - do not modify//GEN-BEGIN:variables
350  private javax.swing.JSplitPane mainSplitPane;
351  private javax.swing.JButton newSearchButton;
352  private javax.swing.JTextArea progressMessageTextArea;
353  private javax.swing.JSplitPane rightSplitPane;
354  // End of variables declaration//GEN-END:variables
355 
359  private final class AnimatedSplitPane extends JSplitPane {
360 
361  private static final long serialVersionUID = 1L;
362 
363  @Override
364  public void paintComponent(Graphics g) {
365  if ((dividerLocation == JSplitPane.UNDEFINED_CONDITION) || (dividerLocation <= rightSplitPane.getHeight() && dividerLocation >= RESULTS_AREA_SMALL_SIZE)) {
366  rightSplitPane.setDividerLocation(dividerLocation);
367  }
368  super.paintComponent(g);
369  }
370 
371  }
372 
373 }
void newSearchButtonActionPerformed(java.awt.event.ActionEvent evt)

Copyright © 2012-2020 Basis Technology. Generated on: Mon Jul 6 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.