i got until here..

public class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent buttonEvent) {
int delay = 1000; //milliseconds

ActionListener taskPerformer = new ActionListener(){
public void actionPerformed(ActionEvent evt)
{
JFrame myFrame1 = new JFrame();
MySadFace sad = new MySadFace();
myFrame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame1.getContentPane().add(sad);
myFrame1.setSize(400, 200);
myFrame1.setVisible(true);
}
};

Timer test = new Timer(1000, taskPerformer);
test.start();

//wait 10 seconds before going on.
try {
Thread.sleep(10000);
}
catch (Exception e) {}
test.stop();
int answer = JOptionPane.YES_OPTION;
answer = JOptionPane.showConfirmDialog(null, "BOOOoooM!!! Would you like to play again?", "", JOptionPane.YES_NO_OPTION);

the timer is working, but why doesn't the MySadFace work?
thanks

Recommended Answers

All 9 Replies

Post the "MySadFace" code as well.

public class MySadFace extends JPanel {
		public void paintComponent(Graphics g){
			g.setColor(Color.black);
			g.fillRect(0, 0, 400, 200);
			g.setColor(Color.red);
			g.fillArc(100, 30, 30, 30, 0, 360);
			g.setColor(Color.red);
			g.fillArc(270, 30, 30, 30, 0, 360);
			g.setColor(Color.yellow);
			g.drawArc(100, 100, 200, 80, 0, 180);
			
		}
	}

It won't work for you like that because you are trying to execute the frame display and the pause all on the AWT event dispatch thread. I'd recommend either swapping out the panel that displays the buttons with the sad face panel or use an icon for the sad face and set the bomb button icon (or the Boom! dialog icon) to that icon - unless you want to get into the threading issues that are preventing that code from working.

I'm not sure if I understand this
Do you mean I do :

public class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent buttonEvent) {
			
myButton.setBackground(Color.black);
int delay = 1000; //milliseconds

ActionListener taskPerformer = new ActionListener(){
public void actionPerformed(ActionEvent evt)
{
myFrame.getContentPane().remove(myButton);
myFrame.getContentPane().remove(myButton1);
myFrame.getContentPane().remove(myButton2);
myFrame.getContentPane().remove(myButton3);
myFrame.getContentPane().remove(myButton4);
myFrame.getContentPane().remove(myButton5);
myFrame.getContentPane().remove(myButton6);
myFrame.getContentPane().remove(myButton7);
myFrame.getContentPane().remove(myButton8);
myFrame.invalidate();

MySadFace myDrawingPanel = new MySadFace();
myFrame.getContentPane().add(myDrawingPanel);
myFrame.validate();
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setSize(400, 200);
myFrame.setVisible(true);
}
};

Timer test = new Timer(1000, taskPerformer);
test.start();

//wait 3 seconds before going on.
try {
Thread.sleep(3000);
}
catch (Exception e) {}

test.stop();
int answer = JOptionPane.YES_OPTION;
answer = JOptionPane.showConfirmDialog(null, "BOOOoooM!!! Would you like to play again?", "", JOptionPane.YES_NO_OPTION);
myFrame1.setVisible(false);
if(answer == JOptionPane.YES_OPTION){				
MiniMinesweeper reset = new MiniMinesweeper();
myFrame.setVisible(false);
reset.reset();
}

else{
myFrame.setVisible(false);
}

this part totally doesn't work

ActionListener taskPerformer = new ActionListener(){
public void actionPerformed(ActionEvent evt)
{
myFrame.getContentPane().remove(myButton);
myFrame.getContentPane().remove(myButton1);
myFrame.getContentPane().remove(myButton2);
myFrame.getContentPane().remove(myButton3);
myFrame.getContentPane().remove(myButton4);
myFrame.getContentPane().remove(myButton5);
myFrame.getContentPane().remove(myButton6);
myFrame.getContentPane().remove(myButton7);
myFrame.getContentPane().remove(myButton8);
myFrame.invalidate();

MySadFace myDrawingPanel = new MySadFace();
myFrame.getContentPane().add(myDrawingPanel);
myFrame.validate();
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setSize(400, 200);
myFrame.setVisible(true);
}
};

I've tried placing it there not in a new actionlistener. It works but the delays happen before the MySadFace.
Why is it when I wrote as below, it doesn't remove all buttons?
It only removed the top 3

public class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent buttonEvent) {
			
myButton.setBackground(Color.black);

myFrame.getContentPane().remove(myButton);
myFrame.getContentPane().remove(myButton1);
myFrame.getContentPane().remove(myButton2);
myFrame.getContentPane().remove(myButton3);
myFrame.getContentPane().remove(myButton4);
myFrame.getContentPane().remove(myButton5);
myFrame.getContentPane().remove(myButton6);
myFrame.getContentPane().remove(myButton7);
myFrame.getContentPane().remove(myButton8);
myFrame.invalidate();

MySadFace myDrawingPanel = new MySadFace();
myFrame.getContentPane().add(myDrawingPanel);
myFrame.validate();
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setSize(400, 200);
myFrame.setVisible(true);*/
int delay = 1000; //milliseconds

It's the swap, pause, and replace operations all occurring within a single event on the AWT dispatch thread that is causing your problem. If you want to fiddle with the UI, wait a bit, and then fiddle with it some more you need to spawn a new thread to manage that so the AWT dispatch thread is free to respond to your UI changes.

The following will work, though since you did away with the panel to contain the buttons you will have to remove all of them and add them again. It would be easier to put them back into a panel you could swap out. I'll call it "gamePanel" in the code below

public class ButtonListener implements ActionListener {

