9 Replies - 5424 Views - Last Post: 12 July 2010 - 05:37 PM Rate Topic: -----

#1 tunvall  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 05-March 10

Pause loop for user input

Posted 11 July 2010 - 09:13 PM

Hi,

I am trying to create an easy swing program, but have run into some issues. I have a for loop that displays images based on an array of case numbers. Either way, each time it ends up on case 4 (which displays instructions) I need the program to stop and wait for the user to hit 'space' before it moves on. I have tried to figure this out, but I am stuck.. appreciate any guidance..

		for(int i = 0;i <= displayIndex.length;i++){


			//reset to zero each time so we can get the first input from the user
			keyInputCount = 0;

			if(indexNumber == displayIndex.length){
				CSVData.updateAll(Data.getDataList());
				JOptionPane.showMessageDialog(
						null,
						"ALL DONE",
						"TASK FINISHED",
						JOptionPane.OK_OPTION);
				setVisible(false);
				dispose();
			}

			//start count for response time
			start = System.currentTimeMillis();

			switch(displayIndex[indexNumber]) {

			case 0:
				middle.setText(null);
				right.setIcon(heart);
				left.setIcon(null);
				inputCount = inputCount + 2;
				try {
					Thread.sleep(DISPLAY_TIME);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
				break;
			case 1:
				middle.setText(null);
				right.setIcon(null);
				left.setIcon(heart);
				inputCount = inputCount + 2;
				try {
					Thread.sleep(DISPLAY_TIME);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
				break;
			case 2:
				right.setIcon(flower);
				left.setIcon(null);
				inputCount = inputCount + 2;
				try {
					Thread.sleep(DISPLAY_TIME);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
				break;
			case 3:
				right.setIcon(null);
				left.setIcon(flower);
				inputCount = inputCount + 2;
				try {

					Thread.sleep(DISPLAY_TIME);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
				break;
			case 4:
				//need to wait for user input (space bar) to move on
				
				right.setIcon(null);
				left.setIcon(null);
				middle.setText(HeartsFlowersInst.getInstructions().get(instIndex));
				instIndex++;
				addKeyListener(
						new KeyAdapter() {
							public void keyPressed(KeyEvent e) {
								if (e.getKeyCode() == KeyEvent.VK_SPACE) {
									middle.setText(null);
								}			
							}
						});
				break;
			}

			indexNumber++;
			right.setIcon(null);
			left.setIcon(null);
			middle.setText("+");
			try {

				Thread.sleep(500);
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
		}
	}





Is This A Good Question/Topic? 0
  • +

Replies To: Pause loop for user input

#2 Dogstopper  Icon User is offline

  • The Ninjaducky
  • member icon



Reputation: 2870
  • View blog
  • Posts: 11,025
  • Joined: 15-July 08

Re: Pause loop for user input

Posted 11 July 2010 - 09:21 PM

Alright, first thing's first. Swing is NOT Thread safe: http://java.sun.com/...s/threads1.html

In order to wait, I would put a flag (a boolean) that is false until space has been pressed (which can be done with a KeyListener). If you have the event handler change the flag, then in your loop, you can detect it.

For your program, I would look into using a javax.swing.Timer instead of threads.
Was This Post Helpful? 1
  • +
  • -

#3 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8327
  • View blog
  • Posts: 31,857
  • Joined: 06-March 08

Re: Pause loop for user input

Posted 11 July 2010 - 09:22 PM

Something you missed here

           JOptionPane.showMessageDialog(  
                     null,  
                     "ALL DONE",  
                     "TASK FINISHED",  
                     JOptionPane.OK_OPTION);  
             setVisible(false);  
             dispose();  


your program will stop until the user replies to you JOptionPane
setVisible(false); applies to the container that outputs the JOptionPane not to the optionPane you are sure that this is what you want ?
dispose(): same thing you are sure that is what you want ? no need to make its visibility to false if you dispose() it the following statement
Was This Post Helpful? 1
  • +
  • -

#4 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10447
  • View blog
  • Posts: 38,690
  • Joined: 27-December 08

Re: Pause loop for user input

Posted 11 July 2010 - 10:15 PM

As the Java GUI is event-driven, I would focus more on listeners and events than on loops as you are doing. The looping style of user interaction is something more for introductory programs that utilize JOptionPane or console I/O. As Dogstopper suggested, I would make use of Swing Timer to change pictures and display your message, maybe incrementing a counter to determine which message to display. And if you set up the KeyListener before hand, you can test to see if the the counter is at the value for case 4, and respond appropriately if the space bar is pressed.

I cover more on Event-Driven programming in my tutorial here, if you want to check it out.
Was This Post Helpful? 1
  • +
  • -

#5 Dogstopper  Icon User is offline

  • The Ninjaducky
  • member icon



Reputation: 2870
  • View blog
  • Posts: 11,025
  • Joined: 15-July 08

Re: Pause loop for user input

Posted 11 July 2010 - 10:19 PM

View Postmacosxnerd101, on 12 July 2010 - 12:15 AM, said:

I cover more on Event-Driven programming in my tutorial here, if you want to check it out.


Didn't know you had that! Looks good man!
Was This Post Helpful? 0
  • +
  • -

#6 tunvall  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 05-March 10

Re: Pause loop for user input

Posted 12 July 2010 - 06:55 AM

View PostDogstopper, on 11 July 2010 - 08:21 PM, said:

Alright, first thing's first. Swing is NOT Thread safe: http://java.sun.com/...s/threads1.html

In order to wait, I would put a flag (a boolean) that is false until space has been pressed (which can be done with a KeyListener). If you have the event handler change the flag, then in your loop, you can detect it.

For your program, I would look into using a javax.swing.Timer instead of threads.


So I tried to use a timer set at 2000ms for the pictures, however, I need the pictures (hearts & flowers) to be displayed for 2000ms, but I need the "+" at the end to only be displayed for 500ms.

It would go something like:

Heart right (2000ms) --> '+' (500ms) --> Heart left (2000ms) --> '+' (500ms) --> Instructions (Paused) --> Space bar hit --> '+' (500ms) --> Heart left (2000ms) and so forth.

Would I have to use two timers, that would stop or start. Or is there a better way?
Was This Post Helpful? 0
  • +
  • -

#7 tunvall  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 05-March 10

Re: Pause loop for user input

Posted 12 July 2010 - 10:35 AM

Ok, so I updated my code using the sound advice you gave me and it is working pretty nicely. However, I still have not figure out how to display the images and the '+' at different rates... also, the use of a display array might be a bit messy?

Either way, I included the whole class this time..

public class HeartsFlowers extends JFrame implements ActionListener
{

	final int DISPLAY_TIME  = 2000;

	final CSVData csvData = new CSVData();
	final int uiRow = UserInfo.getRow();
	final List<String[]> dataList = Data.getDataList();


	//Timer
	Timer timer1;

	//Boolean flags
	boolean spaceAllowed = false;
	boolean pause = false;

	// Make 3 labels that will be seen throughout the program
	JLabel right;
	JLabel left;
	JLabel middle;


	//Image Icons	
	ImageIcon flower;
	ImageIcon heart;

	// Make cursor, which we will make blank
	Cursor blankCursor;
	BufferedImage cursorImg;

	// Integer array and index number that will control which image/text to show
	Integer[] displayIndex = {6,4,5,1,5,1,5,1,5,0,5,6,4,5,1,6}; 
	int indexNumber = 0;

	//Instruction index
	int instIndex = 0;

	//long used to start response time count
	long start;

	//counter to make sure not more than one input is taken
	int keyInputCount;

	//keep track of where to input in the CVS document
	int inputCount = -2;

	public HeartsFlowers()
	{

		super("Hearts and Flowers");

		//make the cursor blank
		cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
		blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(
				cursorImg, new Point(0, 0), "blank cursor");

		//create the two icons
		flower = new ImageIcon("flower.jpg");
		heart = new ImageIcon("heart.jpg");

		right = new JLabel();
		left = new JLabel();
		middle = new JLabel();
		middle.setHorizontalAlignment(SwingConstants.CENTER);

		add(left, BorderLayout.WEST);
		add(middle, BorderLayout.CENTER);
		add(right, BorderLayout.EAST);


		//set frame values
		setExtendedState(Frame.MAXIMIZED_BOTH);
		setUndecorated(true);
		setCursor(blankCursor);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		getContentPane().setBackground(Color.WHITE);
		setVisible(true);


		//add key listener for 'F3', 'z' '/' and 'space' keys
		addKeyListener(
				new KeyAdapter() {
					public void keyPressed(KeyEvent e) {
						if (e.getKeyCode() == KeyEvent.VK_F3) {
							setVisible(false);
							dispose();
						}	
						if (e.getKeyCode() == KeyEvent.VK_Z || e.getKeyCode() == KeyEvent.VK_SLASH) {
							if(keyInputCount == 0){
								String key = Character.toString(e.getKeyChar());
								String rt = Long.toString((System.currentTimeMillis() -
										start));
								dataList.get(uiRow)[(inputCount+4)] = key;
								dataList.get(uiRow)[(inputCount+5)] = rt;
								keyInputCount++;
							}
						}
						if (e.getKeyCode() == KeyEvent.VK_SPACE&& spaceAllowed == true) {
							middle.setText(null);
							pause = false;
							spaceAllowed = false;
							timer1.restart();
						}		

					}
				});


		timer1 = new Timer(DISPLAY_TIME, this);
		timer1.start();

	}

	public void actionPerformed(ActionEvent arg0){

		if(pause){
			timer1.stop();
		}
		//reset to zero each time so we can get the first input from the user
		keyInputCount = 0;

		if(indexNumber == displayIndex.length){
			CSVData.updateAll(Data.getDataList());
			JOptionPane.showMessageDialog(
					null,
					"ALL DONE",
					"TASK FINISHED",
					JOptionPane.OK_OPTION);

			dispose();
		}

		//start count for response time
		start = System.currentTimeMillis();

		middle.setText(null);

		switch(displayIndex[indexNumber]) {

		case 0:
			right.setIcon(heart);
			left.setIcon(null);
			inputCount = inputCount + 2;
			break;
		case 1:
			right.setIcon(null);
			left.setIcon(heart);
			inputCount = inputCount + 2;
			break;
		case 2:
			right.setIcon(flower);
			left.setIcon(null);
			inputCount = inputCount + 2;
			break;
		case 3:
			right.setIcon(null);
			left.setIcon(flower);
			inputCount = inputCount + 2;
			break;
		case 4:
			//need to wait for user input (space bar) to move on
			right.setIcon(null);
			left.setIcon(null);
			middle.setText(HeartsFlowersInst.getInstructions().get(instIndex));
			instIndex++;
			break;
		case 5:
			//need to wait for user input (space bar) to move on
			right.setIcon(null);
			left.setIcon(null);
			middle.setText("+");
			break;
		case 6:
			//makes the screen pause next time the timer fires
			pause = true;
			spaceAllowed = true;
			right.setIcon(null);
			left.setIcon(null);
			break;	
		}

		indexNumber++;

	}

	public static void main(String[] args)
	{
		new HeartsFlowers();
	}

}






Was This Post Helpful? 0
  • +
  • -

#8 bcranger  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 252
  • View blog
  • Posts: 1,199
  • Joined: 01-February 10

Re: Pause loop for user input

Posted 12 July 2010 - 03:51 PM

Not sure if this would work, right off the top of my head, didnt try it.

You might be able to make an array of the times you need, then everytime the timer sends its action event, you set the delay of the timer to the next element in your array, i.e. after you've performed your other taks.
Was This Post Helpful? 1
  • +
  • -

#9 tunvall  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 05-March 10

Re: Pause loop for user input

Posted 12 July 2010 - 05:11 PM

View Postbcranger, on 12 July 2010 - 02:51 PM, said:

Not sure if this would work, right off the top of my head, didnt try it.

You might be able to make an array of the times you need, then everytime the timer sends its action event, you set the delay of the timer to the next element in your array, i.e. after you've performed your other taks.


Thanks for the idea.. based on it I actually ended up putting the change in .setDelay() at the end of each case. Think it works pretty well.
Was This Post Helpful? 0
  • +
  • -

#10 bcranger  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 252
  • View blog
  • Posts: 1,199
  • Joined: 01-February 10

Re: Pause loop for user input

Posted 12 July 2010 - 05:37 PM

Glad to help :bananaman:
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1