如何将实时时间添加到 JPanel 以及何时将按钮按下时间添加到其他 JPanel?

How can I add live time to a JPanel and when button pressed time to other JPanel?

代码的目的是时间和毫秒将始终 运行。当按下按钮时,那一刻的当前时间将出现在绿色面板上。我截图了。

我的应用程序必须如下所示:

有什么帮助吗?

我的按钮没有将时间发送到 greenPanel。

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.*;

public class TimePanel {

    public static void main(String[] args) {
        
        Font timeFont = new Font("Helvetica", Font.BOLD, 50);
        Font msFont = new Font("Helvetica", Font.PLAIN, 72);
        
        Date dateNow = new Date(); // current date and time
        
        SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss"); // current time
        SimpleDateFormat msFormat = new SimpleDateFormat(".S"); // milliseconds
        SimpleDateFormat sendToGreenFormat = new SimpleDateFormat("HH:mm:ss.S");
        
        String timeString = timeFormat.format(dateNow);
        String msString = msFormat.format(dateNow);
        
        JLabel timeLabel = new JLabel(timeString, JLabel.CENTER);
        timeLabel.setFont(timeFont);
        timeLabel.setForeground(new Color(242, 242, 242));
        timeLabel.setBounds(0, 25, 240, 50);
        
        JLabel msLabel = new JLabel(msString, JLabel.CENTER);
        msLabel.setFont(msFont);
        msLabel.setForeground(new Color(242, 242, 242));
        msLabel.setBounds(0, 25, 240, 65);
        
        JButton sendButton = new JButton("Send to Green");
        sendButton.setBounds(585, 260, 150, 25);
        
        JFrame frame = new JFrame("Time Panel");
        frame.setLayout(null);
        
        JPanel greenPanel = new JPanel();
        greenPanel.setLayout(new GridLayout(10,1));
        greenPanel.setBackground(new Color(18, 64, 55, 255));
        greenPanel.setBounds(20, 20, 500, 500);
        
        JPanel timePanel = new JPanel();
        timePanel.setLayout(null);
        timePanel.setBackground(new Color(89, 21, 33, 255));
        timePanel.setBounds(540, 20, 240, 100);
        
        JPanel msPanel = new JPanel(); // milliseconds panel.
        msPanel.setLayout(null);
        msPanel.setBackground(new Color(38, 7, 15, 255));
        msPanel.setBounds(540, 140, 240, 100);
        
        sendButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                
                String timeToGreenString = sendToGreenFormat.format(dateNow);
                
                JLabel timeToGreenLabel = new JLabel(timeToGreenString);
                timeToGreenLabel.setFont(timeFont);
                timeToGreenLabel.setForeground(new Color(242, 242, 242));
                timeToGreenLabel.setBounds(0, 25, 240, 50);
                
                greenPanel.add(timeToGreenLabel);
            }
        });
                
        timePanel.add(timeLabel);
        msPanel.add(msLabel);
        
        frame.add(greenPanel);
        frame.add(timePanel);
        frame.add(msPanel);
        frame.add(sendButton);
        
        frame.setSize(800, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

    }

}

这是我想出的 GUI。

当我创建 Swing GUI 或大多数其他 Java 应用程序时,我使用 model / view / controller 模式。简而言之,这种使用 Swing 的模式意味着:

  1. 视图(Swing 组件)将从模型中读取。

  2. 视图不会更改模型中的任何内容。

  3. 控制器将更新模型并更新视图。

我使用一个或多个普通 Java getter / setter 类 创建了一个应用程序模型。我使用 Swing 组件和 Swing layout managers. Finally, I create one or more controllers by using Swing listeners 创建了一个视图。控制器是你似乎最难理解的地方。

以下是我希望您从我将 post.

的代码中吸取的最重要的几点
  1. 始终通过调用 SwingUtilities invokeLater 方法来启动 Swing 应用程序。此方法确保您的 Swing 组件将在 Event Dispatch Thread.

    上创建和执行
  2. 摆脱静态代码并将您的代码分组到 Java 方法中。您可以在我的代码中看到,唯一的静态方法是启动应用程序的 main 方法。我的主要方法只有一行代码。应用程序的其余部分使用方法和 类.

  3. 不要使用绝对定位 (setBounds)。使用 Swing layout managers。您可以在我的代码中看到 Swing 布局管理器的示例。

  4. 为一个 JFrame 创建多个 JPanel。在单独的方法中创建每个主 JPanel。这允许您在应用程序中组合 Swing 布局管理器。

  5. 在这个特定的应用程序中,控制器非常简单,我将它们设为匿名 类。我创建了两个匿名类,一个用来更新左边的时间面板,一个用来运行控制面板里的两个时钟。控制器应始终与您的模型和视图分开 类。

下次你 post 提问时,我不想在 main 方法中看到你所有的代码。我不想看到绝对定位。我希望您花时间学习我在此回答中概述的概念,否则您将永远无法创建复杂的 Swing 应用程序。最后,你应该通过 Oracle 的完整 Swing tutorial。您可以跳过 Netbeans 部分。

这是代码。我没有费心将左侧时间面板中的时间居中。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class TimePanel implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new TimePanel());
    }
    
    private JLabel timeLabel;
    private JLabel msLabel;
    
    private JTextArea textArea;
    
    private TimeModel model;
    
    public TimePanel() {
        this.model = new TimeModel();
    }
    
    @Override
    public void run() {
        JFrame frame = new JFrame("Time Panel");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(createTextPanel(), BorderLayout.CENTER);
        frame.add(createControlPanel(), BorderLayout.AFTER_LINE_ENDS);
        
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        
        Timer timer = new Timer(50, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                updateControlPanel();
            }
        });
        timer.start();
    }   
    
    private JPanel createTextPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        JPanel innerPanel = new JPanel(new BorderLayout());
        innerPanel.setBackground(model.getBackgroundTextColor());
        innerPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        
        textArea = new JTextArea(8, 10);
        textArea.setBackground(model.getBackgroundTextColor());
        textArea.setForeground(model.getForegroundColor());
        textArea.setFont(model.getTimeFont());
        innerPanel.add(textArea, BorderLayout.CENTER);
        
        JScrollPane scrollPane = new JScrollPane(innerPanel);
        panel.add(scrollPane);
        return panel;
    }   

    private JPanel createControlPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        JPanel innerPanel = new JPanel(new GridBagLayout());
        
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(0, 5, 10, 5);
        gbc.gridx = 0;
        gbc.gridy = 0;
        
        JPanel timePanel = new JPanel(new BorderLayout());
        timePanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
        timePanel.setBackground(model.getBackgroundControlColor());
        
        timeLabel = new JLabel(model.getTime());
        timeLabel.setBackground(model.getBackgroundControlColor());
        timeLabel.setFont(model.getTimeFont());
        timeLabel.setForeground(model.getForegroundColor());
        timePanel.add(timeLabel, BorderLayout.CENTER);

        JPanel msPanel = new JPanel();
        msPanel.setBackground(model.getBackgroundControlColor());
        
        msLabel = new JLabel(model.getMSTime());
        msLabel.setBackground(model.getBackgroundControlColor());
        msLabel.setFont(model.getMSFont());
        msLabel.setForeground(model.getForegroundColor());
        msPanel.add(msLabel);
        
        Dimension t = timePanel.getPreferredSize();
        Dimension m = msPanel.getPreferredSize();
        int width = Math.max(t.width, m.width);
        int height = Math.max(t.height, m.height);
        Dimension a = new Dimension(width, height);
        
        timePanel.setPreferredSize(a);
        msPanel.setPreferredSize(a);
        
        innerPanel.add(timePanel, gbc);
        
        gbc.gridy++;
        innerPanel.add(msPanel, gbc);

        gbc.gridy++;
        JButton sendButton = new JButton("Send to Green");
        sendButton.setFont(model.getButtonFont());
        innerPanel.add(sendButton, gbc);
        
        sendButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                textArea.append(model.getDisplayTime());
                textArea.append(System.lineSeparator());
            }
        });
        
        panel.add(innerPanel);
                    
        return panel;
    }
    
    public void updateControlPanel() {
        timeLabel.setText(model.getTime());
        msLabel.setText(model.getMSTime());
    }
    
    public class TimeModel {
        
        private final Color foregroundColor;
        private final Color backgroundTextColor;
        private final Color backgroundControlColor;
        
        private final DateTimeFormatter timeFormat;
        private final DateTimeFormatter msFormat;
        private final DateTimeFormatter displayFormat;
        
        private final Font timeFont;
        private final Font msFont;
        private final Font buttonFont;
        
        public TimeModel() {
            this.foregroundColor = new Color(242, 242, 242);
            this.backgroundTextColor = new Color(18, 64, 55);
            this.backgroundControlColor = new Color(89, 21, 33);
            
            this.timeFormat = DateTimeFormatter.ofPattern("HH:mm:ss");
            this.msFormat = DateTimeFormatter.ofPattern(".SSS");
            this.displayFormat = DateTimeFormatter.ofPattern("HH:mm:ss.SSS");
            
            String fontName = "Helvetica";
            this.msFont = new Font(fontName, Font.PLAIN, 72);
            this.timeFont = new Font(fontName, Font.BOLD, 48);
            this.buttonFont = new Font(fontName, Font.PLAIN, 16);   
        }
        
        public String getTime() {
            return timeFormat.format(getCurrentTime());
        }
        
        public String getMSTime() {
            return msFormat.format(getCurrentTime());
        }
        
        public String getDisplayTime() {
            return displayFormat.format(getCurrentTime());
        }
        
        public Color getForegroundColor() {
            return foregroundColor;
        }

        public Color getBackgroundTextColor() {
            return backgroundTextColor;
        }

        public Color getBackgroundControlColor() {
            return backgroundControlColor;
        }

        public Font getTimeFont() {
            return timeFont;
        }

        public Font getMSFont() {
            return msFont;
        }

        public Font getButtonFont() {
            return buttonFont;
        }

        private LocalDateTime getCurrentTime() {
            return LocalDateTime.now();
        }
        
    }

}