19 package org.sleuthkit.autopsy.discovery.ui;
21 import java.awt.Color;
22 import java.awt.Component;
23 import java.awt.Point;
24 import java.awt.event.MouseEvent;
25 import java.time.Instant;
26 import java.time.ZonedDateTime;
27 import java.util.HashSet;
28 import java.util.TimeZone;
30 import javax.swing.ImageIcon;
31 import javax.swing.JComponent;
32 import javax.swing.JList;
33 import javax.swing.ListCellRenderer;
34 import org.openide.util.NbBundle;
42 class DomainSummaryPanel
extends javax.swing.JPanel implements ListCellRenderer<DomainWrapper> {
44 private static final long serialVersionUID = 1L;
45 private static final Color SELECTION_COLOR =
new Color(0, 120, 215);
50 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
51 DomainSummaryPanel() {
53 domainNameLabel.setFont(domainNameLabel.getFont().deriveFont(domainNameLabel.getFont().getStyle(), domainNameLabel.getFont().getSize() + 6));
61 @SuppressWarnings(
"unchecked")
63 private
void initComponents() {
65 domainNameLabel =
new javax.swing.JLabel();
66 sampleImageLabel =
new javax.swing.JLabel();
67 numberOfImagesLabel =
new javax.swing.JLabel();
68 activityLabel =
new javax.swing.JLabel();
69 pagesLabel =
new javax.swing.JLabel();
70 filesDownloadedLabel =
new javax.swing.JLabel();
71 totalVisitsLabel =
new javax.swing.JLabel();
72 domainNotabilityLabel =
new javax.swing.JLabel();
73 categoryLabel =
new javax.swing.JLabel();
74 knownAccountTypesLabel =
new javax.swing.JLabel();
76 setBorder(javax.swing.BorderFactory.createEtchedBorder());
78 sampleImageLabel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
79 sampleImageLabel.setIconTextGap(0);
80 sampleImageLabel.setMaximumSize(
new java.awt.Dimension(100, 100));
81 sampleImageLabel.setMinimumSize(
new java.awt.Dimension(100, 100));
82 sampleImageLabel.setPreferredSize(
new java.awt.Dimension(100, 100));
84 org.openide.awt.Mnemonics.setLocalizedText(pagesLabel,
org.openide.util.NbBundle.getMessage(DomainSummaryPanel.class,
"DomainSummaryPanel.pagesLabel.text"));
86 org.openide.awt.Mnemonics.setLocalizedText(filesDownloadedLabel,
org.openide.util.NbBundle.getMessage(DomainSummaryPanel.class,
"DomainSummaryPanel.filesDownloadedLabel.text"));
88 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
89 this.setLayout(layout);
90 layout.setHorizontalGroup(
91 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
92 .addGroup(layout.createSequentialGroup()
94 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
95 .addComponent(domainNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
96 .addComponent(pagesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
97 .addGroup(layout.createSequentialGroup()
98 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING,
false)
99 .addComponent(totalVisitsLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
100 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING,
false)
101 .addComponent(filesDownloadedLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
102 .addComponent(activityLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
103 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
104 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
105 .addComponent(domainNotabilityLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 295, Short.MAX_VALUE)
106 .addComponent(categoryLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
107 .addComponent(knownAccountTypesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
109 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
110 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING,
false)
111 .addComponent(numberOfImagesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
112 .addComponent(sampleImageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
116 layout.linkSize(javax.swing.SwingConstants.HORIZONTAL,
new java.awt.Component[] {activityLabel, filesDownloadedLabel});
118 layout.setVerticalGroup(
119 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
120 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
122 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
123 .addGroup(layout.createSequentialGroup()
124 .addComponent(numberOfImagesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE)
125 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
126 .addComponent(sampleImageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
127 .addGroup(layout.createSequentialGroup()
128 .addComponent(domainNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)
129 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, 15, Short.MAX_VALUE)
130 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
131 .addComponent(activityLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 15, javax.swing.GroupLayout.PREFERRED_SIZE)
132 .addComponent(domainNotabilityLabel, javax.swing.GroupLayout.Alignment.TRAILING))
133 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
134 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING,
false)
135 .addComponent(filesDownloadedLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 14, Short.MAX_VALUE)
136 .addComponent(categoryLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
138 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING,
false)
139 .addComponent(totalVisitsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 14, Short.MAX_VALUE)
140 .addComponent(knownAccountTypesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
141 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
142 .addComponent(pagesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 15, javax.swing.GroupLayout.PREFERRED_SIZE)
147 layout.linkSize(javax.swing.SwingConstants.VERTICAL,
new java.awt.Component[] {domainNotabilityLabel, totalVisitsLabel});
149 layout.linkSize(javax.swing.SwingConstants.VERTICAL,
new java.awt.Component[] {activityLabel, filesDownloadedLabel});
155 private javax.swing.JLabel activityLabel;
156 private javax.swing.JLabel categoryLabel;
157 private javax.swing.JLabel domainNameLabel;
158 private javax.swing.JLabel domainNotabilityLabel;
159 private javax.swing.JLabel filesDownloadedLabel;
160 private javax.swing.JLabel knownAccountTypesLabel;
161 private javax.swing.JLabel numberOfImagesLabel;
162 private javax.swing.JLabel pagesLabel;
163 private javax.swing.JLabel sampleImageLabel;
164 private javax.swing.JLabel totalVisitsLabel;
167 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
168 @NbBundle.Messages({
"# {0} - startDate",
170 "DomainSummaryPanel.activity.text=Activity: {0} to {1}",
171 "DomainSummaryPanel.pages.text=Page views in final 60 days: ",
172 "DomainSummaryPanel.totalPages.text=Total page views: ",
173 "DomainSummaryPanel.downloads.text=Files downloaded: ",
174 "DomainSummaryPanel.notability.text=Previously tagged as notable: ",
175 "DomainSummaryPanel.userRole.text=Account type: ",
176 "DomainSummaryPanel.category.text=Categories: ",
177 "DomainSummaryPanel.loadingImages.text=Loading thumbnail...",
178 "DomainSummaryPanel.no.text=No",
179 "DomainSummaryPanel.yes.text=Yes"})
181 public Component getListCellRendererComponent(JList<? extends DomainWrapper> list, DomainWrapper value,
int index,
boolean isSelected,
boolean cellHasFocus) {
182 domainNameLabel.setText(value.getResultDomain().getDomain());
183 TimeZone timeZone = TimeZoneUtils.getTimeZone();
184 String startDate = formatDate(value.getResultDomain().getActivityStart(), timeZone);
185 String endDate = formatDate(value.getResultDomain().getActivityEnd(), timeZone);
186 String notability = Bundle.DomainSummaryPanel_notability_text();
187 if (value.getResultDomain().getPreviouslyNotableInCR() == SearchData.PreviouslyNotable.PREVIOUSLY_NOTABLE) {
188 notability += Bundle.DomainSummaryPanel_yes_text();
190 notability += Bundle.DomainSummaryPanel_no_text();
192 domainNotabilityLabel.setText(notability);
193 Set<String> webCategories =
new HashSet<>();
194 webCategories.addAll(value.getResultDomain().getWebCategories());
195 categoryLabel.setText(Bundle.DomainSummaryPanel_category_text() + String.join(
",", webCategories));
196 activityLabel.setText(Bundle.DomainSummaryPanel_activity_text(startDate, endDate));
197 totalVisitsLabel.setText(Bundle.DomainSummaryPanel_totalPages_text() + value.getResultDomain().getTotalPageViews());
198 pagesLabel.setText(Bundle.DomainSummaryPanel_pages_text() + value.getResultDomain().getPageViewsInLast60Days());
199 filesDownloadedLabel.setText(Bundle.DomainSummaryPanel_downloads_text() + value.getResultDomain().getFilesDownloaded());
200 knownAccountTypesLabel.setText(Bundle.DomainSummaryPanel_userRole_text() + value.getResultDomain().getAccountTypes());
201 if (value.getThumbnail() == null) {
202 numberOfImagesLabel.setText(Bundle.DomainSummaryPanel_loadingImages_text());
203 sampleImageLabel.setIcon(null);
205 numberOfImagesLabel.setText(null);
206 sampleImageLabel.setIcon(
new ImageIcon(value.getThumbnail()));
208 setBackground(isSelected ? SELECTION_COLOR : list.getBackground());
220 private String formatDate(
long epochSeconds, TimeZone timeZone) {
221 Instant epochSecondsAsInstant = Instant.ofEpochSecond(epochSeconds);
222 ZonedDateTime dateTime = ZonedDateTime.ofInstant(epochSecondsAsInstant, timeZone.toZoneId());
223 MonthAbbreviation currentCutOffMonth = MonthAbbreviation.fromMonthValue(dateTime.getMonthValue());
224 return String.format(
"%s %02d %04d",
225 currentCutOffMonth.toString(),
226 dateTime.getDayOfMonth(), dateTime.getYear());
229 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
231 public String getToolTipText(MouseEvent event) {
234 Point point =
event.getPoint();
235 for (Component comp : getComponents()) {
236 if (DiscoveryUiUtils.isPointOnIcon(comp, point)) {
237 String toolTip = ((JComponent) comp).getToolTipText();
238 if (toolTip == null || toolTip.isEmpty()) {