#javafx #focus #openjfx
#javafx #фокус #openjfx
Вопрос:
(Мое) ожидаемое поведение:
Когда вы вызываете setFocusTraversable(false)
узел с дочерними элементами (т. Е. Узел имеет метод getChildren()
, который возвращает список Node
s) focusTraversable
, свойства этого узла и всех его дочерних элементов получают значение false
.
Фактическое поведение:
Однако, когда я вызываю setFocusTraversable(false)
, например, a TextFlow
, его дочерние элементы все еще могут получать фокус. Это показано в приведенном ниже коде.
Почему setFocusTraversable(boolean)
метод работает таким образом, и как следует обойти это ограничение?
// File: App.java
package nl.aronhoogeveen.bugreports;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Hyperlink;
import javafx.scene.layout.BorderPane;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;
/**
* JavaFX App
*/
public class App extends Application {
@Override
public void start(Stage stage) {
// TextFlow 1
Text text1 = new Text("This is text1");
Hyperlink hyperlink1 = new Hyperlink("This is hyperlink1");
Text text2 = new Text("This is text2");
Hyperlink hyperlink2 = new Hyperlink("This is hyperlink2");
TextFlow textFlow1 = new TextFlow(text1, hyperlink1, text2, hyperlink2);
textFlow1.setFocusTraversable(false);
// TextFlow 2 (CustomTextFlow)
Text text3 = new Text("This is text3");
Hyperlink hyperlink3 = new Hyperlink("This is hyperlink3");
Text text4 = new Text("This is text4");
Hyperlink hyperlink4 = new Hyperlink("This is SPARTAAAAA");
CustomTextFlow textFlow2 = new CustomTextFlow(text3, hyperlink3, text4, hyperlink4);
textFlow2.customSetFocusTraversable(false);
BorderPane rootBorderPane = new BorderPane();
rootBorderPane.setTop(textFlow1);
rootBorderPane.setBottom(textFlow2);
stage.setScene(new Scene(rootBorderPane));
stage.sizeToScene();
stage.show();
}
public static void main(String[] args) {
launch();
}
}
// File: CustomTextFlow.java
package nl.aronhoogeveen.bugreports;
import javafx.scene.Node;
import javafx.scene.text.TextFlow;
public class CustomTextFlow extends TextFlow {
public CustomTextFlow(Node... children) {
super(children);
}
/**
* Sets the property focusTraversable of all children's children to {@code b}.
*
* @param b the value to set for the properties
*/
public void customSetFocusTraversable(boolean b) {
for (Node child : getChildren()) {
// Assume for simplicity that the children are not Parents or other types that have children
child.setFocusTraversable(b);
}
}
}
Я обнаружил ошибку в компоненте HyperlinkLabel
ControlsFX, касающуюся этого поведения, и после расследования я обнаружил, что это поведение уже присутствует в компоненте JavaFX TextFlow
, который используется HyperlinkLabel, и поэтому я публикую этот вопрос.
Комментарии:
1. хм.. что заставляет вас думать, что это свойство применяется к полному поддереву родительского дерева?
2. только что проверил документ — ничего, подтверждающего ваши ожидания, что означает, что в общем случае ожидание неверно. При необходимости разработчики элемента управления могут отключить преобразование focustraversal в дочерние элементы, например, используя пользовательскую FocusTraversalPolicy или привязав их свойство к родительскому (как вы в основном и делаете — за исключением отсутствия каких-либо изменений)
3. Очень аккуратно привязать
focusTraversableProperty
дочерние элементы к родительскому. Я об этом не подумал. Тогда ваш комментарий прекрасно ответил на оба моих вопроса. Спасибо, что подумали. Если вы превратите свой комментарий в ответ, я исключу его