简体   繁体   English

使用可运行程序时,为什么Java SWT Gui应用程序的标签未更改?

[英]Why does the Label not change for my Java SWT Gui application when using a runnable?

So I am having a problem at the moment because the everything is working properly and just been experimenting with some code to create a easy system time and date setup. 因此,我现在遇到了一个问题,因为一切正常,并且正在尝试一些代码来创建简单的系统时间和日期设置。 I have one problem that I somehow can't seem to fix. 我有一个我似乎无法解决的问题。 So I have identified a label (not a JLabel) and when I try to run it via a runnable void it seems to error when I try to set the text to update the exact time of the system. 因此,我确定了一个标签(不是JLabel),当我尝试通过可运行的void运行它时,尝试设置文本以更新系统的确切时间时似乎出错了。 So example Time.setText(time); 因此示例Time.setText(time); time will be identified as a string but it simply errors and doesn't work. 时间将被识别为字符串,但是它只是错误并且无法正常工作。

import java.util.Calendar;
import java.util.GregorianCalendar;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;

public class HomeScreen {

protected Shell shell;
private Label Date;
private Label Time;
private Composite composite;


/**
 * Launch the application.
 * @param args
 */
public static void main(String[] args) {
            try {
                HomeScreen window = new HomeScreen();
                window.open();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

/**
 * Open the window.
 */
public void open() {
    Display display = Display.getDefault();
    createContents();
    shell.open();
    shell.layout();
    Date();
    Time();
    while (!shell.isDisposed()) {
        if (!display.readAndDispatch()) {
            display.sleep();
        }
    }
}

/**
 * Create contents of the window.
 */
protected void createContents() {
    shell = new Shell();
    shell.setSize(450, 300);
    shell.setText("Project Serenity");

    composite = new Composite(shell, SWT.NONE);
    composite.setBounds(0, 0, 470, 278);

    Time = new Label(composite, SWT.NONE);
    Time.setLocation(10, 192);
    Time.setSize(169, 31);
    Time.setText("Time");

    Date = new Label(composite, SWT.NONE);
    Date.setLocation(10, 217);
    Date.setSize(169, 38);
    Date.setText("Date");

}
public void Date() 
{
    Thread Date2 = new Thread()
    {
        @Override
        public void run()
        {   
            try {
                for(;;){
                    Calendar cal = new GregorianCalendar();
                    int day = cal.get(Calendar.DAY_OF_MONTH);
                    int month = cal.get(Calendar.MONTH);
                    int year = cal.get(Calendar.YEAR);
                    Time.setText(day + ", " + month + " " + year);          
                sleep(1000);
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    };
    Date2.start();
}
public void Time() 
{
    Thread Time2 = new Thread()
    {
        @Override
        public void run()
        {
            try {
                for(;;){
                Calendar cal = new GregorianCalendar();
                int second = cal.get(Calendar.SECOND);
                int minute = cal.get(Calendar.MINUTE);
                int hour = cal.get(Calendar.HOUR);
                int am_pm = cal.get(Calendar.AM_PM);
                sleep(1000);
                Time.setText(hour + ":" + minute + ":" + second + " " + am_pm);
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    };
    Time2.start();
}

} }

Thx Pixl Thx Pixl

All access to User Interface objects must be done in the User Interface thread. 对用户界面对象的所有访问都必须在用户界面线程中完成。 Attempting to access them in any other thread will throw an exception. 尝试在任何其他线程中访问它们将引发异常。

You can use the asyncExec method of Display to execute a Runnable in the UI thread. 您可以使用DisplayasyncExec方法在UI线程中执行Runnable So instead of just doing: 因此,不只是这样做:

Time.setText(day + ", " + month + " " + year);          

in your background thread do: 在您的后台线程中执行:

Display.getDefault().asyncExec(() -> Time.setText(day + ", " + month + " " + year));

The above is for Java 8, if you are using an older version of Java use: 上面是针对Java 8的,如果您使用的是Java的旧版本,请使用:

Display.getDefault().asyncExec(new Runnable() {
  @Override
  public void run {
    Time.setText(day + ", " + month + " " + year);          
  }
});

Note: Please learn to use the Java naming conventions - variables start with a lower case letter so Time should be time . 注意:请学习使用Java命名约定-变量以小写字母开头,因此Time应该是time

You also are not doing anything to stop your update threads when you exit the application. 退出应用程序时,您也没有做任何事情来停止更新线程。 Accessing controls once the main UI thread has stopped will give you an error. 一旦主UI线程停止访问控件,将给您一个错误。 You can test if the Time control has been disposed which will tell you that the application has stopped. 您可以测试是否已丢弃Time控件,该控件将告诉您应用程序已停止。

if (Time.isDisposed()) {
  // TODO exit the thread
}

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

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