我使用 Java Swing 创建了一个世界时钟。 时钟本身并不是很复杂。 我做这个迷你项目的原因是看看我是否可以自定义时区。
这是带有默认时区的 GUI。
这是显示世界各地各个时区的JDialog
。
您可以根据需要选择任意多个时区,但我建议 10 个时区是大多数当前显示的实际限制。
Thw JDialog
允许您将时区从主列表移动到显示列表,以及从显示列表移动到主列表。 如果您想重新开始,您可以清除所有显示的时区。 您必须至少选择一个时区来显示,
主要列表仍按字母顺序排列。 显示列表按照您选择的顺序显示时区。 按住Ctrl
键的同时单击鼠标左键可以选择要在列表中添加或删除的多个时区。
此代码不会将您选择的时区保存到属性文件中。 如果您想将此世界时钟用作可执行 JAR 文件,则可以添加此内容。
Oracle 有一个有用的教程:使用 Swing 创建 GUI。 跳过使用 NetBeans IDE 学习 Swing 部分。
当我创建 Swing 应用程序时,我使用模型-视图-控制器 (MVC) 模式。 这种模式使我能够将我的关注点分开,一次专注于 Swing 应用程序的一个部分。 模式名称意味着您首先创建模型,然后创建视图,最后创建控制器。 这是一个迭代过程,因此视图或控制器的更改可能会导致模型发生更改。
对于 Swing 应用程序,MVC 模式意味着:
视图从模型中读取信息。
视图不会更新模型。
控制器更新模型并重新绘制/重新验证视图。
通常没有一个控制器可以“统治所有”。 每个Action
或ActionListener
独立运行并更新其模型和视图的部分。
我创建了一个模型类,即WorldClockModel
类。 此类包含ZonedDateTime
当前日期和时间、所有时区的java.util.List
以及要显示的时区的java.util.List
。 我选择了ZonedDateTime
这样我只需存储当前时间一次。 我可以将ZoneId
传递给ZonedDateTime
来获取任何时区的当前时间。
所有时区的List
来自ZoneId
getAvailableZoneIds
方法。 我过滤掉与城市无关的时区。
我创建了两个视图类: WorldClockGUI
类和DisplayPanel
类。 WorldClockGUI
类创建JFrame
和主JPanel
。 主JPanel
由DisplayPanel
实例组成,每个实例对应一个要显示的时区。
JFrame
有一个默认的BorderLayout
,因此我将主JPanel
放置在BorderLayout
的中心。 主JPanel
使用GridLayout
将DisplayPanel
实例放置在两个均匀间隔的列中。
JDialog
显示所有时区的列表、显示时区的列表,并控制JButtons
将时区从一个列表移动到另一个列表。我使用两个DefaultListModels
,每个列表一个。
TimezoneDialogListener
类将显示列表从显示DefaultListModel
复制回应用程序模型类并更新视图。
Swing Timer
每 20 秒更新一次当前时间。 对于显示小时和分钟的时钟来说,这已经足够准确了。
JDialog
上的其余JButtons
会触发匿名ActionListeners
来执行其任务。 侦听器很短,因此将它们设置为匿名类是有意义的。