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 * A general purpose status bar for all Frame windows
43 *
44 * @author Paul Smith <psmith@apache.org>
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 pausedLabel = new JLabel("", SwingConstants.CENTER);
52 private final JLabel lineSelectionLabel = new JLabel("", SwingConstants.CENTER);
53 private final JLabel eventCountLabel = new JLabel("", SwingConstants.CENTER);
54 private final JLabel receivedEventLabel = new JLabel("0.0", SwingConstants.CENTER);
55 private final JLabel receivedConnectionlabel = new JLabel("", SwingConstants.CENTER);
56 private volatile long lastReceivedConnection = System.currentTimeMillis();
57 private final Thread connectionThread;
58 private final Icon pausedIcon = new ImageIcon(ChainsawIcons.PAUSE);
59 private final Icon netConnectIcon =
60 new ImageIcon(ChainsawIcons.ANIM_NET_CONNECT);
61 private final NumberFormat nf = NumberFormat.getNumberInstance();
62 private final Border statusBarComponentBorder =
63 BorderFactory.createLineBorder(statusMsg.getBackground().darker());
64
65 public ChainsawStatusBar() {
66 setLayout(new GridBagLayout());
67
68 nf.setMaximumFractionDigits(1);
69 nf.setMinimumFractionDigits(1);
70 nf.setGroupingUsed(false);
71
72 JPanel statusMsgPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 2));
73
74 statusMsgPanel.add(statusMsg);
75 statusMsgPanel.setBorder(statusBarComponentBorder);
76
77 pausedLabel.setBorder(statusBarComponentBorder);
78 pausedLabel.setMinimumSize(
79 new Dimension(pausedIcon.getIconWidth(), pausedIcon.getIconHeight()));
80
81 pausedLabel.setToolTipText(
82 "Shows whether the current Log panel is paused or not");
83
84 receivedEventLabel.setBorder(statusBarComponentBorder);
85 receivedEventLabel.setToolTipText(
86 "Indicates whether Chainsaw is receiving events, and how fast it is processing them");
87 receivedEventLabel.setMinimumSize(
88 new Dimension(
89 receivedEventLabel.getFontMetrics(receivedEventLabel.getFont())
90 .stringWidth("9999.9/s") + 5,
91 (int) receivedEventLabel.getPreferredSize().getHeight()));
92
93 eventCountLabel.setBorder(statusBarComponentBorder);
94 eventCountLabel.setToolTipText("<# viewable events>:<# total events>");
95 eventCountLabel.setMinimumSize(
96 new Dimension(
97 eventCountLabel.getFontMetrics(eventCountLabel.getFont())
98 .stringWidth("99999:99999") + 5,
99 (int) eventCountLabel.getPreferredSize().getHeight()));
100
101 receivedConnectionlabel.setBorder(statusBarComponentBorder);
102 receivedConnectionlabel.setToolTipText(
103 "Indicates whether Chainsaw has received a remote connection");
104 receivedConnectionlabel.setMinimumSize(
105 new Dimension(
106 netConnectIcon.getIconWidth() + 4,
107 (int) receivedConnectionlabel.getPreferredSize().getHeight()));
108
109 lineSelectionLabel.setBorder(statusBarComponentBorder);
110 lineSelectionLabel.setMinimumSize(
111 new Dimension(
112 lineSelectionLabel.getFontMetrics(lineSelectionLabel.getFont())
113 .stringWidth("999999"),
114 (int) lineSelectionLabel.getPreferredSize().getHeight()));
115 lineSelectionLabel.setToolTipText(
116 "The current line # selected");
117
118 JComponent[] toFix =
119 new JComponent[] {
120 eventCountLabel,
121 receivedConnectionlabel, lineSelectionLabel, receivedEventLabel,
122 pausedLabel
123 };
124
125 for (int i = 0; i < toFix.length; i++) {
126 toFix[i].setPreferredSize(toFix[i].getMinimumSize());
127 toFix[i].setMaximumSize(toFix[i].getMinimumSize());
128 }
129
130 statusMsg.setMinimumSize(pausedLabel.getPreferredSize());
131 statusMsg.setToolTipText("Shows messages from Chainsaw");
132
133 GridBagConstraints c = new GridBagConstraints();
134 c.insets = new Insets(2, 2, 2, 2);
135 c.weightx = 1.0;
136 c.weighty = 1.0;
137 c.ipadx = 2;
138 c.ipady = 2;
139 c.gridx = 0;
140 c.gridy = 0;
141 c.fill = GridBagConstraints.BOTH;
142 c.anchor = GridBagConstraints.WEST;
143
144 add(statusMsgPanel, c);
145
146 c.weightx = 0.0;
147 c.weighty = 0.0;
148 c.gridx = 1;
149 add(receivedConnectionlabel, c);
150
151 c.weightx = 0.0;
152 c.weighty = 0.0;
153 c.gridx = 2;
154 add(lineSelectionLabel, c);
155
156 c.weightx = 0.0;
157 c.weighty = 0.0;
158 c.gridx = 3;
159 add(eventCountLabel, c);
160
161 c.weightx = 0.0;
162 c.weighty = 0.0;
163 c.gridx = 4;
164 add(receivedEventLabel, c);
165
166 c.weightx = 0.0;
167 c.weighty = 0.0;
168 c.gridx = 5;
169
170 add(pausedLabel, c);
171
172 connectionThread =
173 new Thread(
174 new Runnable() {
175 public void run() {
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 new Runnable() {
192 public void run() {
193 receivedConnectionlabel.setIcon(theIcon);
194 }
195 });
196 }
197 }
198 });
199 connectionThread.start();
200 }
201
202 void setDataRate(final double dataRate) {
203 SwingUtilities.invokeLater(
204 new Runnable() {
205 public void run() {
206 receivedEventLabel.setText(nf.format(dataRate) + "/s");
207 }
208 });
209 }
210
211 /***
212 * Indicates a new connection has been established between
213 * Chainsaw and some remote host
214 * @param source
215 */
216 void remoteConnectionReceived(String source) {
217 lastReceivedConnection = System.currentTimeMillis();
218 MessageCenter.getInstance().getLogger().info("Connection received from " + source);
219 connectionThread.interrupt();
220
221
222 }
223
224 /***
225 * Called when the paused state of the LogPanel has been updated
226 * @param isPaused
227 */
228 void setPaused(final boolean isPaused) {
229 Runnable runnable =
230 new Runnable() {
231 public void run() {
232 pausedLabel.setIcon(isPaused ? pausedIcon : null);
233 pausedLabel.setToolTipText(
234 isPaused ? "This Log panel is currently paused"
235 : "This Log panel is not paused");
236 }
237 };
238
239 SwingUtilities.invokeLater(runnable);
240 }
241
242 void setSelectedLine(
243 final int selectedLine, final int lineCount, final int total) {
244 SwingUtilities.invokeLater(
245 new Runnable() {
246 public void run() {
247 lineSelectionLabel.setText(
248 selectedLine+"");
249 eventCountLabel.setText(lineCount + ":" + total);
250 }
251 });
252 }
253
254 void setNothingSelected() {
255 SwingUtilities.invokeLater(
256 new Runnable() {
257 public void run() {
258 lineSelectionLabel.setText("");
259 }
260 });
261 }
262
263 void clear() {
264 setMessage(DEFAULT_MSG);
265 setNothingSelected();
266 SwingUtilities.invokeLater(
267 new Runnable() {
268 public void run() {
269 receivedEventLabel.setText("");
270 }
271 });
272 }
273
274 public void setMessage(final String msg) {
275 SwingUtilities.invokeLater(
276 new Runnable() {
277 public void run() {
278 statusMsg.setText(" " + msg);
279 }
280 });
281 }
282 }