繁体   English   中英

如何为 Java bean 属性设置新值(日期)?

[英]How to set a new value (Date) for a Java bean property?

我正在编写一个 bean(我正在学习 Java 和 Java bean),它是一个扩展JLabel的数字手表。 显示的文本将是hh:mm:ss

当我尝试在新项目中使用组件(手表)时,它默认显示系统的日期(我将 bean 编程为以这种方式工作)。 但是我想允许开发人员(在这种情况下我自己)可以编辑属性“hora”来设置不同的日期。 所以如果开发者在新项目中插入组件,文字一定是系统的时间。 但是,如果开发人员编辑属性“hora”并设置新日期,例如多一小时,则显示的文本应为新值,在本例中为system date + 1 hour

我当前的代码部分工作:

在更改日期的新项目中使用 bean。

在上一张图片中:

  • 在右侧,属性“hora”的值是:系统日期 + 1 小时。
  • 在左侧,NetBeans 的预览视图显示了正确的时间(系统时间 + 1 小时)。 分钟的差异是因为手表工作并每秒更改其时间。 屏幕截图是在编辑属性值后几分钟制作的。
  • 在中心,项目正在运行并显示错误的日期(系统日期)。
  • 请忽略按钮和微调器,它们仅用于测试目的。

我怎样才能改变这种行为? 那么当我运行项目时,显示的时间与“hora”属性中选择的时间相同?

相关代码:

public class Reloj extends JLabel implements Serializable {
    private Date hora = new Date();
    private SimpleDateFormat formatoHora;
    private boolean doceHoras = false;

    public Reloj() {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
             public void run() {
                setHora(new Date((getHora().getTime())+1000));

            }
        }, 0, 1000);
    }

    public Date getHora() {
        return this.hora;
    }

    public void setHora(Date hora) {
        this.hora = hora;
        this.setText(this.getFormatoHora().format(hora));
        this.repaint();
    }

    public SimpleDateFormat getFormatoHora() {
        if (this.isDoceHoras()) {
            this.formatoHora = new SimpleDateFormat("hh:mm:ss a");
        } else {
            this.formatoHora = new SimpleDateFormat("HH:mm:ss");
        }
        return this.formatoHora;
    }

    public void setDoceHoras(boolean doceHoras) {
        this.doceHoras = doceHoras;
        this.setHora(hora);
    }
}

感谢您的帮助,并为我的英语感到抱歉。

JavaBeans 作为小部件组件

(我正在学习 Java 和 Java bean)

据我所知,在可视化设计工具中使用JavaBeans作为组件从未流行起来。 我很惊讶NetBeans仍然支持它。 我建议您不要在 JavaBean 技术的这方面花费太多时间或精力。

时间

它默认显示系统的日期(我将 bean 编程为以这种方式工作)。

您正在使用多年前被 JSR 310 中定义的现代java.time类取代的糟糕的日期时间类。

永远不要使用DateSimpleDateFormat 如果您必须与尚未更新为java.time 的旧代码进行互操作,请在java.time 中执行所有逻辑,最后使用添加到旧类的新方法进行转换。

对于只有时间的值,没有日期和时区,请使用LocalTime

时区

获取当前时间涉及获取当前时刻。 这需要一个时区。 对于任何给定时刻,日期和时间在全球各地因时区而异。

如果未指定时区,JVM 会隐式应用其当前默认时区。 该默认值可能会在运行时随时更改(!),因此您的结果可能会有所不同。 最好将您想要/预期的时区明确指定为参数。 如果您想使用 JVM 的当前默认时区,请通过调用ZoneId.systemDefault()明确您的意图。 如果关键,请与您的用户确认该区域。

Continent/Region格式指定正确的时区名称,例如America/MontrealAfrica/CasablancaPacific/Auckland 永远不要使用ESTIST等 2-4 个字母的缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalTime lt = LocalTime.now( z ) ;

如果您想使用 JVM 的当前默认时区,请明确要求并作为参数传递。 如果省略,代码读起来会变得模棱两可,因为我们不确定您是否打算使用默认值,或者您是否像许多程序员一样没有意识到这个问题。

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.
LocalTime lt = LocalTime.now( z ) ;

如果此内容至关重要,则应与用户确认时区。 系统默认值可能不符合用户的意图,特别是考虑到移动设备和笔记本电脑很容易在时区之间移动。 在这种情况下,您应该将ZoneId对象作为小部件类或小部件可访问的其他位置的成员字段。

所以如果开发者在新项目中插入组件,文字一定是系统的时间。

