0

I am having trouble updating a jlabel in a method. 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. for example, here is a call:

gui1.setCurStatus("Now running diagnostics... Please wait!");
mKorbel
  • 109,525
  • 20
  • 134
  • 319
droidus
  • 613
  • 5
  • 14
  • 25

2 Answers2

2

Your problem appears to be one of misplaced references.

Here is how you create your 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. Since it is declared inside of main, this variable has scope only inside of main and is visible no where else.

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.

To solve this, you must make sure to call setCurStatus on the currently displayed test object. 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:

  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. 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.

Also, Robin's assumptions are correct, in that even if you fix this, you're going to be stuck with a Swing concurrency issue. The JLabel won't update because the Swing thread is trying to open a file:

  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.

Edit 2
So to fix the reference problem, pass a reference of the gui into the runDiagnostics method using a gui parameter. Then call the setCurStatus method on this parameter. 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:

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

Also, please edit all your code so that it follows Java naming conventions. All class names should begin with a capital letter. This makes it much easier for others to understand what your code is doing.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • alright. here is my code: http://pastebin.com/rBhG4p4z and http://pastebin.com/QCXXt6p1 – droidus Jan 28 '12 at 17:10
  • As much as I hate to use pastebin code, I'll use it occasionally if it's complete. Your posted code has **no main method anywhere**. How can anyone test it? It's not runnable, it's meaningless. Please read up and use [sscce](http://sscce.org) techniques. – Hovercraft Full Of Eels Jan 28 '12 at 17:27
  • for testing purposes, just run diagnostics. that's all that the one code snippet is meant to do. i changed it to the main method. – droidus Jan 28 '12 at 17:34
  • @droidus: OK, for testing purposes I've run your code, and I don't even see a GUI. This is getting most frustrating if you can't post code that we can run and test for ourselves. **Edit**: Now I've added the `gui1.startGUI();` line to the test class, and I see the GUI and also see the `"Now running diagnostics... Please wait!"` JLabel. Again read my link on how to create an [SSCCE](http://sscce.org). You need to put some effort into asking proper questions if we have any chance of helping you. – Hovercraft Full Of Eels Jan 28 '12 at 17:37
  • @droidus: it still won't compile, but see edit to my answer above. – Hovercraft Full Of Eels Jan 28 '12 at 18:13
  • alright, well i will look into this, and i thank you for your time. – droidus Jan 28 '12 at 18:17
  • +1 for your answer as well, and certainly for all the effort you put into answering this question and reading pastebin-code – Robin Jan 28 '12 at 19:25
  • 1
    @droidus: when you resort to pastebin posts, it means that your code is too large to post in the forum. Since we're all volunteers you shouldn't ask us to be reading gobs of code unrelated to your problem at hand. Instead since you're asking free effort from us, **you** should first be putting in the effort to isolate your problem and then create an [sscce](http://sscce.org) and then posting it here. Again, please read the link as it will explain all. – Hovercraft Full Of Eels Jan 28 '12 at 19:28
1

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. 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. 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. 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.

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

Community
  • 1
  • 1
Robin
  • 36,233
  • 5
  • 47
  • 99