How to add real-time date and time into a JFrame component e.g. "status bar"?
date, java, swing
Solution
I created a `JStatusBar` from many nested `JPanels`. I was surprised at how many `JPanels` it took to create a status bar.
`JPanels`. `JPanels` everywhere.
Here's the test GUI.
And here's the JStatusBar class. The status bar has a leftmost status update area. On the right, you can add as many status areas as you want, with a separator bar. The only limit is the width of the status bar.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JPanel;
public class JStatusBar extends JPanel {
private static final long serialVersionUID = 1L;
protected JPanel leftPanel;
protected JPanel rightPanel;
public JStatusBar() {
createPartControl();
}
protected void createPartControl() {
setLayout(new BorderLayout());
setPreferredSize(new Dimension(getWidth(), 23));
leftPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 5, 3));
leftPanel.setOpaque(false);
add(leftPanel, BorderLayout.WEST);
rightPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING, 5, 3));
rightPanel.setOpaque(false);
add(rightPanel, BorderLayout.EAST);
}
public void setLeftComponent(JComponent component) {
leftPanel.add(component);
}
public void addRightComponent(JComponent component) {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEADING, 5, 0));
panel.add(new SeparatorPanel(Color.GRAY, Color.WHITE));
panel.add(component);
rightPanel.add(panel);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int y = 0;
g.setColor(new Color(156, 154, 140));
g.drawLine(0, y, getWidth(), y);
y++;
g.setColor(new Color(196, 194, 183));
g.drawLine(0, y, getWidth(), y);
y++;
g.setColor(new Color(218, 215, 201));
g.drawLine(0, y, getWidth(), y);
y++;
g.setColor(new Color(233, 231, 217));
g.drawLine(0, y, getWidth(), y);
y = getHeight() - 3;
g.setColor(new Color(233, 232, 218));
g.drawLine(0, y, getWidth(), y);
y++;
g.setColor(new Color(233, 231, 216));
g.drawLine(0, y, getWidth(), y);
y++;
g.setColor(new Color(221, 221, 220));
g.drawLine(0, y, getWidth(), y);
}
}
The separator bar is yet another `JPanel`.
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class SeparatorPanel extends JPanel {
private static final long serialVersionUID = 1L;
protected Color leftColor;
protected Color rightColor;
public SeparatorPanel(Color leftColor, Color rightColor) {
this.leftColor = leftColor;
this.rightColor = rightColor;
setOpaque(false);
}
@Override
protected void paintComponent(Graphics g) {
g.setColor(leftColor);
g.drawLine(0, 0, 0, getHeight());
g.setColor(rightColor);
g.drawLine(1, 0, 1, getHeight());
}
}
And finally, the simulator class that shows you how to use the `JStatusBar`.
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class StatusBarSimulator implements Runnable {
protected TimerThread timerThread;
@Override
public void run() {
JFrame frame = new JFrame();
frame.setBounds(100, 200, 400, 200);
frame.setTitle("Status Bar Simulator");
Container contentPane = frame.getContentPane();
contentPane.setLayout(new BorderLayout());
JStatusBar statusBar = new JStatusBar();
JLabel leftLabel = new JLabel("Your application is running.");
statusBar.setLeftComponent(leftLabel);
final JLabel dateLabel = new JLabel();
dateLabel.setHorizontalAlignment(JLabel.CENTER);
statusBar.addRightComponent(dateLabel);
final JLabel timeLabel = new JLabel();
timeLabel.setHorizontalAlignment(JLabel.CENTER);
statusBar.addRightComponent(timeLabel);
contentPane.add(statusBar, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent event) {
exitProcedure();
}
});
timerThread = new TimerThread(dateLabel, timeLabel);
timerThread.start();
frame.setVisible(true);
}
public void exitProcedure() {
timerThread.setRunning(false);
System.exit(0);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new StatusBarSimulator());
}
public class TimerThread extends Thread {
protected boolean isRunning;
protected JLabel dateLabel;
protected JLabel timeLabel;
protected SimpleDateFormat dateFormat =
new SimpleDateFormat("EEE, d MMM yyyy");
protected SimpleDateFormat timeFormat =
new SimpleDateFormat("h:mm a");
public TimerThread(JLabel dateLabel, JLabel timeLabel) {
this.dateLabel = dateLabel;
this.timeLabel = timeLabel;
this.isRunning = true;
}
@Override
public void run() {
while (isRunning) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Calendar currentCalendar = Calendar.getInstance();
Date currentTime = currentCalendar.getTime();
dateLabel.setText(dateFormat.format(currentTime));
timeLabel.setText(timeFormat.format(currentTime));
}
});
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
}
}
}
public void setRunning(boolean isRunning) {
this.isRunning = isRunning;
}
}
}
Problem
Like the one we add into the corner of presentation slides. I already have SwingX library added and working, in case that could help with something.