    public void actionPerformed(ActionEvent buttonEvent) {
        // start the swap thread
        BoomThread boom = new BoomThread();
        boom.start();

        int answer = JOptionPane.showConfirmDialog(null, "BOOOoooM!!! Would you like to play again?", "", JOptionPane.YES_NO_OPTION);
        // reset or whatever
    }
}

class BoomThread extends Thread {

    public void run() {
        // replace game panel with sad face
        // this queues your update onto the 
        // thread that handles UI events.
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                remove(gamePanel);
                add(sad);
                validate();
                repaint();
            }
        });
        // pause this thread
        try {
            Thread.sleep(3000);
        } catch(InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        // swap game panel back in
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                remove(sad);
                add(gamePanel);
                validate();
                repaint();
            }
        });
    }
}

You will also need to create the "sad" panel in your initialization and have the reference at the class level so the thread use it.

Hope that helps.

I tried

remove(myButton);

but it says that the the method remove JButton is undefined for the type Runnable

So, I tried this instead because I did it this way :

myFrame.setLayout(new GridLayout(3, 3));
		int randomNumber = (int)(Math.random()*9)+1; 

		myButton = new JButton();
		myButton1 = new JButton();
		myButton2 = new JButton();
		myButton3 = new JButton();
		myButton4 = new JButton();
		myButton5 = new JButton();
		myButton6 = new JButton();
		myButton7 = new JButton();
		myButton8 = new JButton();

		myButton.addActionListener(new ButtonListener());
		myButton1.addActionListener(new ButtonListener1());
		myButton2.addActionListener(new ButtonListener2());
		myButton3.addActionListener(new ButtonListener3());
		myButton4.addActionListener(new ButtonListener4());
		myButton5.addActionListener(new ButtonListener5());
		myButton6.addActionListener(new ButtonListener6());
		myButton7.addActionListener(new ButtonListener7());
		myButton8.addActionListener(new ButtonListener8());
	
		if(randomNumber == 1){
			myFrame.getContentPane().add(myButton);
			myFrame.getContentPane().add(myButton1);
			myFrame.getContentPane().add(myButton2);
			myFrame.getContentPane().add(myButton3);
			myFrame.getContentPane().add(myButton4);
			myFrame.getContentPane().add(myButton5);
			myFrame.getContentPane().add(myButton6);
			myFrame.getContentPane().add(myButton7);
			myFrame.getContentPane().add(myButton8);

Correct me if I'm wrong. What it does here is the buttons that myFrame contains would be removed and would be replaced by "sad", right?
I'm not sure if I understand what you were saying before because doing it this way, it removes all the buttons but the 'sad' only shows in the top three panels instead of in the overall frame. What could be wrong here?

class BoomThread extends Thread{
	public void run(){
		EventQueue.invokeLater(new Runnable(){
			public void run(){
				myFrame.remove(myButton);
				myFrame.remove(myButton1);
				myFrame.remove(myButton2);
				myFrame.remove(myButton3);
				myFrame.remove(myButton4);
				myFrame.remove(myButton5);
				myFrame.remove(myButton6);
				myFrame.remove(myButton7);
				myFrame.remove(myButton8);
				myFrame.add(sad);
				myFrame.validate();
				myFrame.repaint();
			}
		});
			
		try{
			Thread.sleep(3000);
		}catch(InterruptedException e){
			Thread.currentThread().interrupt();
		}
			
		EventQueue.invokeLater(new Runnable(){
			public void run(){
				//myFrame.remove(sad);
				int answer = JOptionPane.YES_OPTION;
				answer = JOptionPane.showConfirmDialog(null, "BOOOoooM!!! Would you like to play again?", "", JOptionPane.YES_NO_OPTION);
				myFrame1.setVisible(false);
				if(answer == JOptionPane.YES_OPTION){				
					MiniMines reset = new MiniMines();
					myFrame.setVisible(false);
					reset.reset();
				}
				else{
					myFrame.setVisible(false);
				}
				//myFrame.validate();
				//myFrame.repaint();
			}
		});
	}
}

I don't know what all you are swapping around there after the pause, but basically I was showing that you could swap out the game panel for the sad face panel and then swap them back. Any variations on that will depend on how you have specifically organized your components. Putting those UI changes on the event queue in separate Runnables with

EventQueue.invokeLater(new Runnable(){ ... });

allows the UI to be responsive to repaints, because those are processed on the same thread.

I tried

remove(myButton);

but it says that the the method remove JButton is undefined for the type Runnable

This error is likely a result of where you located the inner class BoomThread. Inner classes have access to the methods of their enclosing class, so if it were in the class extending Frame it would be able to call that method.

ah ok. I get it now :D

Thanks :D :D

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.