您可以解析用户输入的文本。 如果采用标准ISO 8601格式,HH:MM:SS 与 24 小时制,您无需费心指定格式模式。 java.time类在解析/生成文本时默认使用标准格式。

String input = "23:01:23" ;
LocalTime lt = LocalTime.parse( input ) ;

如果要本地化表示LocalTime对象值的显示文本,请使用DateTimeFormatter 指定Locale以确定本地化中使用的人类语言和文化规范。 并指定一个FormatStyle来说明多长时间或缩写。

Locale locale = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedTime( FormatStyle.MEDIUM ) ;

搜索以了解更多信息。 这已经在 Stack Overflow 上多次讨论过。

动态更新

你的其余代码对我来说有点混乱。 您似乎想将时钟更新到当前时刻,不断刷新。 然而,您还允许用户更改时间。 这是矛盾的。

我怀疑您真正想要的是两个一起工作的部分:时间显示和时区。 如果您试图让用户改变时钟显示以匹配他们的时区,您应该通过让用户指定时区来实现(如上所述)。 换句话说,时钟偏移应该是结果,而不是原因。 用户操作您的时区属性,时钟会自动更改其时间,如该时区所代表地区的人们使用的偏移量所示。

另一个问题:定期更新。 您正在使用TimerTimerTask ,这两个类已被Executor 框架取代。 特别是在 Swing 中,您应该使用javax.swing.Timer类(参见教程)而不是java.util.Timer

强制性警告:切勿从后台线程访问、更新或操作 Swing 小部件。 仅在用户界面线程中执行此操作。

示例应用

这是一个快速而肮脏的示例 Swing 应用程序。 这不是 JavaBean 组件。 而且我不太记得 Swing。 但这可能会对您有所帮助。 您可以看到更改时区 ( ZoneId ) 如何更新时间,同时将时间移动到该时区中当前有效的偏移量。

带有用于输入时区的字段的本地化时间的屏幕截图。

package org.example;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.DateTimeException;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;

/**
 * Hello world!
 */
public class App extends JFrame
{
    ZoneId zoneId;
    LocalTime localTime;
    JTextField timeZone;
    JLabel displayTime;
    DateTimeFormatter formatter;


    public App ( )
    {
        initUI();
    }

    private void initUI ( )
    {

        setTitle( "Simple example" );
        setSize( 300 , 200 );
        setLocationRelativeTo( null );
        setDefaultCloseOperation( EXIT_ON_CLOSE );

        // Widgets
        this.zoneId = ZoneId.systemDefault();
        this.timeZone = new JTextField( this.zoneId.getId() , 20 );
        this.localTime = LocalTime.now( this.zoneId );
        Locale locale = Locale.CANADA_FRENCH;
        this.formatter = DateTimeFormatter.ofLocalizedTime( FormatStyle.MEDIUM );
        this.displayTime = new JLabel( this.localTime.format( this.formatter ) );

        this.timeZone.addActionListener( new ActionListener()
        {
            @Override
            public void actionPerformed ( ActionEvent event )
            {
                System.out.println( "The entered text is: " + timeZone.getText() );
                try
                {
                    zoneId = ZoneId.of( timeZone.getText() );
                    localTime = LocalTime.now( zoneId );
                    String output = LocalTime.now( zoneId ).format( formatter );
                    displayTime.setText( output );
                }
                catch ( DateTimeException e )
                {
                    System.out.println( "BAD INPUT - The user gave an invalid time zone: " + timeZone );
                }
            }
        } );

        // Arrange
        JPanel panel = new JPanel();
        panel.add( this.displayTime );
        panel.add( this.timeZone );
        this.add( panel );
    }

    public static void main ( String[] args )
    {

        EventQueue.invokeLater( ( ) -> {

            var ex = new App();
            ex.setVisible( true );
        } );
    }
}

关于java.time

java.time框架内置于 Java 8 及更高版本中。 这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar ,和SimpleDateFormat

要了解更多信息,请参阅Oracle 教程 并在 Stack Overflow 上搜索许多示例和解释。 规范是JSR 310

现在处于维护模式Joda-Time项目建议迁移到java.time类。

您可以直接与您的数据库交换java.time对象。 使用符合JDBC 4.2或更高版本的JDBC 驱动程序 不需要字符串,不需要java.sql.*类。

从哪里获得 java.time 类?

ThreeTen-Extra项目用额外的类扩展了 java.time。 该项目是未来可能添加到 java.time 的试验场。 您可以在这里找到一些有用的类,比如IntervalYearWeekYearQuarter ,和更多

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM