对 TabPanes 选项卡使用 JavaFX PopOver 以查看其内容

我尝试Peek Control为 a创建一个TabPane因此,如果面板已经打开,则会Snapshot保存。当用户将鼠标悬停在 上时,Tab它会显示一个PopOver. 这类似于Windows Aero Peek.

我的问题是PopOver它不应该被隐藏......因为它hide()Tabs Graphic.

我创建了一个小的可运行示例来演示问题:

import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.controlsfx.control.PopOver;
import org.controlsfx.control.PopOver.ArrowLocation;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.Label;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Main extends Application {
    Peek peek;
    Tab lastPeek;
    boolean show = false;

    public static void main(String[] args) {
        System.out.println("WE HAVE PROBLEMS WITH FOCUS HERE");
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        peek = new Peek();
        primaryStage.setTitle("Tabs");
        Group root = new Group();
        Scene scene = new Scene(root, 400, 250, Color.WHITE);

        TabPane tabPane = new TabPane();

        BorderPane borderPane = new BorderPane();

        final PopOver popOver = new PopOver();
        popOver.setArrowLocation(ArrowLocation.TOP_LEFT);
        final ImageView preview = new ImageView();
        preview.setFitHeight(100);
        preview.setSmooth(true);
        preview.setPreserveRatio(true);
        popOver.setContentNode(preview);

        for (int i = 0; i < 5; i++) {
            Tab tab = new Tab();
            HBox hbox = new HBox();
            hbox.getChildren().add(new Label("", new ImageView(new Image(Main.class.getResourceAsStream(i + ".jpg")))));
            hbox.setAlignment(Pos.CENTER);
            tab.setContent(hbox);
            tabPane.getTabs().add(tab);

            final Label decoration = new Label("Tab" + i);
            tab.setGraphic(decoration);
            System.out.println("tab.getGraphic() = " + tab.getGraphic());

            final int index = i;
            tab.getGraphic().setOnMouseEntered(mouseEvent -> {
                boolean show = false;
                if (lastPeek != tab) {
                    // Show PopOver when mouse enters label
                    Image previewImage = peek.get(tab);
                    if (previewImage != null) {
                        show = true;
                    }
                    System.out.println("previewImage = " + previewImage);
                    preview.setImage(previewImage);
                    System.out.println("show() " + "Tab" + index);
                    lastPeek = tab;
                }
                if (!tab.isSelected() && !tab.isDisabled() && show) {
                    popOver.show((Node) mouseEvent.getSource(), -3);
                }
            });

            tab.getGraphic().setOnMouseExited(mouseEvent -> {
                // Hide PopOver when mouse exits label
                // how can we handle this correct??
                 popOver.hide();
                System.out.println("hide() " + "Tab" + index);
            });

        }

        tabPane.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>() {
            @Override
            public void changed(ObservableValue<? extends Tab> ov, Tab oldTab, Tab newTab) {
                Image preview = oldTab.getContent().snapshot(new SnapshotParameters(), null);
                peek.set(oldTab, preview);
            }
        });
        tabPane.selectionModelProperty().addListener(new ChangeListener<SingleSelectionModel<Tab>>() {

            @Override
            public void changed(ObservableValue<? extends SingleSelectionModel<Tab>> ov,
                    SingleSelectionModel<Tab> oldValue, SingleSelectionModel<Tab> newValue) {
            }
        });

        // bind to take available space
        borderPane.prefHeightProperty().bind(scene.heightProperty());
        borderPane.prefWidthProperty().bind(scene.widthProperty());

        borderPane.setCenter(tabPane);
        root.getChildren().add(borderPane);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

}

这是Peek班级Snapshots

public class Peek {
    ObservableMap<Object, Image> peeks = FXCollections.observableHashMap();

    public void set(Object key, Image preview) {
        peeks.put(key, preview);
    }

    public Image get(Object key) {
        Image preview = peeks.get(key);
        return preview;
    }

}
帕博

这实际上是因为您显示的 popOver。一旦显示 popOver ,它就会获得焦点,并且一个 MouseExit 事件被分派到您的选项卡的图形。
您可以通过向弹出窗口添加更大的偏移量来观察它:

