2

I have been trying to fix my .setText crash issue, which occures when i press the num0 button randomly.

  • But it seems i can only resolve it by using new Thread(new Runnable() { __overwrite__swing__textfields___ }); but in that case i can not access my JTextField.

Therefore i have written a RunnableOutput class to send and apply but t hat also failing. Example:

RunnableOutput.java

package ui;

import java.awt.ComponentOrientation;
import javax.swing.*;

/**
 * JTextField - Wrapper for thread-safe 
 * 
 * @author root
 */
public class RunnableOutput implements Runnable {
  private JTextField outputArea;
  private String messageToAppend;

  // initialze outputArea and message
  public RunnableOutput(JTextField output, String message) {
    outputArea = output;
    messageToAppend = message;
  }

  @Override
  public void run() {
    outputArea.setText(messageToAppend);
  }

}

Menu.java:

public static JTextField nameTextField0 = new JTextField(20);
public void IPpanel(JPanel configPanel) { 

  JPanel Numlock = new JPanel(new GridLayout(0,12));
  JButton num0 = new JButton("0"); 
  num0.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent ae) {

      // Fails: 
      // was expecting this should fixed it but indeed still not
      SwingUtilities.invokeLater(
        new RunnableOutput(nameTextField0, "Unit test: 0"));       

      // Fails: 
      // wont work few times works but when randomly i press the 
      // button it fails
      // Same result with: SwingUtilities.invokeAndWait();
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          nameTextField0.setText("Unit test: 1");
        }
      });

      // Works: does not freez but does not change/apply the values
      new Thread(new Runnable() {
        Menu.nameTextField0.setText("Unit test: 2");
      });        

    }
  });
  Numlock.add(num0); 

  configPanel.setLayout(new GridLayout(0,1));
  configPanel.add(Numlock);

}

Follow up:

  • Used Polymorphism and that fix all those

1 Answers1

0

1) you have to add code lines

revalidate()
repaint();

in the case(s) you add JComponents to the already visible Container

2) add/remove JComponents from/to the already visible Container must be done on EventDispatschTread, should be wrapped into invokeLater / invokeAndWait

3) I'd suggest to wrapping (event are declared as Thread Safe methods) setText(), append() into invokeLater called from Runnable#Thread, Executor or util.Timer

4) use SwingTimer (guarantted output on EDT) or Runnable#Thread (must be wrapped into invokeLater / invokeAndWait)

5) for Swing GUI would be better to use SwingWorker, maybe better that Runnable#Thread with/or Executor/util.Timer

6) don't block EDT

7) as adviced for better help sooner edit your question with a SSCCE

EDIT

   new Thread(new Runnable() {

        public void run() {

            final RunnableOutput a = new RunnableOutput();

            if (SwingUtilities.isEventDispatchThread()) {
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        a.setText(nameTextField0, text);
                    }
                });
            } else {
                try {
                    SwingUtilities.invokeAndWait(new Runnable() {

                        @Override
                        public void run() {
                            a.setText(nameTextField0, text);
                        }
                    });
                } catch (InterruptedException ex) {
                    Logger.getLogger(Menu.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InvocationTargetException ex) {
                    Logger.getLogger(Menu.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }).start();
Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • 1
    @YumYumYum everything is hidden into public void draw(Graphics2D g) { this periodically recreating all Objects inside, these Object create only once otherwise outofmemory killed current JVM :-) – mKorbel Apr 13 '12 at 21:46
  • WOW you are Genius. What do you suggest in such case? My goal was to have keyboard capture + JPanel as modal so that i can have it game look UI's. All the rest was not so important therefore i used such a way. But i would like Guru like you, advise as first choice. –  Apr 14 '12 at 19:13
  • 1
    @YumYumYum leave this code, create a empty JFrame, put there image as backgroud to the JPanel, then you'll same output to the screen without hight painting and processor requirements – mKorbel Apr 15 '12 at 06:03