Javafx 2 JavaFX画布-仅当画布可见时绘制
我正在考虑将我们的内部自动/测量应用程序从Swing移植到JavaFX,主要是因为它具有更好的外观和多点触控支持,但我找不到一种方法来仅在自定义组件可见时渲染它们 为了激发动机,想象一个有10个选项卡的屏幕,每个选项卡内都有一个显示正在测量的一些实时数据的绘图。在任何时候,只能看到一个情节。数据量很大,计算机有足够的能力一次绘制一幅图,但不能同时绘制所有图 摇摆版本 现在在Swing版本中,这种行为的实现非常简单。每个绘图都是一个自定义JComponent,它具有覆盖的paintComponent方法,该方法执行所有绘图。在两种重要情况下调用paintComponent:Javafx 2 JavaFX画布-仅当画布可见时绘制,javafx-2,javafx-8,Javafx 2,Javafx 8,我正在考虑将我们的内部自动/测量应用程序从Swing移植到JavaFX,主要是因为它具有更好的外观和多点触控支持,但我找不到一种方法来仅在自定义组件可见时渲染它们 为了激发动机,想象一个有10个选项卡的屏幕,每个选项卡内都有一个显示正在测量的一些实时数据的绘图。在任何时候,只能看到一个情节。数据量很大,计算机有足够的能力一次绘制一幅图,但不能同时绘制所有图 摇摆版本 现在在Swing版本中,这种行为的实现非常简单。每个绘图都是一个自定义JComponent,它具有覆盖的paintComponen
- 当组件可见时,例如,用户选择带有绘图的选项卡
- 当实时数据更改时,我的代码会对组件调用repaint(),如果该组件可见(或者当该组件再次可见时),则会调用paintComponent
请注意,不要将此可见性与Node.visibleProperty混淆。visibleProperty执行不同的操作,基本上会关闭节点的渲染。使用选项卡窗格,我认为唯一的方法是观察选项卡窗格的选定项(即选定选项卡)。您可能希望对绘图区域进行编码,使其独立于是否在选项卡窗格中显示,因此我将在绘图中包含一个
BooleanProperty
,指示它是否处于活动状态:
public class PlotPane extends Pane {
private final BooleanProperty active = new SimpleBooleanProperty();
public BooleanProperty activeProperty() {
return active ;
}
public final boolean isActive() {
return activeProperty().get();
}
public final void setActive(boolean active) {
activeProperty().set(active);
}
public PlotPane(String name) {
// just for demo...
activeProperty().addListener((obs, wasActive, isActive) -> {
if (isActive) {
System.out.println(name + " is active");
} else {
System.out.println(name + " is inactive");
}
});
}
}
然后,当您将其组装到选项卡窗格中时,可以绑定属性:
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class ActiveTabTest extends Application {
@Override
public void start(Stage primaryStage) {
PlotPane pane1 = new PlotPane("Pane1");
Tab tab1 = new Tab("Pane1", pane1);
PlotPane pane2 = new PlotPane("Pane2");
Tab tab2 = new Tab("Pane2", pane2);
TabPane tabPane = new TabPane(tab1, tab2);
pane1.activeProperty().bind(tabPane.getSelectionModel().selectedItemProperty().isEqualTo(tab1));
pane2.activeProperty().bind(tabPane.getSelectionModel().selectedItemProperty().isEqualTo(tab2));
primaryStage.setScene(new Scene(tabPane, 400, 400));
primaryStage.show();
}
public static class PlotPane extends Pane {
private final BooleanProperty active = new SimpleBooleanProperty();
public BooleanProperty activeProperty() {
return active ;
}
public final boolean isActive() {
return activeProperty().get();
}
public final void setActive(boolean active) {
activeProperty().set(active);
}
public PlotPane(String name) {
// just for demo...
activeProperty().addListener((obs, wasActive, isActive) -> {
if (isActive) {
System.out.println(name + " is active");
} else {
System.out.println(name + " is inactive");
}
});
}
}
public static void main(String[] args) {
launch(args);
}
}
如果画布在物理上不可见,则不会对其进行绘制,这是正确的,但这为您提供了打开/关闭数据流监视等功能的机会
如果需要,可以进一步细化绑定,例如:
plot1.activeProperty().bind(tabPane.getSelectionModel().selectedItemProperty().isEqualTo(tab1)
.and(tabPane.sceneProperty().isNotNull()));
好吧,这是个令人伤心的消息,在JavaFX中,在Swing中自动工作的东西基本上是不可能的。无论如何,非常感谢您为这个问题提供了一个干净的手动解决方案。如果存在类似于
Node.isPhysicallyVisibleProperty
的东西,它实际上可能工作得很好。。我会再等一会儿,然后把你的帖子标记为回答,谢谢。我不确定我是否理解你为什么认为这是不可能的:你肯定只是按照我显示的创建属性,然后观察它,根据需要打开/关闭处理?这不管用吗?问题是您的解决方案仅限于选项卡窗格中的画布,我必须使用您的解决方案手动连接画布。当窗口最小化时,它不会停止预处理/渲染;当它处于手风琴中时,它不会停止打印;当它被遮挡时,它不会停止预处理/渲染;当它由于任何其他无法想象的原因而无法在物理上看到时,它也不会停止预处理/渲染。没有任何进一步效果的Swing解决方案不会渲染绘图,除非它在物理上可见。