在JavaFX 8中获取Node的可见状态 [英] Get visible state of Node in JavaFX 8

查看:120
本文介绍了在JavaFX 8中获取Node的可见状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要检测节点当前是否正在显示。
I.e.如果我的节点在TabPane中,我需要知道它是否在选定的选项卡中。

I need to detect if a node is currently displaying. I.e. if my Node is in a TabPane, I need to know if it is in a selected tab or not.

在示例中,我想知道HBox何时显示Node的visibleProperty和managedProperty似乎没有帮助我:

In the example, I want to know when the HBox is displaying.The visibleProperty and managedProperty of Node, does not seem to help me:

public class VisibleTest extends Application {

@Override
public void start(Stage primaryStage) throws Exception {

    TabPane tabpane = new TabPane();
    tabpane.getTabs().add(new Tab("Tab1", new Label("Label1")));

    HBox hbox = new HBox(new Label("Label2"));
    hbox.setStyle("-fx-background-color: aquamarine;");

    hbox.visibleProperty().addListener((observable, oldValue, newValue) -> {
        System.out.println("Hbox visible changed. newValue: " + newValue);
    });

    hbox.managedProperty().addListener((observable, oldValue, newValue) -> {
        System.out.println("Hbox managed changed. newValue: " + newValue);
    });

    Tab tab2 = new Tab("tab2", hbox);
    tabpane.getTabs().add(tab2);

    primaryStage.setScene(new Scene(tabpane));
    primaryStage.setWidth(600);
    primaryStage.setHeight(500);
    primaryStage.show();
}

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

我知道,有可能听 selectedProperty 选项卡的状态,但这并不能解决我的实际问题。

I know, it is possible to listen on the selectedProperty state of the tab, but this does not solve my real problem.

节点。 impl_isTreeVisible()做我想要的,但这是一个被删除的API。

Node.impl_isTreeVisible() does what I want, but this is depricated API.

任何想法?


------------------------------------更新--- -----------------

我意识到上面的代码示例并不能很好地解释我想要实现的目标。
下面是一些Swing代码那种演示了我想在JavaFX中完成的任务。检测JComponent / Node是否可见/显示,并根据该状态启动或停止后台进程。如果它是一个javaFX类,构造函数将如何。

Any ideas?

------------------------------------ update--------------------
I realize the code example above does not explain well what I'm trying to accomplish.
Below is some Swing code that kind of demonstrates what I am trying to accomplish in JavaFX. Detect if the JComponent/Node is visible/shown, and based on that state, start or stop background processes. How would the constructor look like if it was a javaFX class.

public class SwingVisible extends JComponent {

    String instanceNR;
    Thread instanceThread;
    boolean doExpensiveStuff = false;

    public SwingVisible(String instanceNR) {
        this.instanceNR = instanceNR;
        this.setLayout(new FlowLayout());
        this.add(new JLabel(instanceNR));

        instanceThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    if (doExpensiveStuff) {
                        /*
                         * do expensive stuff.
                         */
                        System.out.println(instanceNR + " is visible " + isVisible());
                    }
                }
            }
        });

        /*
         * How to do this in FX?
         */
        addComponentListener(new ComponentAdapter() {
            @Override
            public void componentShown(ComponentEvent e) {
                if (!instanceThread.isAlive()) {
                    instanceThread.start();
                }
                doExpensiveStuff = true;
            }

            @Override
            public void componentHidden(ComponentEvent e) {
                doExpensiveStuff = false;
            }
        });
    }

    public static void main(String[] args) {    
        /*
         * This block represents code that is external to my library. End user
         * can put instances of SwingVisible in JTabbedPanes, JFrames, JWindows,
         * or other JComponents. How many instances there will bee is not in my
         * control.
         */
        JTabbedPane jtp = new JTabbedPane();
        jtp.add("tab1", new SwingVisible("1"));
        jtp.add("tab2", new SwingVisible("2"));
        jtp.add("tab3", new SwingVisible("3"));

        JFrame f = new JFrame("test");
        f.setContentPane(jtp);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(300, 300);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

选择tab1时的输出:

Output when tab1 is selected:


1可见true

1可见true

1可见true

b $ b ...

1 is visible true
1 is visible true
1 is visible true

...

选择tab2时的输出:

Output when tab2 is selected:


2可见true

2可见true

2可见true

...

2 is visible true
2 is visible true
2 is visible true
...


推荐答案

您可以使用标签's selectedProperty 知道它是否被选中,如果其内容可见或不可见,则为扩展名。它是一个布尔属性。

You can use Tab's selectedProperty to know if it is selected or not, and by extension if its content is visible or not. It is a boolean property.

我已根据您最初的JavaFX示例将Swing代码转换为JavaFX:

I've converted your Swing code to JavaFX based on your initial JavaFX example:

public class VisibleTest extends Application {

    public class FXVisible extends Tab {

        FXVisible(String id) {
            super(id, new Label(id));

            Timeline thread = new Timeline(
                    new KeyFrame(Duration.ZERO, e -> { 
                        if (isSelected()) {
                            // do expensive stuff
                            System.out.println(id + " is visible");
                        }
                    }),
                    new KeyFrame(Duration.seconds(1))
            );
            thread.setCycleCount(Timeline.INDEFINITE);

            selectedProperty().addListener((selectedProperty, wasSelected, isSelected) -> {
                if (isSelected) {
                    if (thread.getStatus() != Status.RUNNING) {
                        System.out.println(id + " starting thread");
                        thread.play();
                    }
                }
                // else, it is not selected -> content not shown
            });
        }
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        TabPane tabpane = new TabPane();
        tabpane.getTabs().add(new FXVisible("1"));
        tabpane.getTabs().add(new FXVisible("2"));
        tabpane.getTabs().add(new FXVisible("3"));
        // add as many as you want

        primaryStage.setScene(new Scene(tabpane));
        primaryStage.setWidth(600);
        primaryStage.setHeight(500);
        primaryStage.show();
    }

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

我用JavaFX替换你的线程 时间表 。你的问题不是关于这个主题的,所以我不会在这里详细介绍,虽然它是自我解释的。

I replaced your thread with a JavaFX Timeline. Your question is not about this topic so I won't go into details here, though it's self explanatory.

我不明白为什么在Swing例子中你有一个监听器更改一个布尔值,指示组件是否可见,只需在线程中直接调用 isVisible()(有关线程的说明,请参阅下面的注释)。这就是为什么在上面的代码中我采用了直接检查 isSelected()的方法而没有自我声明的布尔值。如果你需要恢复你的设计,那就相当简单了。为了清楚起见,请注意这一点。

I don't understand why in the Swing example you have a listener changing a boolean that indicates if the component is visible or not when you can just call isVisible() directly in the thread (see comments below for a note about threading). This is why in my code above I took the approach of checking isSelected() directly with no self-declared boolean. If you need to revert to your design it's rather straightforward. Just noting this for clarity.

可以用上的更改侦听器替换 ComponentListener selectedProperty()并查询新值。只需确保您的示例执行它应该执行的操作:第一次选择选项卡时,线程/计时器将启动。之后,线程/计时器什么都不做。您可能想要暂停非显示内容的计算。再次,只是注意到它,因为它似乎是我的潜在错误,否则你没事。

The ComponentListener can be replaced with a change listener on selectedProperty() and querying the new value. Just be sure that your example does what it's supposed to do: the first time the tab is selected the thread/timer starts. After that the thread/timer does nothing. You might have wanted to pause the computation for non-displaying content. Again, just noting it because it seemed like a potential mistake to me, otherwise you're fine.

这篇关于在JavaFX 8中获取Node的可见状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