I am making a simple JavaFX game with a main menu, an options menu, and an actual game. I was able to successfully navigate through all of these menus until I made a seemingly unrelated change: I called the method "runGame()" on the following line.
The scene is getting changed, as I ran the statement
if (window.getScene() == app) {
System.out.println("This is working");
}
between window.setScene(app) and the runGame() call. However, even though the scene is apparently changing, it is not shown, and the program becomes unresponsive.
The content of runGame() is as follows:
public void runGame() {
gameClock = new Timeline(new KeyFrame(Duration.seconds(1), e -> spawnAndShrink()));
gameClock.setCycleCount(Timeline.INDEFINITE);
// Timer for program
while (!Target.isGameOver()) {
gameClock.play();
}
gameClock.stop();
}
I have already declared "Timeline gameClock" at the top of my program and imported all the necessary classes. There are no error messages.
I have also modified the runGame() method during my troubleshooting process, changing
gameClock = new Timeline(new KeyFrame(Duration.seconds(1), e -> spawnAndShrink()));
to
gameClock = new Timeline(new KeyFrame(Duration.seconds(1), e -> System.out.println("Timeline is working")));
The method "spawnAndShrink()" is intended to be called every second; it calls two other methods names "spawn()" and "shrink()" (super creative, I know). Did I set up my Timeline wrong, or is there an error in the underlying methods? I also encountered the same error changing scenes when I tried calling "Thread.sleep(1000)" in a while loop instead of using a Timeline.
Related
I have an multi-window javafx mailbox project.Which is realized by turning the visibility and availability true and false of the window(anchorpane).
now I hava two windows (paneA and B),When i switch from A to B,because there is a process where i need to load some information into the pane B and which would take some time, I wanted to make an progressindicator to show that panel B is actually loading information.
but the problem is,even if i set the progress-indicator's visibility and availability true before i called the loading function and switching pane function,the progress-indicator only show after the loading was finished.
i tried to set the progress-indicator's visibility and availability in another thread and it also wont work properly(show after the loading)
"loading" in the code is the fxml id of the progressindicator
here is the code:(the code is part of the controller.java)
//open inboxpage
public void OpenBox() {
this.loading.setVisible(true);//loading is the id of the progress indicator
this.loading.setDisable(false);
SendPane.setDisable(true);
SendPane.setVisible(false);
SettingPane.setDisable(true);
SettingPane.setVisible(false);
BoxPane.setDisable(false);
BoxPane.setVisible(true);
if(account.length()+pwd.length()<2) {
//this.loading.setVisible(false);
//this.loading.setDisable(true);
this.MailDisplay.setText("Please fill in your infos");
}else {
this.MailDisplay.clear();
LoadMails(account,pwd);
//this.loading.setVisible(false);
//this.loading.setDisable(true);
}
}
the truth is ,if i use the code below,the progress indicator won't show at all(the indicator show after loading,but it was set to unvisible soon after showing)
//open inboxpage
public void OpenBox() {
this.loading.setVisible(true);//loading is the id of the progress indicator
this.loading.setDisable(false);
SendPane.setDisable(true);
SendPane.setVisible(false);
SettingPane.setDisable(true);
SettingPane.setVisible(false);
BoxPane.setDisable(false);
BoxPane.setVisible(true);
if(account.length()+pwd.length()<2) {
this.loading.setVisible(false);
this.loading.setDisable(true);
this.MailDisplay.setText("Please fill in your infos");
}else {
this.MailDisplay.clear();
LoadMails(account,pwd);
this.loading.setVisible(false);
this.loading.setDisable(true);
}
}
Thanks to all who commented above,the problem was solved.
I used another thread to load the information into the pane.
before the execute of such thread ,invoke the indicator
setDisable(f);
setVisible(t);
at end of the run method of this class,invoke indicator.setdisable(t),visible(f)
```
ExecutorService executor = Executors.newCachedThreadPool();
System.out.println("call thread");
call(executor,account,pwd);
private synchronized void call (ExecutorService executor,String acc,String pwd) {
loadBox loader= new loadBox();
loader.loading=this.loading;
loader.account = acc;
loader.pwd= pwd ;
loader.ChooseMail = ChooseMail ;
loader.MailDisplay= this.MailDisplay;
System.out.println("exe thread");
executor.execute(loader);
}
```
http://code.makery.ch/blog/javafx-dialogs-official/ shows how to get the stage of a JavaFX-8 dialog:
// Get the Stage.
Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
Alas, this does not work for me: the dialog pane (although displayed) gives null on .getScene().
Is there any other easy way to get the stage or at least the scene of an open dialog window?
The background of the question is that, under certain circumstances, need to display an Alert to the user while keeping the underlying dialog window open. Currently, that does not work due to an invalid combination of Modality values, but that's a different topic.
Hard to say for sure if you post no context code but I think the problem is the timing. You need to get the stage before you showAndWait (or at least before the dialog is closed). Try this:
public static boolean showConfirmationDialog(String contentText, String headerText) {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION, contentText, ButtonType.YES, ButtonType.NO);
alert.setTitle("Test");
alert.setHeaderText(headerText);
Window alertWindow = alert.getDialogPane().getScene().getWindow();
System.out.println("alertWindow.getOpacity(): " + alertWindow.getOpacity());
Optional<ButtonType> result = alert.showAndWait();
//This would cause a NullPointerException at this point:
//alertWindow = alert.getDialogPane().getScene().getWindow();
//System.out.println("alertWindow.getOpacity(): " + alertWindow.getOpacity());
return (result.get() == ButtonType.YES);
}
I need a reference to the object under the mouse cursor in a javaFX Pane (or ScrollPane)
The following code removes the node under the cursor from the Pane.
The node object is stored in an ArrayList and has a unique id. If I had a reference to the node object, it would be a simple matter to remove it from the list. I'd be happy just to be able to pull the id of the node object out of the target description supplied by the MouseEvent's description of the target, and use it to find my node in the list. Note: I am creating these nodes dynamically and they are nameless: myList.add(new TYPE()).
Here's the snippet that I'm using to remove the node in the Pane;
root.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle (MouseEvent me) {
// would like a line here that grabbed the reference to the target
pane.getChildren().remove(me.getTarget());
}
});
It would be better for you to put the setOnMouseClicked listener to the node on which you want to remove from the list.
List<Node> listOfNodes = new ArrayList();
Node node = new Node();
listOfNodes.add(node);
node.setOnMouseClicked((event) -> {
listOfNodes.remove(node);
});
Note: Better use ObservableList than the ordinary ArrayList especially if you want that node to be removed also out from the root pane.
To James_D: Reason for disbelief: the syntax that fails to get past the compiler is the statement containing the expression me.getTarget().getText() which is commented out. It seemed to me that that ought to have worked.
for (Text tl : textList)
if ( (me.getTarget()) == (tl) )
{
System.out.println("HuRah!");
System.out.println("text is " + tl.getText());
//System.out.println("text is " + me.getTarget().getText());
textList.remove(me.getTarget());
}
In my cocos3d application, i have a UIViewController as rootview controller and from there i'll launch again Cocos3d scenes when use clicking on an option.
Here is my code below to launch scene from this view controller. Issue is, if i open uiviewcontroller and then move to scene by clicking on an option more than twice, then i'm getting error as "OpenGL error 0x0506 in -[EAGLView swapBuffers]
[GL ERROR] Unknown GL error (1286), before drawing HomeOwners3DScene Unnamed:1691. To investigate further, set the preprocessor macro GL_ERROR_TRACING_ENABLED=1 in your project build settings."
[This issue doesn't come first time when i view the scene, it shows properly. But if i go back and click back to show the scene more than twice or more, then it appeared to be blank scene with the below error in xcode]
Code below to move from my viewcontroller to further scenes:
-(void) launchMainScene :(UIViewController *) uiViewCrtller
{
[uiViewCrtller.view removeFromSuperview];
// This must be the first thing we do and must be done before establishing view controller.
if( ! [CCDirector setDirectorType: kCCDirectorTypeDisplayLink] )
[CCDirector setDirectorType: kCCDirectorTypeDefault];
// Default texture format for PNG/BMP/TIFF/JPEG/GIF images.
// It can be RGBA8888, RGBA4444, RGB5_A1, RGB565. You can change anytime.
CCTexture2D.defaultAlphaPixelFormat = kCCTexture2DPixelFormat_RGBA8888;
// Create the view controller for the 3D view.
viewController = [CC3DeviceCameraOverlayUIViewController new];
//viewController.supportedInterfaceOrientations = UIInterfaceOrientationLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft;
// Create the CCDirector, set the frame rate, and attach the view.
CCDirector *director = CCDirector.sharedDirector;
//director.runLoopCommon = YES; // Improves display link integration with UIKit
[director setDeviceOrientation:kCCDeviceOrientationPortrait];
director.animationInterval = (1.0f / kAnimationFrameRate);
director.displayFPS = YES;
director.openGLView = viewController.view;
// Enables High Res mode on Retina Displays and maintains low res on all other devices
// This must be done after the GL view is assigned to the director!
[director enableRetinaDisplay: YES];
[director setDepthTest:NO];
// Create the window, make the controller (and its view) the root of the window, and present the window
[window addSubview: viewController.view];
CCDirector.sharedDirector.displayFPS = NO;
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
// Set to YES for Augmented Reality 3D overlay on device camera.
// This must be done after the window is made visible!
viewController.isOverlayingDeviceCamera = NO;
// Create the customized CC3Layer that supports 3D rendering and schedule it for automatic updates.
CC3Layer* cc3Layer = [HomeOwners3DLayer node];
[cc3Layer scheduleUpdate];
// Create the customized 3D scene and attach it to the layer.
// Could also just create this inside the customer layer.
cc3Layer.cc3Scene = [HomeOwners3DScene scene];
// Assign to a generic variable so we can uncomment options below to play with the capabilities
CC3ControllableLayer* mainLayer = cc3Layer;
CCScene *scene = [CCScene node];
[scene addChild: mainLayer];
[[CCDirector sharedDirector] runWithScene: scene];
}
Below Error is throwing in Xcode console when i launch scene and go back viewcontroller and launch scene multiple times with showing blank screen in the scene:
*[This issue doesn't come first time when i view the scene, it shows properly. But if i go back and click back to show the scene more than twice or more, then it appeared to be blank scene with the below error in xcode]*
OpenGL error 0x0506 in -[EAGLView swapBuffers]
[GL ERROR] Unknown GL error (1286), before drawing HomeOwners3DScene Unnamed:1691. To investigate further, set the preprocessor macro GL_ERROR_TRACING_ENABLED=1 in your project build settings.
Please help to solve my problem.
Thank you.
I'm building a Flex app which requires me to download files.
I have the following code:
public function execute(event:CairngormEvent) : void
{
var evt:StemDownloadEvent = event as StemDownloadEvent;
var req:URLRequest = new URLRequest(evt.data.file_path);
var localRef:FileReference = new FileReference();
localRef.addEventListener(Event.OPEN, _open);
localRef.addEventListener(ProgressEvent.PROGRESS, _progress);
localRef.addEventListener(Event.COMPLETE, _complete);
localRef.addEventListener(Event.CANCEL, _cancel);
localRef.addEventListener(Event.SELECT, _select);
localRef.addEventListener(SecurityErrorEvent.SECURITY_ERROR, _securityError);
localRef.addEventListener(IOErrorEvent.IO_ERROR, _ioError);
try {
localRef.download(req);
} catch (e:Error) {
SoundRoom.logger.log(e);
}
}
As you can see, I hooked up every possible event listener as well.
When this executes, I get the browse window, and am able to select a location, and click save. After that, nothing happens.
I have each event handler hooked up to my logger, and not a single one is being called! Is there something missing here?
The problem seems to be with my command being destroyed before this could finish.
For a proof of concept, I set my localRef variable to be static instead of an instance variable, and everything went through successfully! I guess Cairngorm commands kill themselves asap!