0

I'm trying to get a thread to run for a swing application on button click, but the value isn't updating. It supposed to grab the computer name I'm searching, but in order for the value to update I have to launch a new instance of the GUI. I created a thread, but for some reason it's not working. Any help is appreciated.

(t.start is at end of code block)

searchComputerButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
              Thread t = new Thread("my non EDT thread") {
                    public void run() {
                        //my work
                        testLabel.setText(CN);
                    }

                };

            String line;
            BufferedWriter bw = null;
            BufferedWriter writer = null;
            try {
                writer = new BufferedWriter(new FileWriter(tempFile));
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            // String lineToRemove = "OU=Workstations";

            String s = null;

            Process p = null;
            /*
             * try { // p = Runtime.getRuntime().exec(
             * "cmd /c start c:\\computerQuery.bat computerName"); } catch
             * (IOException e1) { // TODO Auto-generated catch block
             * e1.printStackTrace(); }
             */
            try {

                p = Runtime.getRuntime().exec("c:\\computerQuery.bat");

            } catch (IOException e1) {

                // TODO Auto-generated catch block

                e1.printStackTrace();

            }
            StringBuffer sbuffer = new StringBuffer();
            BufferedReader in = new BufferedReader(new InputStreamReader(p
                    .getInputStream()));

            try {

                while ((line = in.readLine()) != null) {

                    System.out.println(line);

                    // textArea.append(line);

                    String dn = "CN=FDCD111304,OU=Workstations,OU=SIM,OU=Accounts,DC=FL,DC=NET";
                    LdapName ldapName = new LdapName(dn);
                    String commonName = (String) ldapName.getRdn(
                            ldapName.size() - 1).getValue();

                }
                ComputerQuery.sendParam();

            } catch (IOException e1) {

                // TODO Auto-generated catch block

                e1.printStackTrace();

            } catch (InvalidNameException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } finally

            {
                try {
                    fw.close();

                }

                catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }

            try {

                in.close();

            } catch (IOException e1) {

                // TODO Auto-generated catch block

                e1.printStackTrace();

            }

            ComputerQuery.sendParam();
            t.start();
        }
    });

UPDATE

private void threadStart() {
          SwingUtilities.invokeLater(new Runnable() {
            public void run() {

              testLabel.setText(CN);
            }
          });

And I put the method here

JButton searchComputerButton = new JButton("Search");
        searchComputerButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                threadStart();
                String line;
user6680
  • 79
  • 6
  • 34
  • 78
  • 1
    All GUI updates should be done on the EDT. – Andrew Thompson Jul 04 '15 at 13:45
  • I've heard this before, but I don't really understand it. Is there any chance you can give me a working example of what I should be doing? – user6680 Jul 04 '15 at 13:52
  • 1
    *"Is there any chance you can give me a working example.."* Is there any chance you can realize that SO is not a code generation machine, and actually invest some effort on your own? As it happens, I have an example around these parts that uses a Swing `Timer` to periodically establish a `SwingWorker` and perform a long running task repeatedly. Search and you might find it. – Andrew Thompson Jul 04 '15 at 14:18

1 Answers1

1

Be aware of the Swing Thread https://docs.oracle.com/javase/tutorial/uiswin/concurrency/

Have a look here: http://www.javamex.com/tutorials/threads/invokelater.shtml

You must enqueue your JLabel update method invocation using the Method SwingUtilities.invokeLater(???). Following example does it

Further more i think that is has something to do with the .batch file invocations. Have a look here: How do I run a batch file from my Java Application? Runnable task = new UpdateJob("Query: " + i); SwingUtilities.invokeLater(task);


To make it more understandable.

Swing manages all draw-Operations, within one Thread. It provides a queue. If you call a method from outside of that queue the behaviour is completely unpredictable.. NullPointer... RuntimeExc.... But if you call SwingUtilities.invokeLater(...) your method will be enqueued into the Swing-Queue and invoked as soon as possible!

UPDATE due to comment:

check your mainthread (GUI) check your threads. when a sub-thread (e.g a ActionListener) want to call JLabel::setText it has to use the method SwingUtils::InvokeLater("...");

That means invokeLater() has to be call within all threads which not directly belong to the main threads.

UPDATE due to Question

In my oppinion you current't code doesn't need SwingUtilities.invok.. at all. Did you change the Code assigned to you your question.

Community
  • 1
  • 1
Diversity
  • 1,890
  • 13
  • 20
  • I updated my code based using invokelater, but it still won't update. Can you tell me what I'm doing wrong. See updated code above – user6680 Jul 04 '15 at 14:22
  • I think the problem is the Runtime.getRuntime(... invocation. So the SwingUtililties.invokerLater has to be made outside of that function, – Diversity Jul 04 '15 at 14:24
  • I think the update is not the reall source of your problem! – Diversity Jul 04 '15 at 14:29
  • Where is the thread, which you initlalize outside from your application? – Diversity Jul 04 '15 at 14:30
  • If you are referring to this Thread t = new Thread("my non EDT thread") { I removed it and tried the invoke later code. Here is the full class code updated http://pastebin.com/D25Tki2J Are you saying I should keep this here? Because I'm not calling the thread in the invoke later. Should I be? – user6680 Jul 04 '15 at 14:33
  • You have to call InvokeLater whenever you try to invoke a method of an object which was not directly created by the main thread or the thread Swing belongs to. That means InvokeLater has to be invoked by a method which not belongs to the main thread – Diversity Jul 04 '15 at 14:40
  • I created a method outside of the main method and put the method inside the jbutton click. See code updated above. But the value still doesn't update when I click the button. What am I missing? – user6680 Jul 04 '15 at 15:00