有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

swing如何为JavaBean属性设置新值(日期)?

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

当我尝试在一个新项目中使用组件(watch)时,它默认显示系统的日期(我将bean编程为以这种方式工作)。然而,我想让开发者(在本例中是我自己)可以编辑属性“hora”来设置不同的日期。因此,如果开发人员在新项目中插入组件,则文本必须是系统的时间。但是,如果开发人员编辑属性“hora”并设置一个新日期,例如再设置一个小时,则显示的文本应为新值,在本例中为system date + 1 hour

我当前的代码部分工作:

Use of the bean in a new project with the date changed.

在上图中:

  • 在右边,房产“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);
    }
}

谢谢你的帮助,对不起我的英语


共 (1) 个答案

  1. # 1 楼答案

    JavaBeans作为小部件组件

    (I am learning Java and Java beans)

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

    爪哇。时间

    it shows by default the date of the system (I programmed the bean to work in this way).

    您使用的是几年前被现代java取代的糟糕的日期时间类。JSR 310中定义的时间

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

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

    时区

    获取当前时间包括获取当前时刻。这需要一个时区。对于任何给定的时刻,一天中的日期和时间在全球各地因时区而不同

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

    Continent/Region的格式指定一个proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。千万不要使用2-4个字母的缩写,例如ESTIST,因为它们不是真正的时区,没有标准化,甚至不是唯一的(!)

    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对象作为小部件类上的成员字段,或者小部件可以访问的其他地方

    So if the developer insert the component in a new project, the text must be the time of the system.

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

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

    如果要本地化表示LocalTime对象值的显示文本,请使用DateTimeFormatter。指定一个^{}来确定人类语言和文化规范used in localizing。并指定一个^{}来表示长度或缩写

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

    搜索以了解更多信息。这已经在堆栈溢出上讨论过很多次了

    动态更新

    你剩下的代码让我有点困惑。你似乎想将时钟更新到当前时刻,不断刷新。然而,您也允许用户更改时间。这是矛盾的

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

    另一个问题:定期更新。您正在使用TimerTimerTask,这两个类已被Executor framework取代。特别是在Swing中,应该使用javax.swing.Timer类(参见Tutorial),而不是^{}

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

    示例应用程序

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

    Screenshot of localized time-of-day with a field to enter a time zone.

    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。时间

    {a13}框架内置于Java8及更高版本中。这些类取代了legacy日期时间类,如^{}^{}、&^{}

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

    目前位于maintenance modeJoda-Time项目建议迁移到java.time

    你可以交换java。时间对象直接与数据库连接。使用符合JDBC 4.2或更高版本的JDBC driver。不需要字符串,也不需要java.sql.*

    在哪里可以获得java。时间课

    {a36}项目扩展了java。有额外课程的时间。这个项目是java未来可能增加的一个试验场。时间你可以在这里找到一些有用的类,比如^{}^{}^{}more