问题描述
代码的目的是使时间和毫秒始终运行。当按钮按下时,此时绿色面板上会出现当前时间。我截图了。
我的应用程序必须如下所示:
有什么帮助吗?
我的按钮没有将时间发送到 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));
msLabel.setBounds(0,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,100);
JPanel msPanel = new JPanel(); // milliseconds panel.
msPanel.setLayout(null);
msPanel.setBackground(new Color(38,7,15,255));
msPanel.setBounds(540,140,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));
timetoGreenLabel.setBounds(0,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);
}
}
解决方法
这是我想出的图形用户界面。
当我创建 Swing GUI 或大多数其他 Java 应用程序时,我使用 model / view / controller 模式。简而言之,这种使用 Swing 的模式意味着:
-
视图(Swing 组件)将从模型中读取。
-
视图不会改变模型中的任何内容。
-
控制器将更新模型并更新视图。
我使用一个或多个普通 Java getter / setter 类创建了一个应用程序模型。我使用 Swing 组件和 Swing layout managers 创建了一个视图。最后,我使用 Swing listeners 创建了一个或多个控制器。控制器似乎是您最难以理解的地方。
以下是我希望您从我将发布的代码中删除的最重要的几点。
-
始终通过调用
SwingUtilities
invokeLater
方法来启动 Swing 应用程序。此方法可确保您的 Swing 组件将在 Event Dispatch Thread 上创建和执行。 -
摆脱静态代码并将您的代码分组到 Java 方法中。您可以在我的代码中看到,唯一的静态方法是启动应用程序的
main
方法。我的主要方法只有一行代码。应用程序的其余部分使用方法和类。 -
不要使用绝对定位(
setBounds
)。使用Swing layout managers。您可以在我的代码中看到 Swing 布局管理器的示例。 -
为一个 JFrame 创建多个 JPanel。在单独的方法中创建每个主 JPanel。这允许您在应用程序中组合 Swing 布局管理器。
-
在这个特定的应用程序中,控制器非常简单,我将它们设为匿名类。我创建了两个匿名类,一个用于更新左侧的时间面板,另一个用于运行控制面板中的两个时钟。控制器应该始终是与您的模型和视图分开的类。
下次您发布问题时,我不想在 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));
JPanel innerPanel = new JPanel(new BorderLayout());
innerPanel.setBackground(model.getBackgroundTextColor());
innerPanel.setBorder(BorderFactory.createEmptyBorder(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));
JPanel innerPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(0,5);
gbc.gridx = 0;
gbc.gridy = 0;
JPanel timePanel = new JPanel(new BorderLayout());
timePanel.setBorder(BorderFactory.createEmptyBorder(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,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();
}
}
}