2

I have a swing application that creates a number of panels based on a user entered list of names, with a panel for each name that the user enters. At the bottom of the application I have a JPanel, with a button to close the current panel and a JLabel that displays the current number of open panels.

I initialize the label like so

String[] usernames = input("Usernames"); int totalTabs = usernames.length; JLabel lblRemaining = new JLabel("Remaining: " + totalTabs); 

I have then added an action listener to the close button and have attempted to use a SwingWorker to update the label but it just doesn't seem to update.

close.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { unlookup(username); SwingWorker<String, String> updateLabel = new SwingWorker<String, String>(){ @Override protected String doInBackground() throws Exception { String tabTotal = Integer.toString(desktop.getTabCount()); return tabTotal; } @Override protected void done(){ try { lblRemaining.setText(get()); System.out.println(get()); } catch (Exception ignore) { } } }; updateLabel.execute(); } }); 

The println is showing the correct figure in the console so I know it must be something to do with the GUI not updating but I just can't seem to figure it out!

I'm fairly new to Java and Swing so hopefully it's something fairly obvious that I'm doing wrong!

Thanks :)

4
  • What's the point of using a SwingWorker? It is illegal to access any Swing class, including "desktop" which is a JTabbedPane, in any thread other than the Event Dispatch Thread, so using it in doInBackground leads to undefined results. Your ActionListener already runs on the EDT. "lblRemaining.setText(Integer.toString(desktop.getTabCount()));" is all you should need in actionPerformed. (Apart from "unlookup(username)", which is cryptic and likely has nothing to do with the question.) Commented Apr 14, 2016 at 15:45
  • @laszlok, the doInBackground() method is not accessing the GUI. It is returning a String value which is then accessed in the done() method, which does execute on the EDT. So the SwingWorker code does look correct. Agreed the SwingWorder may not be necessary as it doesn't look like it is doing any long running task which would freeze the GUI so all the code could be in the ActionListener itself. Commented Apr 14, 2016 at 16:02
  • @camickr, please read docs.oracle.com/javase/tutorial/uiswing/concurrency/… - the desktop.getTabCount() method is a Swing component method that is not marked thread safe and therefore invoking it on a thread other than the EDT, as the tutorial says, "risks thread interference or memory consistency errors". That it doesn't involve painting (if that's what you mean by "not accessing the GUI") is immaterial. Commented Apr 14, 2016 at 20:38
  • @laszlok, good point. I was looking at the posted code which was just getting the value from the length of an array containing the names. But I guess the method could be invoked on a JTabbedPane. Having said that if there is a random problem it will only be with the value returned. It will not prevent the label from being updated. Commented Apr 15, 2016 at 1:01

1 Answer 1

2

The println is showing the correct figure in the console

Then this means you have a wrong reference to the JLabel.

So you probably 1) created an instance variable by that name and then 2) created a local variable with the same name and added that label to the frame. The Swing worker will only have access to the instance variable.

Get rid of the local variable.

if you need more help then post a proper SSCCE that demonstrates the problem. A SSCCE should be included with ALL questions. We can't tell what the problem really is based on a couple of lines of code.

Sign up to request clarification or add additional context in comments.

2 Comments

Unfortunately this is part of a much larger application that was created by someone else (much of which I can't share) but I've updated my post to show as much code as possible.
Not interested in "as much code as possible". We need a SSCCE. So you create a simple app that demonstrates what you are doing. Create a frame with the label and a button. When you click the button you start the SwingWorker. So the whole SSCCE will be about 20-30 lines of code. Get that simple piece of code working, then compare the working code to your real application. We don't have access to your real application so we can't guess what you might be doing wrong. There is no magic to updating a label. If you have the proper reference and the code is executed the label will update itself.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.