Мы полагаемся на Node.impl_isTreeVisible(), потому что isVisible не работает должным образом (или, по крайней мере, так, как мы этого хотим).
/**
* @treatAsPrivate implementation detail
* @deprecated This is an internal API that is not intended for use and will be removed in the next version
*/
@Deprecated
public final boolean impl_isTreeVisible() {
return impl_treeVisibleProperty().get();
}
У нас есть пользовательский узел, который содержит Plot. Это получает непрерывные данные. Мы хотим избежать обновления графика, если он не виден (все еще управляется/рендерится, но скрыт). Если узел помещен на вкладку, которая не выбрана, поэтому он не виден в окне, то использование isVisible все равно возвращает значение true. Это приводит к тому, что узел на выбранной вкладке отображается каждый раз при обновлении графика.
Это будет оцениваться как true, даже если узел не виден в окне приложения.
if (isVisible()) {
updatePlot()
}
Поэтому мы использовали следующее, которое работает так, как мы этого хотим.
if (impl_isTreeVisible()) {
updatePlot()
}
Однако это больше не будет работать в Java 9, поскольку такие методы удалены. Есть ли новый подход к этому в Java 9?
Обновление: просмотрев исходный код Java 9 для javafx.scene.Node, я обнаружил метод isTreeVisible(), который выглядит как замена impl_isTreeVisible. Однако, глядя на Javadoc, я не могу найти это isTreeVisible(). http://download.java.net/java/jdk9/docs/api/javafx/scene/Node.html
Попытка использования примера с использованием isTreeVisible() не будет компилироваться с Java 9
Java9AppTest.java:50: error: cannot find symbol
if (text1.isTreeVisible()) {
^
symbol: method isTreeVisible()
location: variable text1 of type Text
Update2: сначала не удалось увидеть, что isTreeVisible() является частным пакетом.
Update3. Взглянув еще раз на исходный код Node, я начал проверять NodeHelper, можно ли использовать его для получения isTreeVisible(), однако пакет NodeHelper не виден. Хотя использование --add-exports для com.sun.javafx.scene для получения доступа к NodeHelper работает.
--add-exports javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED
Затем я могу прочитать состояние isTreeVisible() узла.
final boolean isTreeVisible = NodeHelper.isTreeVisible(node);
Пример кода
Содержит две вкладки, каждая со своим текстом. Имеет задачу, которая обновляет каждый текст. Использование isVisible() обновит каждый текст на обеих вкладках. Использование impl_isTreeVisible() будет обновлять только тот текст, который действительно виден. Имеет смысл обновлять текст, даже если он не виден. Это просто для иллюстрации проблемы. Замените текст фоновым процессом, который выполняет гораздо большую нагрузку на процессор.
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Java9AppTest extends Application {
private Text text1, text2;
public static void main(String[] args) {
Java9AppTest.launch(args);
}
public void start(Stage stage) throws Exception {
TabPane root = new TabPane();
VBox box1 = new VBox();
text1 = new Text();
text1.setText("Hello World!");
text1.textProperty().addListener((observable, oldValue, newValue) -> {
System.out.println("text1 changed from " + oldValue + " to " + newValue);
});
box1.getChildren().addAll(text1);
Tab tab1 = new Tab("Tab 1");
tab1.setContent(box1);
VBox box2 = new VBox();
text2 = new Text();
text2.setText("Another Hello World!");
text2.textProperty().addListener((observable, oldValue, newValue) -> {
System.out.println("text2 changed from " + oldValue + " to " + newValue);
});
box2.getChildren().add(text2);
Tab tab2 = new Tab("Tab 2");
tab2.setContent(box2);
root.getTabs().addAll(tab1, tab2);
Task<Void> task = new Task<Void>() {
/* (non-Javadoc)
* @see javafx.concurrent.Task#call()
*/
@Override
protected Void call() throws Exception {
final String oldText = "Hello World!";
final String newText = "New Hello World!";
while (true) {
if (text1.isVisible()) {
if (text1.getText().equals(oldText)) {
text1.setText(newText);
} else {
text1.setText(oldText);
}
}
if (text2.isVisible()) {
if (text2.getText().equals(oldText)) {
text2.setText(newText);
} else {
text2.setText(oldText);
}
}
Thread.sleep(2000);
}
}
};
stage.setScene(new Scene(root));
stage.setWidth(200);
stage.setHeight(200);
stage.setTitle("JavaFX 9 Application");
stage.show();
Thread thread = new Thread(task, "Task");
thread.start();
}
}
@treatAsPrivate
подразумевает, что вы должны рассматривать это как частный метод: т. е. его не следует вызывать из подкласса. (По сути, команда JavaFX хотела сделать это приватным, но не могла этого сделать без реализации проекта Jigsaw, который был перенесен с Java 8 на 9.) Заменойpublic final boolean impl_isTreeVisible()
в Java 9 является пакетно-приватный методfinal boolean isTreeVisible()
. - person James_D   schedule 10.05.2017Control
и пишу скин, который является подклассомSkinBase
, переопределяяlayoutChildren()
. AIUI,layoutChildren()
будет вызываться только при необходимости. - person James_D   schedule 10.05.2017