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