2017-02-06 25 views
1

Я пытаюсь создать собственный элемент управления в JavaFX, используя некоторую функцию привязки. Это моя проблема: у меня есть класс с DoubleProperty, который я использую для вычисления позиции элемента внутри моего настраиваемого элемента управления. Вот код:Метод invalidate() метода JavaFX, не вызываемый с привязкой

public class CustomControl extends Region { 
    private DoubleProperty positionProperty; 

    public CustomControl() { 
    positionProperty= new DoublePropertyBase(0.0) { 
     @Override public Object getBean() { return CustomControl.this; } 
     @Override public String getName() { return "position"; } 
     @Override protected void invalidated() { updatePostion(); } 
    }; 
    } 

    public DoubleProperty positionProperty() { return positionProperty; } 
    public double getPosition() { return positionProperty.get(); } 
    public void setPosition(double value) { positionProperty.set(value); } 

    private void updatePosition() { 
    double value = doubleProperty.get(); 
    //compute the new position using value 
    } 
} 

В моем приложении у меня есть два CustomControl с и я хочу, чтобы, когда я называю метод setPosition() на первом из них, второй один обновляет положение его компонента, а также. Для этого я переплетены в positionProperty двух CustomControl с так:

CustomControl control1 = new CustomControl(); 
CustomControl control2 = new CustomControl(); 
control2.positionProperty.bind(control1.positionProperty); 

Тогда, когда я звоню, например

control1.setPosition(50.0); 

только положение компонента control1 обновляется, на самом деле, когда я называю метод setPosition(), метод invalidated() из positionProperty из control1 фактически называется, но не тот, который был указан positionProperty, из contol2. Как я могу достичь того, чего хочу? Спасибо!

PS: Я также заметил, что с помощью метода bindBidirectional() вместо bind() работ, но она не должна работать, используя только bind() тоже?

EDIT: пример код доступен здесь: https://[email protected]/luca_bertolini/customcontrolexample.git

+0

Любая причина, по которой вы создаете реализацию «DoubleProperty» для анонимного класса? Ваша проблема, вероятно, связана с тем, что вы переопределяете метод «invalidated», не вызывая метод base ('super'). – Itai

+0

@sillyfly Я создал анонимный класс, потому что мне нужно будет иметь много этих 'CustomControl' на экране, а использование анонимного класса вместо установки прослушивателя в свойстве обеспечит меньшее использование памяти и меньше вычислительной сложности. Также стандартная реализация 'invalidate()' пуста, поэтому она не сильно меняется, если я вызываю 'super.invalidate()' или нет. –

+0

Опубликовать [MCVE]. Я тестировал это, и он работал точно так, как ожидалось ('System.out.println (control2.getPosition());' отображается '50.0'). Должна быть ошибка где-то еще в коде, который вы еще не опубликовали. –

ответ

1

JavaFX использует ленивые вычисления для всех привязок, что означает, что, когда изменение происходит на вашем out.positionProperty объекта, новое значение не сразу принимается во внимание. Это происходит позже, тогда и только тогда, когда впоследствии запрашивается значение.

Попробуйте это:

out.positionProperty().addListener(new InvalidationListener() { 
    @Override 
    public void invalidated(final Observable observable) { 
     // System.out.println("It must go now."); 
    } 
}); 

, и вы увидите, что на этот раз ваш код работает, как вы хотите.

+0

Да, это работает. Думаю, это единственный способ добиться того, чего я хочу. Спасибо! –

+0

Добро пожаловать. – Meziane