2014-01-14 3 views
5

Когда я нажал кнопку, она изменит свое положение.Явно позиционирующие узлы в JavaFX

Но когда я перемещаю мышь, кнопка возвращается в центр сцены, почему?

У меня есть следующий код:

public class HolaMundo extends Application { 

    Button btn; 
    Scene scene; 

    @Override 
    public void start(Stage primaryStage) { 
     btn = new Button(); 
     btn.setText("Hola Mundo"); 

     StackPane root = new StackPane(); 
     root.getChildren().add(btn); 

     scene = new Scene(root, 300, 250); 

     primaryStage.setTitle("Hello World!"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 

     scene.setOnMouseMoved(new EventHandler<MouseEvent>(){ 

      @Override 
      public void handle(MouseEvent t) { 
       btn.setText(String.valueOf(t.getX())); 
      } 
     }); 

     btn.setOnAction(new EventHandler<ActionEvent>() { 

      @Override 
      public void handle(ActionEvent event) { 
       btn.setLayoutX(Math.random() * (300 - btn.getWidth())); 
       btn.setLayoutY(Math.random() * (250 - btn.getHeight())); 
      } 
     }); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
+0

Какая версия JavaFX включена? С помощью JavaFX 8 кнопка вообще не перемещается. – assylias

ответ

14

Предлагаемый подход

Для вашего конкретного фрагмента кода, возможно, с помощью Pane вместо StackPane является лучшим подходом.

Почему ваш код не делать то, что вы хотите

Если вы собираетесь установить вручную значение макета, не используйте панель макета (например, как StackPane), которая автоматически устанавливает значение макета для вас , Если вы используете панель макета, то значения макета, которые вы явно задали, будут автоматически переопределены, когда в следующий раз панель макета выполнит макет (например, изменится размер или какой-либо его контент или местоположение в графе сцены загрязнится).

Варианта явно выложив узлы

Если вы хотите явно макет элементов в JavaFX выполните одно из следующих действий:

  1. Подкласса Region и переопределить layoutChildren.
  2. Поместите свой контент в Pane, если вам нужен контейнер для стилизации CSS или реализации функций изменения размера.
  3. Поместите свой контент в Group, если вам не нужен контейнер для стилизации CSS или реализации функций изменения размера.

Связанные рекомендации по позиционированию узлов

Если вы хотите, чтобы автоматически выкладываются компонентами, используя предопределенные менеджер компоновки, но вы хотите изменить или временно изменить расположение некоторых компонентов из их положения по умолчанию , вы можете отрегулировать значения translateX/Y, а не значения layoutX/Y.В соответствии с определением translateX:

Окончательный перевод The ​​узла будет вычислена как layoutX + translateX, где layoutX устанавливает стабильное положение узла и translateX необязательно делает динамические корректировки в этой позиции. Эта переменная может использоваться для изменения местоположения узла, не нарушая его layoutBounds, что делает его полезным для анимирования местоположения узла.

Это означает, что менеджер компоновки может вычислить положение по умолчанию ребенка с помощью layoutX, и вы можете настроить положение по умолчанию с помощью translateX.

0

Не имея глубоко исследовал текущий случай, я вижу разницу, когда я использую AnchorPane вместо StackPane разместить кнопку на.

Изменив текст ярлыка кнопки по событию mouseMoved-Event, отображается панель (запрограммировано макет). С помощью StackPane, размещающего все его дети в самом центре, позиция Button сбрасывается в центр панели. Когда вы посмотрите на метод layoutChildren из StackPane, вы увидите вызов resizeRelocate. Таким образом, layoutX и layoutY сбрасываются, и кнопка возвращается в центральное положение (или независимо от того, как вы устанавливаете выравнивание StackPane).

Поэтому я считаю, что это правильное поведение StackPane, и я рекомендую использовать другую панель, например. AnchorPane.

Смежные вопросы