2015-05-25 2 views
0

Я пытаюсь изменить сцену своей сцены с переходом «постепенное исчезновение» и «постепенное исчезновение». Я действительно закрыт, чтобы получить его, но совсем нет.Как использовать JavaFX FadeTransition In и Out

В первый раз, это не работает. Затем, иногда это прекрасно работает, а другие новые сцены показываются полностью в миллисекундах, чтобы продолжить работу с остальной частью перехода. Единственный, который отлично работает, - это FadeOut.

Я думаю, что я делаю что-то неправильно, но я не знаю, что. Я пробовал с FadeTransition и Timeline, но результат всегда один и тот же.

я покажу вам фрагмент кода, где я работаю:

// Вызывается из CONTROLLER КОГДА Я ХОЧУ ИЗМЕНИТЬ сюжетного

private static FadeTransition fadeOut = new FadeTransition(); 
private static FadeTransition fadeIn = new FadeTransition(); 

public void setScene(final String resource_fxml, final String title) { 
     fadeOut.setOnFinished(new EventHandler<ActionEvent>() { 

      @Override 
      public void handle(ActionEvent event) { 
       loadScene(resource_fxml, title); 
      } 
     }); 
     fadeOut.setNode(lastRoot); 
     fadeOut.setDuration(Duration.millis(Config.TRANSITIONS_TIME)); 
     fadeOut.setFromValue(1.0); 
     fadeOut.setToValue(0.0); 
     fadeOut.play(); 
} 

private void loadScene(String resource_fxml, String title) { 
     double width = SceneManager.lastScene.getWidth(); 
     double height = SceneManager.lastScene.getHeight(); 

     Parent newRoot = null; 
     try { 
      newRoot = FXMLLoader.load(getClass().getResource(resource_fxml)); 
     } catch (IOException ex) { 
      log.error("Resource not found"); 
     } 

//  DoubleProperty opacity = newRoot.opacityProperty(); 
//  Timeline fadeIn = new Timeline(
//    new KeyFrame(Duration.ZERO, new KeyValue(opacity, 0.0)), 
//    new KeyFrame(Duration.millis(Config.TRANSITIONS_TIME), new KeyValue(opacity, 1.0)) 
//  ); 
//  fadeIn.play(); 

     fadeOut.setNode(newRoot); 
     fadeOut.setDuration(Duration.millis(Config.TRANSITIONS_TIME)); 
     fadeOut.setFromValue(0.0); 
     fadeOut.setToValue(1.0); 
     fadeOut.play(); 

     lastScene = new Scene(newRoot, width, height); 
     mainStage.setTitle(title); 
     mainStage.setScene(lastScene); 
     mainStage.show(); 

     lastRoot = newRoot; 

    } 

EDIT: я показываю окончательный код (» loadScene "), который работает очень хорошо. Спасибо за ваши советы, Стивен Ван Импе!

private void loadScene(String resource_fxml, String title) { 
     double width = SceneManager.lastScene.getWidth(); 
     double height = SceneManager.lastScene.getHeight(); 

     Parent newRoot = null; 
     try { 
      newRoot = XMLLoader.load(getClass().getResource(resource_fxml)); 
     } catch (IOException ex) { 
      log.error("Resource not found"); 
     } 

     fadeIn.setNode(newRoot); 
     fadeIn.setDuration(Duration.millis(Config.TRANSITIONS_TIME)); 
     fadeIn.setFromValue(0.0); 
     fadeIn.setToValue(1.0); 

     DoubleProperty opacity = newRoot.opacityProperty(); 
     opacity.set(0); 
     lastScene = new Scene(newRoot, width, height); 
     mainStage.setTitle(title); 
     mainStage.setScene(lastScene); 

     fadeIn.play(); 

     lastRoot = newRoot; 
    } 

ответ

0

Вы используете fadeOut снова в loadScene. Я так понимаю, вы хотите использовать там fadeIn? Кроме того, вы начинаете анимацию, когда newRoot еще не является частью сцены. Возможно, вам захочется попробовать сначала создать сцену (но запустив newRoot с непрозрачностью 0), а затем запустив анимацию.

Как правило, я бы также рекомендовал, чтобы вы не меняли местами сцены (или даже корни сцен) при смене экранов, а просто сворачивали Panes в вашем графическом интерфейсе. Это даст вам больше гибкости для анимации. Вы могли бы, например, исчезнуть в новом окне и постепенно погасить старое, что невозможно, если вы используете Scenes.

+0

Интересно, что вы говорите об обменивающих панелях. Но у меня есть вопрос об этом. Если для этого я использую Panes, все эти Panes должны быть в том же .fxml, что приводит к тому, что все Panes в одном контроллере? Если да, я думаю, с ним будет сложно работать. –

+0

Это не нужно. Каждый экран может иметь отдельный FXML и контроллер. Вы можете просто загрузить их по мере необходимости. Я также рекомендую использовать конструкцию 'fx: root'. Это обеспечивает отличную инкапсуляцию. См. [Мой ответ здесь] (http://stackoverflow.com/questions/30446878/how-to-pass-arguments-in-javafx/30457992#30457992) для получения дополнительной информации о 'fx: root'. –