popOver.show((Node) mouseEvent.getSource(), -15);

或者简单地从选项卡的顶部而不是从底部输入鼠标(问题不再出现)。

此外,由于事件似乎没有很好地同步(将鼠标从一个选项卡移动到另一个选项卡的速度足够快时),我建议您按选项卡创建一个 PopOver。

public class Main extends Application {

   Peek peek;

   Tab lastPeek;

   HashMap<Label, PopOver> popMap = new HashMap<>();

   boolean show = false;

   public static void main(String[] args) {
      System.out.println("WE HAVE PROBLEMS WITH FOCUS HERE");
      Application.launch(args);
   }

   @Override
   public void start(Stage primaryStage) {
      peek = new Peek();
      primaryStage.setTitle("Tabs");
      Group root = new Group();
      Scene scene = new Scene(root, 400, 250, Color.WHITE);

      TabPane tabPane = new TabPane();

      BorderPane borderPane = new BorderPane();

      for(int i = 0; i < 5; i++) {
         Tab tab = new Tab();
         HBox hbox = new HBox();
         hbox.getChildren()
               .add(new Label("", new ImageView(new Image(Main.class.getResourceAsStream(i + ".jpg")))));
         hbox.setAlignment(Pos.CENTER);
         tab.setContent(hbox);
         tabPane.getTabs().add(tab);

         final Label decoration = new Label("Tab" + i);
         tab.setGraphic(decoration);
         System.out.println("tab.getGraphic() = " + tab.getGraphic());
         final PopOver popOver = new PopOver();
         popOver.setArrowLocation(ArrowLocation.TOP_LEFT);
         final ImageView preview = new ImageView();
         preview.setFitHeight(100);
         preview.setSmooth(true);
         preview.setPreserveRatio(true);
         popOver.setContentNode(preview);

         popMap.put(decoration, popOver);
         final int index = i;
         decoration.setOnMouseEntered(mouseEvent -> {

            PopOver lPop = popMap.get((Label) mouseEvent.getSource());

            boolean show = false;
            if(lastPeek != tab) {
               // Show PopOver when mouse enters label
               Image previewImage = peek.get(tab);
               if(previewImage != null) {
                  show = true;
               }
               System.out.println("previewImage = " + previewImage);
               preview.setImage(previewImage);
               System.out.println("show() " + "Tab" + index);

            }
            if(!tab.isSelected() && !tab.isDisabled() && show) {
               lPop.show((Node) mouseEvent.getSource(), -decoration.getHeight() / 2);
            }
         });

         tab.getGraphic().setOnMouseExited(mouseEvent -> {
            // Hide PopOver when mouse exits label
            // how can we handle this correct??
            PopOver lPop = popMap.get((Label) mouseEvent.getSource());
            if(lPop.isShowing())
               lPop.hide();
            System.out.println("hide() " + "Tab" + index);
         });

      }

      tabPane.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>() {

         @Override
         public void changed(ObservableValue<? extends Tab> ov, Tab oldTab, Tab newTab) {
            Image preview = oldTab.getContent().snapshot(new SnapshotParameters(), null);
            peek.set(oldTab, preview);
         }
      });
      tabPane.selectionModelProperty().addListener(new ChangeListener<SingleSelectionModel<Tab>>() {

         @Override
         public void changed(ObservableValue<? extends SingleSelectionModel<Tab>> ov,
               SingleSelectionModel<Tab> oldValue, SingleSelectionModel<Tab> newValue) {
         }
      });

      // bind to take available space
      borderPane.prefHeightProperty().bind(scene.heightProperty());
      borderPane.prefWidthProperty().bind(scene.widthProperty());

      borderPane.setCenter(tabPane);
      root.getChildren().add(borderPane);
      primaryStage.setScene(scene);
      primaryStage.show();
   }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

记住使用会话打开的选项卡及其内容

来自分类Dev

识别JavaFX选项卡

来自分类Dev

如何使用FXML在JavaFX中动态创建选项卡?

来自分类Dev

JavaFX-TabPane / Tab如何添加填充选项卡大小的内容?

来自分类Dev

Javafx如何动态地向fxml文件中的现有选项卡添加内容

