1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.log4j.chainsaw;
19
20 import org.apache.log4j.chainsaw.icons.ChainsawIcons;
21 import org.apache.log4j.chainsaw.messages.MessageCenter;
22
23 import javax.swing.*;
24 import javax.swing.border.Border;
25 import java.awt.*;
26 import java.text.NumberFormat;
27
28
29
30
31
32
33
34 public class ChainsawStatusBar extends JPanel {
35 private static final int DELAY_PERIOD = 5000;
36 private static final String DEFAULT_MSG = "Welcome to Chainsaw v2!";
37 private final JLabel statusMsg = new JLabel(DEFAULT_MSG);
38 private final JLabel searchMatchLabel = new JLabel("", SwingConstants.CENTER);
39 private final JLabel pausedLabel = new JLabel("", SwingConstants.CENTER);
40 private final JLabel lineSelectionLabel = new JLabel("", SwingConstants.CENTER);
41 private final JLabel eventCountLabel = new JLabel("", SwingConstants.CENTER);
42 private final JLabel receivedEventLabel = new JLabel("", SwingConstants.CENTER);
43 private final JLabel receivedConnectionlabel = new JLabel("", SwingConstants.CENTER);
44 private volatile long lastReceivedConnection = System.currentTimeMillis();
45 private final Thread connectionThread;
46 private final Icon pausedIcon = new ImageIcon(ChainsawIcons.PAUSE);
47 private final Icon netConnectIcon =
48 new ImageIcon(ChainsawIcons.ANIM_NET_CONNECT);
49 private final NumberFormat nf = NumberFormat.getNumberInstance();
50 private final Border statusBarComponentBorder =
51 BorderFactory.createLineBorder(statusMsg.getBackground().darker());
52 private final LogUI logUI;
53
54 public ChainsawStatusBar(LogUI logUI) {
55 setLayout(new GridBagLayout());
56 this.logUI = logUI;
57 nf.setMaximumFractionDigits(0);
58 nf.setMinimumFractionDigits(0);
59 nf.setGroupingUsed(false);
60
61 JPanel statusMsgPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 2));
62
63 statusMsgPanel.add(statusMsg);
64 statusMsgPanel.setBorder(statusBarComponentBorder);
65
66 pausedLabel.setBorder(statusBarComponentBorder);
67 pausedLabel.setMinimumSize(
68 new Dimension(pausedIcon.getIconWidth(), pausedIcon.getIconHeight()));
69
70 pausedLabel.setToolTipText(
71 "Shows whether the current Log panel is paused or not");
72
73 receivedEventLabel.setBorder(statusBarComponentBorder);
74 receivedEventLabel.setToolTipText(
75 "Indicates whether Chainsaw is receiving events, and how fast it is processing them");
76 receivedEventLabel.setMinimumSize(
77 new Dimension(
78 receivedEventLabel.getFontMetrics(receivedEventLabel.getFont())
79 .stringWidth("99999999999.9/s") + 5,
80 (int) receivedEventLabel.getPreferredSize().getHeight()));
81
82 eventCountLabel.setBorder(statusBarComponentBorder);
83 eventCountLabel.setToolTipText("<# viewable events>:<# total events>");
84 eventCountLabel.setMinimumSize(
85 new Dimension(
86 eventCountLabel.getFontMetrics(eventCountLabel.getFont())
87 .stringWidth("Filtered/Total: 999999999999:999999999999") + 5,
88 (int) eventCountLabel.getPreferredSize().getHeight()));
89
90 searchMatchLabel.setBorder(statusBarComponentBorder);
91 searchMatchLabel.setToolTipText("<# viewable events>:<# total events>");
92 searchMatchLabel.setMinimumSize(
93 new Dimension(
94 searchMatchLabel.getFontMetrics(eventCountLabel.getFont()).stringWidth("Find matches: 999999999999") + 5,
95 (int) searchMatchLabel.getPreferredSize().getHeight()));
96
97 receivedConnectionlabel.setBorder(statusBarComponentBorder);
98 receivedConnectionlabel.setToolTipText(
99 "Indicates whether Chainsaw has received a remote connection");
100 receivedConnectionlabel.setMinimumSize(
101 new Dimension(
102 netConnectIcon.getIconWidth() + 4,
103 (int) receivedConnectionlabel.getPreferredSize().getHeight()));
104
105 lineSelectionLabel.setBorder(statusBarComponentBorder);
106 lineSelectionLabel.setMinimumSize(
107 new Dimension(
108 lineSelectionLabel.getFontMetrics(lineSelectionLabel.getFont())
109 .stringWidth("999999999"),
110 (int) lineSelectionLabel.getPreferredSize().getHeight()));
111 lineSelectionLabel.setToolTipText(
112 "The current line # selected");
113
114 JComponent[] toFix =
115 new JComponent[]{
116 searchMatchLabel, eventCountLabel,
117 receivedConnectionlabel, lineSelectionLabel, receivedEventLabel,
118 pausedLabel
119 };
120
121 for (JComponent aToFix : toFix) {
122 aToFix.setPreferredSize(aToFix.getMinimumSize());
123 aToFix.setMaximumSize(aToFix.getMinimumSize());
124 }
125
126 statusMsg.setMinimumSize(pausedLabel.getPreferredSize());
127 statusMsg.setToolTipText("Shows messages from Chainsaw");
128
129 GridBagConstraints c = new GridBagConstraints();
130 c.insets = new Insets(2, 2, 2, 2);
131 c.weightx = 1.0;
132 c.weighty = 1.0;
133 c.ipadx = 2;
134 c.ipady = 2;
135 c.gridx = 0;
136 c.gridy = 0;
137 c.fill = GridBagConstraints.BOTH;
138 c.anchor = GridBagConstraints.WEST;
139
140 add(statusMsgPanel, c);
141
142 c.weightx = 0.0;
143 c.weighty = 0.0;
144 c.gridx = 1;
145 add(receivedConnectionlabel, c);
146
147 c.weightx = 0.0;
148 c.weighty = 0.0;
149 c.gridx = 2;
150 add(lineSelectionLabel, c);
151
152 c.weightx = 0.0;
153 c.weighty = 0.0;
154 c.gridx = 3;
155 add(searchMatchLabel, c);
156
157 c.weightx = 0.0;
158 c.weighty = 0.0;
159 c.gridx = 4;
160 add(eventCountLabel, c);
161
162 c.weightx = 0.0;
163 c.weighty = 0.0;
164 c.gridx = 5;
165 add(receivedEventLabel, c);
166
167 c.weightx = 0.0;
168 c.weighty = 0.0;
169 c.gridx = 6;
170
171 add(pausedLabel, c);
172
173 connectionThread =
174 new Thread(
175 () -> {
176 while (true) {
177 try {
178 Thread.sleep(DELAY_PERIOD);
179 } catch (InterruptedException e) {
180 }
181
182 Icon icon = null;
183
184 if (
185 (System.currentTimeMillis() - lastReceivedConnection) < DELAY_PERIOD) {
186 icon = netConnectIcon;
187 }
188
189 final Icon theIcon = icon;
190 SwingUtilities.invokeLater(
191 () -> receivedConnectionlabel.setIcon(theIcon));
192 }
193 });
194 connectionThread.start();
195 }
196
197 void setDataRate(final double dataRate) {
198 SwingUtilities.invokeLater(
199 () -> receivedEventLabel.setText(nf.format(dataRate) + "/s"));
200 }
201
202
203
204
205
206
207
208 void remoteConnectionReceived(String source) {
209 lastReceivedConnection = System.currentTimeMillis();
210 MessageCenter.getInstance().getLogger().info("Connection received from " + source);
211 connectionThread.interrupt();
212
213
214 }
215
216
217
218
219
220
221
222 void setPaused(final boolean isPaused, String tabName) {
223 if (tabName.equals(logUI.getActiveTabName())) {
224 Runnable runnable =
225 () -> {
226 pausedLabel.setIcon(isPaused ? pausedIcon : null);
227 pausedLabel.setToolTipText(
228 isPaused ? "This Log panel is currently paused"
229 : "This Log panel is not paused");
230 };
231 SwingUtilities.invokeLater(runnable);
232 }
233 }
234
235 void setSelectedLine(
236 final int selectedLine, final int lineCount, final int total, String tabName) {
237 if (tabName.equals(logUI.getActiveTabName())) {
238 SwingUtilities.invokeLater(
239 () -> {
240 lineSelectionLabel.setText(selectedLine + "");
241 eventCountLabel.setText("Filtered/Total: " + lineCount + ":" + total);
242 });
243 }
244 }
245
246 void setSearchMatchCount(int searchMatchCount, String tabName) {
247 if (tabName.equals(logUI.getActiveTabName())) {
248 if (searchMatchCount == 0) {
249 searchMatchLabel.setText("");
250 } else {
251 searchMatchLabel.setText("Find matches: " + searchMatchCount);
252 }
253 }
254 }
255
256 void setNothingSelected() {
257 SwingUtilities.invokeLater(
258 () -> lineSelectionLabel.setText(""));
259 }
260
261 void clear() {
262 setMessage(DEFAULT_MSG);
263 setNothingSelected();
264 SwingUtilities.invokeLater(
265 () -> receivedEventLabel.setText(""));
266 }
267
268 public void setMessage(final String msg) {
269 SwingUtilities.invokeLater(
270 () -> statusMsg.setText(" " + msg));
271 }
272 }