简体   繁体   English

更新jlabel

[英]updating jlabel

I am having trouble updating a jlabel in a method. 我在更新方法中的jlabel时遇到问题。 here is my code: 这是我的代码:

    JLabel curStatus = new JLabel("");
JButton jbtnSubmit;

public static void main(String[] args) {
    test gui = new test();
    gui.startGUI();
    // gui.setCurStatus("testing!"); << seems to work here, 
    //but when i call it from another class, it doesn't want to run.
}

// Set up the GUI end for the user
public void startGUI() {
    // These are all essential GUI pieces
    new JTextArea("");
    final JFrame jfrm = new JFrame("my program");
    jfrm.setLayout(new FlowLayout());
    jfrm.setSize(300, 300);
    jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    jbtnSubmit = new JButton("Submit");

    jfrm.add(jbtnSubmit);
    jfrm.add(curStatus);
    jfrm.setVisible(true);
}

public void setCurStatus(String inCurStatus) {
    curStatus.setText(inCurStatus);
    curStatus.setVisible(true);
}

what is happening, is that the label, curStatus is not appearing. 正在发生的情况是未显示标签curStatus。 for example, here is a call: 例如,这是一个电话:

gui1.setCurStatus("Now running diagnostics... Please wait!");

Your problem appears to be one of misplaced references. 您的问题似乎是参考文献放错了位置之一。

Here is how you create your GUI: 这是创建GUI的方法:

  public static void main(String[] args) {
     test gui = new test();
     gui.startGUI();
     // gui.setCurStatus("testing!"); << seems to work here,
     // but when i call it from another class, it doesn't want to run.
  }

You create your "test" object (which should be named "Test" by the way to conform to Java naming conventions) inside of your main method. 您可以在主要方法中创建“测试”对象(应遵循Java命名约定的方式命名为“测试”)。 Since it is declared inside of main, this variable has scope only inside of main and is visible no where else. 由于在main内部声明了此变量,因此该变量仅在main内部具有作用域,在其他任何地方均不可见。

You then tell us that you are calling the method like so: 然后,您告诉我们您正在像这样调用该方法:

gui1.setCurStatus("Now running diagnostics... Please wait!");

The gui1 variable refers to a test class object but it likely refers to a different object than the test object that is being displayed since the original displayed test object is only refered to by a variable local to the main method. gui1变量引用测试类对象,但它可能引用的对象与正在显示的测试对象不同 ,因为原始显示的测试对象仅由main方法本地的变量引用。

To solve this, you must make sure to call setCurStatus on the currently displayed test object. 要解决此问题,必须确保在当前显示的测试对象上调用setCurStatus。 How to do this depends on the rest of your code, something you've refused to show us despite our requests for you to do so. 如何执行此操作取决于您的其余代码,尽管我们要求您这样做,但您拒绝向我们显示某些内容。