来自分类Dev

使用 Bootstrap 选项卡时选项卡内容不会改变

来自分类Dev

更改JavaFx选项卡的默认外观

来自分类Dev

JavaFX-选项卡中的FXML

来自分类Dev

更改JavaFx选项卡的默认外观

来自分类Dev

JavaFX Scene Builder定制选项卡

来自分类Dev

JavaFX 禁用选项卡导航

来自分类Dev

如何使用$ stateProvider更改选项卡的内容?

来自分类Dev

使用 MaterializeCSS 更改选项卡内容的背景颜色

来自分类Dev

使用 AdornerDecorator 包装 AvalonDock 选项卡内容

来自分类Dev

如何使用 js/css 使选项卡内容可见

来自分类Dev

Javafx如何动态地将内容添加到fxml文件中的现有选项卡

来自分类Dev

来自ControlFX的JavaFX PopOver

来自分类Dev

设置JavaFX Popover的样式

来自分类Dev

jquery 选项卡 - 在选项卡内的导航中保存选项卡内容

来自分类Dev

使用ng-show时,ui-bootstrap选项卡显示不正确的选项卡内容

来自分类Dev

如何通过外部事件处理程序使用JavaFX更改选项卡?

来自分类Dev

使用JFoenix框架JavaFX的变化密切选项卡按钮的颜色

来自分类Dev

将按钮添加到选项卡和选项卡区域JavaFX

来自分类Dev

javafx的先前选项卡会影响最新的选项卡

来自分类Dev

PyQt5将选项卡调整为其内容

来自分类Dev

我可以按其内存和CPU使用情况列出firefox中的选项卡,并找到使用最多的选项卡吗?

来自分类Dev

通过可编辑单元格的JavaFX选项卡

来自分类Dev

JavaFX ContextMenu加速器从错误的选项卡启动

来自分类Dev

JavaFx-SceneBuilder中的选项卡顺序

Related 相关文章

  1. 1

    记住使用会话打开的选项卡及其内容

  2. 2

    识别JavaFX选项卡

  3. 3

    如何使用FXML在JavaFX中动态创建选项卡?

  4. 4

    JavaFX-TabPane / Tab如何添加填充选项卡大小的内容?

  5. 5

    Javafx如何动态地向fxml文件中的现有选项卡添加内容

  6. 6

    使用 Bootstrap 选项卡时选项卡内容不会改变

  7. 7

    更改JavaFx选项卡的默认外观

  8. 8

    JavaFX-选项卡中的FXML

  9. 9

    更改JavaFx选项卡的默认外观

  10. 10

    JavaFX Scene Builder定制选项卡

  11. 11

    JavaFX 禁用选项卡导航

  12. 12

    如何使用$ stateProvider更改选项卡的内容?

  13. 13

    使用 MaterializeCSS 更改选项卡内容的背景颜色

  14. 14

    使用 AdornerDecorator 包装 AvalonDock 选项卡内容

  15. 15

    如何使用 js/css 使选项卡内容可见

  16. 16

    Javafx如何动态地将内容添加到fxml文件中的现有选项卡

  17. 17

    来自ControlFX的JavaFX PopOver

  18. 18

    设置JavaFX Popover的样式

  19. 19

    jquery 选项卡 - 在选项卡内的导航中保存选项卡内容

  20. 20

    使用ng-show时,ui-bootstrap选项卡显示不正确的选项卡内容

  21. 21

    如何通过外部事件处理程序使用JavaFX更改选项卡?

  22. 22

    使用JFoenix框架JavaFX的变化密切选项卡按钮的颜色

  23. 23

    将按钮添加到选项卡和选项卡区域JavaFX

  24. 24

    javafx的先前选项卡会影响最新的选项卡

  25. 25

    PyQt5将选项卡调整为其内容

  26. 26

    我可以按其内存和CPU使用情况列出firefox中的选项卡,并找到使用最多的选项卡吗?

  27. 27

    通过可编辑单元格的JavaFX选项卡

  28. 28

    JavaFX ContextMenu加速器从错误的选项卡启动

  29. 29

    JavaFx-SceneBuilder中的选项卡顺序

热门标签

归档