Update 1: Here is a more interesting thing. When i delete the last line { mainapp.showReportingScreen() ;} now program first execute the findAplliedJars method then show processing screen.
I'm working in JavaFX and struggling with actions of a button. What I want is, when that button is clicked:
do something;
show another screen;
do another thing;
show another screen;
But, my program skips the 2. point.
Here is my code:
public class SomeController implements Initializable {
.
.
.
#Override
public void initialize(URL location, ResourceBundle resources) {
.
.
.
someButton.setOnAction(new EventHandler<ActionEvent>(){
public void handle(ActionEvent event) {
Report.setUserName(userNameField.getText());
Report.setPassword(passwordField.getText());
Report.setSmAdress(smAdressField.getText());
mainApp.showProcessingScreen();
Report.findAppliedJars();
mainApp.showReportingScreen();
}
});
}
.
.
.
}
So, without showing processingScreen, my program executes findAppliedJars() and then shows reportingScreen.
What may be the problem? Thanks.
Update 2: Here is my showProcessingScreen() method:
public void showProcessingScreen() {
try {
// Load Report Screen
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("ProcessingScreen.fxml"));
AnchorPane processingScreen = (AnchorPane) loader.load();
// Set report screen into the center of root layout.
rootLayout.setCenter(processingScreen);
ProcessingScreenController controller = loader.getController();
controller.setMainApp(this);
} catch (IOException e) {
e.printStackTrace();
}
}
Unless you somehow pause the execution, the program will continue to execute, and essentially skip over the showing of your processing screen. To show your processing screen for a certain amount of time you need to use an animation and show your reporting screen once the animation has finished. Note the code below is only an outline of what your end result may look like and does not compile.
Transition transition;
// Set up your transition or animation
transition = buildTransition();
// Show your processing screen within the transition
showProcessingScreen();
transition.setOnFinished(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
Report.findAppliedJars();
mainApp.showReportingScreen();
}
});
If you are trying to load something in the background while the processing screen is showing then you will have to use concurrency. If you go this route, the code should look similar to the above, except you would be using the Task class and the setOnSucceeded method. There are other ways to perform this operation, but I believe this is the simplest way.
Related
I have an options menu from which you can save the game and it should briefly close the menu and take a screenshot of the current game.
However, the menu does not close until after calling getScreenCapture even though it runs before causing the screenshot to always be of the settings menu.
(The screenshot itself is working it's just controlling what displays at the time of the screenshot)
!! Without the screenshot line it updates the scene immediately even though the scene change line comes before.
So far I have tried Thread.sleep but no length of time allows for the scene to update
//The initial call to save:
private void saveRoom() {
program.changeState(previous);
room.save();
}
//The changing of scenes: (State extends Scene)
public void changeState(State state) {
currentState = state;
stage.setScene(currentState);
currentState.paintAll();
}
//How the game scene draws to screen:
#Override
public void paintAll() {
ArrayList<Shape> toAdd = new ArrayList<>();
for(Furniture f : furniture) {
f.paint(toAdd);
}
optionsButton.paint(toAdd);
addFurnitureButton.paint(toAdd);
root.getChildren().clear();
root.getChildren().addAll(toAdd);
}
//How the options menu draws to screen (same as game):
#Override
public void paintAll() {
ArrayList<Shape> toAdd = new ArrayList<>();
toolsButton.paint(toAdd);
saveButton.paint(toAdd);
saveAndExitButton.paint(toAdd);
exitButton.paint(toAdd);
closeButton.paint(toAdd);
root.getChildren().clear();
root.getChildren().addAll(toAdd);
}
//The capture command:
robot.getScreenCapture(null, new Rectangle2D(x,y,x1,y1));
Update: I am now using the Scene.snapshot command to take the screenshot instead and it does not cause the problem, but am still open to finding out how to go about using Robot to take a screenshot since unlike Scene.snapshot, it captures the whole screen rather than just the program which could come in handy in a future project.
I am trying to implement a feature where the program plays a video in fullscreen when there is no mouseclick or mousemove, say for x seconds. and stops the video and go back to previous scene when mouse is clicked or moved
currently i have this one working.. BUT the video plays after 5 seconds even though i click and move the mouse.. and I can't seem to find a solution on how to close the video and proceed to the previous scene/fxml when mouse is clicked move..
current code as of writing:
for playing video when mouse is idle:
PauseTransition delay = new PauseTransition(Duration.seconds(5));
delay.setOnFinished( event -> {
try {
Main.showVideo();
} catch (IOException ex) {
Logger.getLogger(UserMainPage2Controller.class.getName()).log(Level.SEVERE, null, ex);
}
} );
delay.play();
for showing video (located inside my main class):
public static void showVideo() throws IOException
{
File f = new File("C:\\vid\\saitama.mp4");
Media media = new Media(f.toURI().toString());
MediaView mv = new MediaView();
MediaPlayer mp = new MediaPlayer(media);
mv.setMediaPlayer(mp);
FXMLLoader loader=new FXMLLoader();
loader.setLocation(Main.class.getResource("page/videoPlayer.fxml"));
mainLayout = loader.load();
StackPane root=new StackPane();
root.getChildren().add(mv);
stage.setScene(new Scene(root,1000,1000));
stage.setTitle("Video");
stage.setFullScreen(true);
stage.show();
mp.play();
}
and im not really sure what to put inside my VideoPlayercontroller class either:
right now it is empty.
public class VideoPlayerController implements Initializable {
#Override
public void initialize(URL url, ResourceBundle rb) {
}
}
So what im trying to do is only play the video when mouse is idle (not clicked or moved for x seconds).. and closes the video when the mouse is moved or click..
like for example..
if mouseclicked then Main.showPreviousScene();
May be an issue that your delay is happening every time 5 seconds after first movement but not being updated before its elapsed. Try using timers instead so that you set the timer to 5 seconds on mouse moved event on timer elapsed event set the video to play.
Currently i'm trying to make an image slowly slide using Java fx from one coordinate to another. For this construction i'm using a pane and have added a shaft imageview and a elevator image to it. I've been succesfull in changing the coordinates of the image but I want the image to slowly slide over to that position. As a result I added a loop that with a thread.sleep method to slow down the looping speed. Unforunately this does not give the desired effect.
Hopefully one of you has a good suggestion I could use for this.
My loop:
Button een = new Button("1");
een.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent event) {
if(elevator.getY()>300){
while(elevator.getY()!=300){
elevator.setY(elevator.getY()-1);
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(LayoutSample.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
});
Yours truly
No loops, no sleep, TranslateTransition, linked javadoc includes a sample.
I have a basic javafx program where a rectangle, simulating an elevator, must move up and down at the push of 'up' and 'down' buttons. I have successfully implemented the code to do this below:
public void handle(ActionEvent event) {
if (event.getSource() == upButton) {
//this should all be put into a 'slideNode' method
TranslateTransition translateTransition1 = new TranslateTransition(Duration.millis(500), theElevator);
translateTransition1.setByX(0);
translateTransition1.setByY(-50);
translateTransition1.setCycleCount(1);
translateTransition1.setAutoReverse(false);
translateTransition1.play();
}
}
The issue I need to solve is what happens when the elevator is partway through this motion and the button is pressed again - the elevator doesn't get the full motion it would have if I waited until it reached its first destination to press the button again!
I understand why this happens, but I'd like to know if there's a way to solve this. I imagine there should be some piece of the API similar to the following, which I can toss at the end of my code:
Pause pause = new Pause(Duration.millis(500));
pause.pause();
Does such a thing exist? How would you solve my problem?
You can disable the button while the TranslateTransition is playing:
public void handle(ActionEvent event) {
if (event.getSource() == upButton) {
//this should all be put into a 'slideNode' method
TranslateTransition translateTransition1 = new TranslateTransition(Duration.millis(500), theElevator);
translateTransition1.setByX(0);
translateTransition1.setByY(-50);
translateTransition1.setCycleCount(1);
translateTransition1.setAutoReverse(false);
translateTransition.statusProperty().addListener((obs, oldStatus, newStatus) ->
button.setDisable(newStatus==Animation.Status.RUNNING));
translateTransition1.play();
}
}
Been trying around and searching but couldn't find any solution, so I finally decided to give up and ask further...
Creating a javafx app, I load tiles in a TilePane.
This tiles are clickable and lead to a details page of their respective content.
On each tile, if they do belong to a certain pack, I do display the pack name, that is also clickable and lead to a page showing that specific pack content.
So that means the container, the tile, that is a Pane is clickable and on top of it I have a Label that is claickable also. What happens is when I do click the Label, it also triggers the Pane onMousePressed()... Here is a part of the tile creation code, the part focused on the onMousePressed(). I tried to make the Pane react by double click and the Label by single, it works, but I want to Pane to open with a single click.
I would be more than thankfull for any ideas how to solve that.
public DownloadTile (Downloadable upload, MainApp mainApp) {
_mainApp = mainApp;
_upload = upload;
_tile = new Pane();
_tile.setPrefHeight(100);
_tile.setPrefWidth(296);
_tile.setStyle("-fx-background-color: #ffffff;");
_tile.setCursor(Cursor.HAND);
}
public void refresh() {
_tile.getChildren().clear();
_tile.setOnMousePressed(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
if (event.isPrimaryButtonDown() /*&& event.getClickCount() == 2*/) {
_mainApp.showDownloadDialog(dt, _upload);
}
}
});
if (_upload.getPack() != null) {
Label pack = new Label();
pack.setText(_upload.getPack());
pack.getStyleClass().add("pack-link");
pack.setCursor(Cursor.HAND);
pack.relocate(10, 48);
_tile.getChildren().add(pack);
pack.setOnMousePressed(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
if (event.isPrimaryButtonDown()) {
_mainApp.showPackPage(_upload);
}
}
});
}
}
Your label will receive the mouseclick first (since it's on top), so after you have processed the click, you can stop it from being passed down the chain using 'consume':
pane.setOnMouseClicked(
(Event event) -> {
// process your click here
System.out.println("Panel clicked");
pane.requestFocus();
event.consume();
};