How to add real-time date and time to a JFrame component, for example. "status bar"?

Like the one we add to the corner of the presentation slides.

I already have a SwingX library added and working in case something helps.

+4
source share
4 answers

I created a JStatusBar from a variety of nested JPanels . I was surprised how many JPanels it took to create the status bar.

JPanels JPanels everywhere.

Here's a test graphical interface.

enter image description here

And here is the JStatusBar class. The status bar has the leftmost status update area. On the right, you can add as many status areas as you want, with a dividing bar. The only limitation 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 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, a simulator class that shows you how to use 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; } } } 
+5
source

Basically, you want to use JLabel to display the date / time, and set javax.swing.Timer to a regular interval to update the label and the DateFormat instance to format the date value ...

enter image description here

 public class PlaySchoolClock { public static void main(String[] args) { new PlaySchoolClock(); } public PlaySchoolClock() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException ex) { } catch (InstantiationException ex) { } catch (IllegalAccessException ex) { } catch (UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new ClockPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class ClockPane extends JPanel { private JLabel clock; public ClockPane() { setLayout(new BorderLayout()); clock = new JLabel(); clock.setHorizontalAlignment(JLabel.CENTER); clock.setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD, 48f)); tickTock(); add(clock); Timer timer = new Timer(500, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { tickTock(); } }); timer.setRepeats(true); timer.setCoalesce(true); timer.setInitialDelay(0); timer.start(); } public void tickTock() { clock.setText(DateFormat.getDateTimeInstance().format(new Date())); } } } 

This example uses a time interval of half a second. The main reason for this is that I have no difficulty calculating how far we get from the next second when we set the initial delay. This ensures that we are always updated.

The next question is to ask why. This type of setup is relatively expensive when the timer starts every half second (to catch any boundary cases) and update the screen when most OSs actually have a date and time on the screen ... IMHO

+8
source

Add the shortcut component to the appropriate place in your hirerarchy JFrame component (perhaps a JToolBar?).

Then create a timer that fires once per second, and add an ActionListener to it, which updates the label text using Current Time.

See the accepted answer in Using SwingWorker and Timer to display time on a shortcut?

+3
source

Create a SimpleDateFormat object that helps you format the current date. Add JLabel to your JFrame . In a separate thread, create a loop that continues to read the current date, format it to String and pass it to JLabel in EDT. Make a separate thread for one second or less before updating the tag again.

+2
source

Source: https://habr.com/ru/post/1445833/


All Articles