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.TimeZone;
28 import javax.swing.ImageIcon;
29 import javax.swing.JComponent;
30 import javax.swing.JList;
31 import javax.swing.ListCellRenderer;
32 import org.openide.util.NbBundle;
40 class DomainSummaryPanel
extends javax.swing.JPanel implements ListCellRenderer<DomainWrapper> {
42 private static final long serialVersionUID = 1L;
43 private static final Color SELECTION_COLOR =
new Color(0, 120, 215);
48 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
49 DomainSummaryPanel() {
51 domainNameLabel.setFont(domainNameLabel.getFont().deriveFont(domainNameLabel.getFont().getStyle(), domainNameLabel.getFont().getSize() + 6));
59 @SuppressWarnings(
"unchecked")
61 private
void initComponents() {
63 domainNameLabel =
new javax.swing.JLabel();
64 sampleImageLabel =
new javax.swing.JLabel();
65 numberOfImagesLabel =
new javax.swing.JLabel();
66 activityLabel =
new javax.swing.JLabel();
67 pagesLabel =
new javax.swing.JLabel();
68 filesDownloadedLabel =
new javax.swing.JLabel();
69 totalVisitsLabel =
new javax.swing.JLabel();
70 domainNotabilityLabel =
new javax.swing.JLabel();
71 categoryLabel =
new javax.swing.JLabel();
73 setBorder(javax.swing.BorderFactory.createEtchedBorder());
75 sampleImageLabel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
76 sampleImageLabel.setIconTextGap(0);
77 sampleImageLabel.setMaximumSize(
new java.awt.Dimension(100, 100));
78 sampleImageLabel.setMinimumSize(
new java.awt.Dimension(100, 100));
79 sampleImageLabel.setPreferredSize(
new java.awt.Dimension(100, 100));
81 org.openide.awt.Mnemonics.setLocalizedText(pagesLabel,
org.openide.util.NbBundle.getMessage(DomainSummaryPanel.class,
"DomainSummaryPanel.pagesLabel.text"));
83 org.openide.awt.Mnemonics.setLocalizedText(filesDownloadedLabel,
org.openide.util.NbBundle.getMessage(DomainSummaryPanel.class,
"DomainSummaryPanel.filesDownloadedLabel.text"));
85 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
86 this.setLayout(layout);
87 layout.setHorizontalGroup(
88 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
89 .addGroup(layout.createSequentialGroup()
91 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
92 .addComponent(domainNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
93 .addGroup(layout.createSequentialGroup()
94 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING,
false)
95 .addComponent(filesDownloadedLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
96 .addComponent(activityLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
97 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
98 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
99 .addComponent(domainNotabilityLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
100 .addComponent(categoryLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
102 .addComponent(pagesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
103 .addComponent(totalVisitsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
104 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
105 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING,
false)
106 .addComponent(numberOfImagesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
107 .addComponent(sampleImageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
111 layout.linkSize(javax.swing.SwingConstants.HORIZONTAL,
new java.awt.Component[] {activityLabel, filesDownloadedLabel});
113 layout.setVerticalGroup(
114 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
115 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
117 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
118 .addGroup(layout.createSequentialGroup()
119 .addComponent(numberOfImagesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE)
120 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 8, Short.MAX_VALUE)
121 .addComponent(sampleImageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
122 .addGroup(layout.createSequentialGroup()
123 .addComponent(domainNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)
124 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
125 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
126 .addComponent(activityLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 15, javax.swing.GroupLayout.PREFERRED_SIZE)
127 .addComponent(domainNotabilityLabel, javax.swing.GroupLayout.Alignment.TRAILING))
128 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
129 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING,
false)
130 .addComponent(filesDownloadedLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 14, Short.MAX_VALUE)
131 .addComponent(categoryLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
132 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
133 .addComponent(totalVisitsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 14, Short.MAX_VALUE)
134 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
135 .addComponent(pagesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 15, javax.swing.GroupLayout.PREFERRED_SIZE)
140 layout.linkSize(javax.swing.SwingConstants.VERTICAL,
new java.awt.Component[] {domainNotabilityLabel, totalVisitsLabel});
142 layout.linkSize(javax.swing.SwingConstants.VERTICAL,
new java.awt.Component[] {activityLabel, filesDownloadedLabel});
148 private javax.swing.JLabel activityLabel;
149 private javax.swing.JLabel categoryLabel;
150 private javax.swing.JLabel domainNameLabel;
151 private javax.swing.JLabel domainNotabilityLabel;
152 private javax.swing.JLabel filesDownloadedLabel;
153 private javax.swing.JLabel numberOfImagesLabel;
154 private javax.swing.JLabel pagesLabel;
155 private javax.swing.JLabel sampleImageLabel;
156 private javax.swing.JLabel totalVisitsLabel;
159 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
160 @NbBundle.Messages({
"# {0} - startDate",
162 "DomainSummaryPanel.activity.text=Activity: {0} to {1}",
163 "DomainSummaryPanel.pages.text=Page views in past 60 days: ",
164 "DomainSummaryPanel.totalPages.text=Total page views: ",
165 "DomainSummaryPanel.downloads.text=Files downloaded: ",
166 "DomainSummaryPanel.notability.text=Previously tagged as notable: ",
167 "DomainSummaryPanel.unknown.text=User role: Unknown",
168 "DomainSummaryPanel.known.text=User role: Known account type(s)",
169 "DomainSummaryPanel.category.text=Category: ",
170 "DomainSummaryPanel.loadingImages.text=Loading thumbnail...",
171 "DomainSummaryPanel.no.text=No",
172 "DomainSummaryPanel.yes.text=Yes"})
174 public Component getListCellRendererComponent(JList<? extends DomainWrapper> list, DomainWrapper value,
int index,
boolean isSelected,
boolean cellHasFocus) {
175 domainNameLabel.setText(value.getResultDomain().getDomain());
176 TimeZone timeZone = ContentUtils.getTimeZone(value.getResultDomain().getDataSource());
177 String startDate = formatDate(value.getResultDomain().getActivityStart(), timeZone);
178 String endDate = formatDate(value.getResultDomain().getActivityEnd(), timeZone);
179 String notability = Bundle.DomainSummaryPanel_notability_text();
180 if (value.getResultDomain().getPreviouslyNotableInCR() == SearchData.PreviouslyNotable.PREVIOUSLY_NOTABLE) {
181 notability += Bundle.DomainSummaryPanel_yes_text();
183 notability += Bundle.DomainSummaryPanel_no_text();
185 domainNotabilityLabel.setText(notability);
186 categoryLabel.setText(Bundle.DomainSummaryPanel_category_text() + value.getResultDomain().getWebCategory());
187 activityLabel.setText(Bundle.DomainSummaryPanel_activity_text(startDate, endDate));
188 totalVisitsLabel.setText(Bundle.DomainSummaryPanel_totalPages_text() + value.getResultDomain().getTotalPageViews());
189 pagesLabel.setText(Bundle.DomainSummaryPanel_pages_text() + value.getResultDomain().getPageViewsInLast60Days());
190 filesDownloadedLabel.setText(Bundle.DomainSummaryPanel_downloads_text() + value.getResultDomain().getFilesDownloaded());
191 if (value.getThumbnail() == null) {
192 numberOfImagesLabel.setText(Bundle.DomainSummaryPanel_loadingImages_text());
193 sampleImageLabel.setIcon(null);
195 numberOfImagesLabel.setText(null);
196 sampleImageLabel.setIcon(
new ImageIcon(value.getThumbnail()));
198 setBackground(isSelected ? SELECTION_COLOR : list.getBackground());
210 private String formatDate(
long epochSeconds, TimeZone timeZone) {
211 Instant epochSecondsAsInstant = Instant.ofEpochSecond(epochSeconds);
212 ZonedDateTime dateTime = ZonedDateTime.ofInstant(epochSecondsAsInstant, timeZone.toZoneId());
213 MonthAbbreviation currentCutOffMonth = MonthAbbreviation.fromMonthValue(dateTime.getMonthValue());
214 return String.format(
"%s %02d %04d",
215 currentCutOffMonth.toString(),
216 dateTime.getDayOfMonth(), dateTime.getYear());
219 @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
221 public String getToolTipText(MouseEvent event) {
224 Point point =
event.getPoint();
225 for (Component comp : getComponents()) {
226 if (DiscoveryUiUtils.isPointOnIcon(comp, point)) {
227 String toolTip = ((JComponent) comp).getToolTipText();
228 if (toolTip == null || toolTip.isEmpty()) {