This site requires JavaScript, please enable it in your browser!
Greenfoot back
GregC246
GregC246 wrote ...

2012/8/16

Closing window

1
2
GregC246 GregC246

2012/8/16

#
I have a feeling that you can't, but is it possible to close the window of a stand-alone project in-game?
erdelf erdelf

2012/8/16

#
I don't understand what you want, maybe you can be more specific
GregC246 GregC246

2012/8/16

#
Is there a method that can close the window of a stand-alone .jar project? Basically i want to make a "quit" button that will emulate pressing the red X in the corner.
kiarocks kiarocks

2012/8/16

#
It's very hard, but I think it is possible.
SPower SPower

2012/8/16

#
To explain kiarocks answer, I think you need to get access to the JFrame greenfoot is using to present your scenario. With that, you can close it, and your program closes. This would lead to tricky, tricky code, but it is possible.
GregC246 GregC246

2012/8/16

#
Well, I found where the window is stored (rootPaneContainer in GreenfootScenarioViewer). But i have absolutely no idea how to access that... The javadoc also says:
This class can view and run a Greenfoot scenario. It is not possible to interact with the objects in any way.
:(
kiarocks kiarocks

2012/8/16

#
It is very hard to get, I'm working on the code for you.
SPower SPower

2012/8/16

#
@Grec the doc says that because that frame can't talk to the Actors. But, you can get access to the frame (I think), and call the method dispose on it. But again, this will be very tricky to do.
kiarocks kiarocks

2012/8/16

#
OK, I still have no idea how to get an instance of the GreenfootSecnarioViewer. But, if you could find a way to do that, use this code:
Field f = GreenfootScenarionViewer.class.getDeclaredField("rootPaneContainer");
f.setAccessible(true);
//<Set variable like this>
Component c = (Component)f.get(<viewer instance>);
Don't forget to import java.reflect.Field.
GregC246 GregC246

2012/8/16

#
@kiarocks
new GreenfootScenarioViewer(frame);
The GreenfootScenarioViewer is never even assigned to a permanent variable, so... Thanks for the help, by the way.
kiarocks kiarocks

2012/8/16

#
I think it is, just thats the only reference you can find. EDIT: I found it, its in WorldHandlerDelagateStandalone. Now to find an instance of that.
kiarocks kiarocks

2012/8/17

#
Yay! Did a lot of work, here you go:
import java.awt.Toolkit;
import java.awt.event.WindowEvent;
import java.lang.reflect.Field;

import greenfoot.core.WorldHandler;
import greenfoot.export.GreenfootScenarioViewer;
import greenfoot.platforms.WorldHandlerDelegate;
import greenfoot.platforms.standalone.WorldHandlerDelegate;

public class Blah {
	public void close() throws NoSuchFieldException{
		WorldHandler wh = WorldHandler.getInstance();
		Field whd_get = WorldHandler.class.getDeclaredField("handlerDelegate");
		whd_get.setAccessible(true);
		WorldHandlerDelegate w = (WorldHandlerDelegate)whd_get.get(wh);
		if(w instanceof WorldHandlerDelegateStandAlone)
		{
			WorldHandlerDelegateStandAlone wsa = (WorldHandlerDelegateStandAlone)w;
			Field gsv_get = WorldHandlerDelegateStandAlone.class.getDeclaredField("viewer");
			gsv_get.setAccessible(true);
			GreenfootScenarioViewer gsv = (GreenfootScenarioViewer)gsv_get.get(wsa);
			Field f = GreenfootScenarioViewer.class.getDeclaredField("rootPaneContainer");
			f.setAccessible(true);
			RootPaneContainer rpc = (RootPaneContainer)f.get(gsv);
			WindowEvent wev = new WindowEvent(rpc, WindowEvent.WINDOW_CLOSING);
            Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
		}
		else return; //Not stand-alone, don't continue.
	}
}
GregC246 GregC246

2012/8/17

#
Thanks a lot! It works, but I had to make a few changes:
import java.awt.Toolkit;  
import java.awt.event.WindowEvent;  
import java.lang.reflect.Field; 
import greenfoot.core.WorldHandler;  
import greenfoot.export.GreenfootScenarioViewer;  
import greenfoot.platforms.WorldHandlerDelegate;  
import greenfoot.platforms.standalone.WorldHandlerDelegateStandAlone;  
import javax.swing.RootPaneContainer;
import javax.swing.JFrame;
  
public class Blah {  
    public void close() throws NoSuchFieldException,java.lang.IllegalAccessException{  
        WorldHandler wh = WorldHandler.getInstance();  
        Field whd_get = WorldHandler.class.getDeclaredField("handlerDelegate");  
        whd_get.setAccessible(true);  
        WorldHandlerDelegate w = (WorldHandlerDelegate)whd_get.get(wh);  
        if(w instanceof WorldHandlerDelegateStandAlone)  
        {  
           WorldHandlerDelegateStandAlone wsa = (WorldHandlerDelegateStandAlone)w;  
            Field gsv_get = WorldHandlerDelegateStandAlone.class.getDeclaredField("viewer");  
            gsv_get.setAccessible(true);  
            GreenfootScenarioViewer gsv = (GreenfootScenarioViewer)gsv_get.get(wsa);  
            Field f = GreenfootScenarioViewer.class.getDeclaredField("rootPaneContainer");  
            f.setAccessible(true);  
            System.out.println(f.get(gsv).getClass());
            JFrame rpc = (JFrame)f.get(gsv);  
            WindowEvent wev = new WindowEvent(rpc, WindowEvent.WINDOW_CLOSING);  
            Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
        }  
        else return; //Not stand-alone, don't continue.  
    }  
} 
Most notably using JFrame rather than RootPaneContainer (which didn't agree with new WindowEvent() ).
kiarocks kiarocks

2012/8/17

#
It was code I wrote on the spot, so it was untested.
mjrb4 mjrb4

2012/8/17

#
Worth mentioning for those who aren't aware - that sort of code (anything that uses reflection to grab private fields) may work in one version of Greenfoot but potentially break completely in the next. So the trade off you get for having that functionality is potentially having to re-write it each time the internal structure changes :-)
There are more replies on the next page.
1
2