0

I have looked around for a while to add a system which delays the GUI text area only but to no avail, so far I have this:

    public void msg2(String msg) {
    for (int i = 0; i < msg.length(); i++) {
        mainTextController.append(Character.toString(msg.charAt(i)));
        try {
            Thread.sleep(45);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    mainTextController.append("\n");
}

the problem here is that whenever i run this method it works and the type-writer effect is there, but, the entire program halts until the sleep method is over.

I have tried BlockingQueue but the same results are shown.

I am not looking to be spoon fed just some insight on how can I overcome this problem.

this is the entire class:

package gui;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wb.swt.SWTResourceManager;

public class LabyrinthGUI {

    protected Shell shell;
    private Text mainTextController;

    /**
     * Launch the application.
     * 
     * @param args
     */
    public static void main(String[] args) {
        try {
            LabyrinthGUI window = new LabyrinthGUI();
            window.open();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Open the window.
     */
    Display display;
    public void open() {
        display = Display.getDefault();
        createContents();
        shell.open();
        shell.layout();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }

    /**
     * Create contents of the window.
     */
    Button btnGoNorth;

    protected void createContents() {
        shell = new Shell();
        shell.setBackground(SWTResourceManager.getColor(SWT.COLOR_BLACK));
        shell.setSize(600, 700);
        shell.setText("Murat's Labyrinth - v0.1");

        mainTextController = new Text(shell, SWT.READ_ONLY | SWT.WRAP);
        mainTextController.setDragDetect(false);
        mainTextController.setDoubleClickEnabled(false);
        mainTextController.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_ARROW));
        mainTextController.setEditable(false);
        mainTextController.setFont(SWTResourceManager.getFont("System", 9, SWT.NORMAL));
        mainTextController.setForeground(SWTResourceManager.getColor(SWT.COLOR_YELLOW));
        mainTextController.setBackground(SWTResourceManager.getColor(SWT.COLOR_BLACK));
        mainTextController.setBounds(10, 10, 564, 535);

        btnGoNorth = new Button(shell, SWT.BORDER);
        btnGoNorth.setSelection(true);


        btnGoNorth.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                msg2("You clicked here");
            }
        });

        btnGoNorth.setGrayed(true);
        btnGoNorth.setTouchEnabled(true);
        btnGoNorth.setFont(SWTResourceManager.getFont("System", 9, SWT.NORMAL));
        btnGoNorth.setBounds(227, 551, 75, 25);
        btnGoNorth.setText("Go North");

        Button btnGoSouth = new Button(shell, SWT.BORDER);
        btnGoSouth.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
            }
        });
        btnGoSouth.setText("Go South");
        btnGoSouth.setFont(SWTResourceManager.getFont("System", 9, SWT.NORMAL));
        btnGoSouth.setBounds(227, 626, 75, 25);

        Button btnGoWest = new Button(shell, SWT.BORDER);
        btnGoWest.setText("Go West");
        btnGoWest.setFont(SWTResourceManager.getFont("System", 9, SWT.NORMAL));
        btnGoWest.setBounds(134, 587, 75, 25);

        Button btnGoEast = new Button(shell, SWT.BORDER);
        btnGoEast.setText("Go East");
        //btnGoEast.setCursor(new Cursor());
        btnGoEast.setFont(SWTResourceManager.getFont("System", 9, SWT.NORMAL));
        btnGoEast.setBounds(328, 587, 75, 25);

    }


    public void lock() {
        btnGoNorth.setEnabled(false);
    }

    public void unlock() {
        btnGoNorth.setEnabled(true);
    }

    public void msg2(String msg) {
        for (int i = 0; i < msg.length(); i++) {
            mainTextController.append(Character.toString(msg.charAt(i)));
            try {
                Thread.sleep(45);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        mainTextController.append("\n");
    }
}
  • Do the wait from a separate thread instead of the main one. Make sure your access to the text area is properly synchronized. – Mad Physicist Apr 25 '18 at 18:41
  • Basically, your loop should be the `run` method of the `Runnable` you pass to the temp thread. – Mad Physicist Apr 25 '18 at 18:44
  • Possible duplicate of [Thread.sleep(time) is not working the way I need it to. I need something better](https://stackoverflow.com/questions/49906655/thread-sleeptime-is-not-working-the-way-i-need-it-to-i-need-something-better) – daniu Apr 25 '18 at 18:58

1 Answers1

1

the entire program halts until the sleep method is over.

Don't use Thread.sleep().

Instead you should be using a Swing Timer for animation.

Read the section from the Swing tutorial on How to Use Swing Timers for more information and working examples.

camickr
  • 321,443
  • 19
  • 166
  • 288