4

就像我们添加到演示幻灯片一角的那个。

我已经添加并运行了 SwingX 库,以防万一。

4

4 回答 4

8

基本上,您想使用一个JLabel来显示日期/时间,一个javax.swing.Timer设置为定期间隔来更新标签和一个DateFormat实例来格式化日期值......

在此处输入图像描述

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()));
        }
    }
}

此示例使用半秒的时间间隔。主要原因是当我们设置初始延迟时,我不会费心去计算我们离下一秒还有多远。这确保我们始终保持最新

下一个问题是问“为什么?” 这种设置相对昂贵,计时器每半秒触发一次(以捕捉任何边缘情况)并更新屏幕,而大多数操作系统实际上已经在屏幕上显示了日期/时间......恕我直言

于 2012-11-13T21:06:41.010 回答
6

JStatusBar从许多嵌套的JPanels. JPanels我很惊讶创建一个状态栏需要多少时间。

JPanels. JPanels到处。

这是测试 GUI。

在此处输入图像描述

这是 JStatusBar 类。状态栏有一个最左边的状态更新区域。在右侧,您可以使用分隔栏添加任意数量的状态区域。唯一的限制是状态栏的宽度。

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);
    }

}

分隔栏是另一个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());
    }

}

最后,向您展示如何使用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;
        }

    }

}
于 2012-11-14T14:04:49.897 回答
3

在 JFrame 的组件层次结构中的适当位置添加标签组件(可能是 JToolBar?)。

然后创建一个每秒触发一次的计时器,并为其添加一个 ActionListener 以使用当前时间更新标签的文本。

请参阅使用 SwingWorker 和 Timer 在标签上显示时间的已接受答案?

于 2012-11-13T19:30:22.837 回答
2

创建一个SimpleDateFormat可以帮助您格式化当前日期的对象。添加一个JLabel到您的JFrame. 在一个单独的线程中,创建一个持续读取当前日期的循环,将其格式化为 aString并将其传递给JLabelEDT 中的 the。在再次更新标签之前,让单独的线程休眠一秒钟或更短时间。

于 2012-11-13T19:28:09.193 回答