Edit : Based on your latest bit of posted code (which still won't compile for me since it is missing a method, createTasksFile() , my assumptions are correct, you are calling setCurStatus(...) on a gui object that is not the displayed one: 编辑 :根据最新发布的代码(由于缺少方法createTasksFile() ,它仍然不会为我编译createTasksFile() ,我的假设是正确的,您正在对gui对象调用setCurStatus(...)不是显示的一个:

  public static String[] runDiagnostics() throws IOException {

     gui gui1 = new gui(); // (A)
     gui1.setCurStatus("Now running diagnostics... Please wait!");

On line (A) you create a new gui object and call setCurStatus on it, but it is not the GUI object that is being displayed but a completely different and unrelated object. 在(A)行上,创建一个新的gui对象并在其上调用setCurStatus,但是显示的不是 GUI对象,而是一个完全不同且不相关的对象。 It's only relation is that it is an object of the same class as the one being displayed but that's it. 唯一的关系是,它是与所显示对象属于同一类的对象,仅此而已。 The solution is to get a reference to the displayed GUI and call this method on that object, and that object only. 解决方案是获取对显示的GUI的引用,然后在该对象(仅该对象)上调用此方法。

Also , Robin's assumptions are correct, in that even if you fix this, you're going to be stuck with a Swing concurrency issue. 同样 ,Robin的假设是正确的,因为即使您解决了这个问题,您也将陷入Swing并发问题。 The JLabel won't update because the Swing thread is trying to open a file: JLabel不会更新,因为Swing线程正在尝试打开文件:

  public static String[] runDiagnostics() throws IOException {

     gui gui1 = new gui();
     gui1.setCurStatus("Now running diagnostics... Please wait!");

     int i = 0;
     int errorsI = 0;
     File f = new File("tasks.txt");
     String[] errors = { "", "", "", "", "" };

     // try to create the file three times
     do {
        f.createNewFile();
        i++;
     } while (!f.exists() && i < 3);

So we're both right. 所以我们都是对的。 The solution to this is to open your file on a background thread, a SwingWorker would work nicely here. 解决方案是在后台线程上打开文件,SwingWorker在这里可以很好地工作。

Edit 2 编辑2
So to fix the reference problem, pass a reference of the gui into the runDiagnostics method using a gui parameter. 因此,要解决引用问题,请使用gui参数将gui的引用传递到runDiagnostics方法中。 Then call the setCurStatus method on this parameter. 然后,对此参数调用setCurStatus方法。 For example: 例如:

  public static String[] runDiagnostics(gui gui1) throws IOException {

     //!! gui gui1 = new gui(); // !! no longer needed
     gui1.setCurStatus("Now running diagnostics... Please wait!");

You would have to pass the GUI in when calling the method: 调用方法时,您必须传递GUI:

        //!! results = taskBckg.runDiagnostics();
        results = taskBckg.runDiagnostics(gui);

Also, please edit all your code so that it follows Java naming conventions. 另外,请编辑所有代码,使其遵循Java命名约定。 All class names should begin with a capital letter. 所有班级名称应以大写字母开头。 This makes it much easier for others to understand what your code is doing. 这使得其他人更容易理解您的代码在做什么。

I will have a guess as well based on the message you are trying to display, since the question lacks some essential information. 根据您要显示的消息,我也会有一个猜测,因为该问题缺少一些基本信息。 Based on the 基于

"Now running diagnostics... Please wait!" “现在正在运行诊断程序……请稍候!”

message, I will assume you are running diagnostics and trying to update the UI on the same thread. 消息,我假设您正在运行诊断程序并尝试在同一线程上更新UI。 The code you posted contains no obvious mistakes which would explain why your call 您发布的代码没有任何明显的错误,这些错误可以解释您为什么打电话

gui1.setCurStatus("Now running diagnostics... Please wait!");

would not update the label contents. 不会更新标签内容。

What you have to do is all explained in the Swing concurrency tutorial . 您必须做的全部在Swing并发教程中进行了说明。 The main point is that you update the UI on the Event dispatch thread , and you never perform heavy calculations on that thread since that will block the UI, leading to a terrible user experience. 要点是,您在Event派发线程上更新了UI,并且从未在该线程上执行过多的计算,因为这会阻塞UI,从而导致糟糕的用户体验。 Heavy calculations should be done on a worker thread, for example by using the SwingWorker class, and only the update of the UI (for example for reporting progress) should happen on the EDT. 应在工作线程上进行大量计算,例如使用SwingWorker类,并且仅应在EDT上进行UI更新(例如用于报告进度)。

With this information and links you should be able to find all relevant information. 使用此信息和链接,您应该能够找到所有相关信息。 Also on this site you will find multiple examples on how to use SwingWorker to perform background calculations and updating the UI, like for example my answer on a previous question 同样在此站点上,您将找到有关如何使用SwingWorker进行后台计算和更新UI的多个示例,例如我对上一个问题的回答

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

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