2017-02-23 13 views
14

Tôi cố gắng để làm việc xung quanh lỗi này trong jdk: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8088624hiển thị một tooltip trong JavaFX mang lại sân khấu của mình vào foreground

public class Blubb extends Application { 
    public static void main(String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     Button btn = new Button("Click"); 
     btn.setTooltip(new Tooltip("Blubb")); 

     Scene scene = new Scene(new BorderPane(btn), 320, 240); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 

     Stage secondStage = new Stage(); 
     secondStage.setScene(new Scene(new BorderPane(new Button("Click")), 320, 240)); 
     //secondStage.initOwner(primaryStage); 
     secondStage.show(); 
    } 
} 

Nếu nút trên sân khấu chính được bay lượn, nó sẽ đến trước giai đoạn thứ hai. Tôi thấy rằng việc gọi initOwner() trên một Giai đoạn sẽ loại bỏ hành vi này.

Bây giờ vấn đề của tôi là sau: Tôi có nhiều "cửa sổ bật lên" có chủ sở hữu chung (giai đoạn chính). Di chuột qua các điều khiển trên giai đoạn chính không gây ra bất kỳ hành vi không mong muốn nào sau giải pháp initOwner(). Tuy nhiên, nếu bạn di chuột qua các điều khiển trong cửa sổ bật lên trong khi một cửa sổ bật lên khác đang được lấy nét, cửa sổ bật lên được di chuột sẽ lấy nét.

Có cách nào tôi có thể khắc phục lỗi này không chỉ cho giai đoạn chính mà còn cả các cửa sổ bật lên?

CẬP NHẬT: tắt cách giải quyết của tôi có tác dụng phụ không mong muốn. Javadocs cho trạng thái Giai đoạn sau:

Giai đoạn sẽ luôn ở trên cùng cửa sổ chính.

Vì vậy, bổ sung, điều gì sẽ là giải pháp thay thế khiến cửa sổ bật lên không "luôn ở trên cùng" và có thể thu nhỏ tối đa?

Trả lời

4

Có một cách để giải quyết vấn đề này bằng cách chồng lên StackPanes. Tạo Scene của bạn với StackPane để bạn có thể thêm StackPane khi sân khấu bị mất trọng tâm. Ngăn xếp chồng lên nhau sẽ ngăn chặn Tooltip s hoặc bất kỳ điều gì khác xảy ra khi di chuột qua trong khi ngăn không được lấy nét. Bạn cũng có thể giảm thiểu bất kỳ giai đoạn nào của bạn và chúng sẽ không luôn luôn trên đầu.

public class Blubb extends Application { 

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

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     Button button_1 = new Button("Button #1"); 
     button_1.setTooltip(new Tooltip("Blubb #1")); 

     StackPane primary = new StackPane(new BorderPane(button_1)); 
     primaryStage.setScene(new Scene(primary, 320, 240)); 
     addStageFocusListener(primaryStage, primary); 
     primaryStage.show(); 

     Button button_2 = new Button("Button #2"); 
     button_2.setTooltip(new Tooltip("Blubb #2")); 

     StackPane second = new StackPane(new BorderPane(button_2)); 
     Stage secondStage = new Stage(); 
     addStageFocusListener(secondStage, second); 
     secondStage.setScene(new Scene(second, 320, 240)); 
     secondStage.show(); 
    } 

    public void addStageFocusListener(Stage stage, StackPane stackPane) { 
     stage.focusedProperty().addListener(new ChangeListener<Boolean>(){ 
      public final StackPane preventTooltip = new StackPane(); 
      public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { 
       if(stage.isFocused()) { 
        if(stackPane.getChildren().contains(preventTooltip)) { 
         stackPane.getChildren().remove(preventTooltip); 
        } 
       } else { 
        stackPane.getChildren().add(preventTooltip); 
       } 
      } 
     }); 
    } 
} 
+0

Cảm ơn bạn đây là một giải pháp thực sự tuyệt vời hoạt động tốt với một số lượng lớn các chú giải công cụ! – Selim

1

Bạn có thể thử bỏ chú giải công cụ bất cứ khi nào cửa sổ nút mất tiêu điểm. Chẳng hạn như bên dưới:

public class Blubb extends Application { 
    public static void main(String[] args) { 
     launch(args); 
    } 

    public static void installTooltip(Node n, Tooltip tp) 
    { 
     Window w = n.getScene().getWindow(); 
     w.focusedProperty().addListener((val, before, after) -> { 
      if (after) 
       Tooltip.install(n, tp); 
      else 
       Tooltip.uninstall(n, tp); 
     }); 

     if (w.isFocused()) 
      Tooltip.install(n, tp); 
     else 
      Tooltip.uninstall(n, tp); 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     Tooltip tp = new Tooltip("Blubb"); 
     Button btn = new Button("Click"); 

     Scene scene = new Scene(new BorderPane(btn), 320, 240); 
     primaryStage.setScene(scene); 
     //primaryStage.show(); 

     Stage secondStage = new Stage(); 
     secondStage.setScene(new Scene(new BorderPane(new Button("Click")), 320, 240)); 
     //secondStage.initOwner(primaryStage); 
     secondStage.show(); 
     primaryStage.show(); 

     installTooltip(btn, tp); 
    } 
} 

Tất nhiên, bạn sẽ phải gọi installTooltip sau khi nút được thêm vào thành phần.

3

Bạn có thể thử này:

public static final disableMouseEventOnUnfocus(final Stage stage) 
{ 
    if (stage == null 
     || stage.getScene() == null 
     || stage.getScene().getRoot() == null) 
     return; 
    else 
    { 
     stage.getScene().getRoot().mouseTransparentProperty().bind(stage.focusedProperty().not()); 
    } 
} 

Tôi không thử nó mặc dù, nhưng nếu nó hoạt động, đây sẽ là một lựa chọn tốt. Không cần phải cấu trúc lại bố cục của bạn và bạn có thể để lại tất cả bố cục trong FXML, mà không chỉ định fx:id cho các chú giải công cụ.

+0

Điều này hoạt động và thực sự súc tích! – Selim

2

Tôi đã đưa ra giải pháp thay thế này, vì tôi thấy dễ dàng hơn trong trường hợp của tôi để phân lớp Tooltip và áp dụng sửa chữa ở đó. Tôi chỉ cần quá tải phương thức show() để chỉ hiển thị nếu cửa sổ đang sở hữu được tập trung. Nó hoạt động giống như một sự quyến rũ đối với tôi ...

public class FixedTooltip extends Tooltip { 

    public FixedTooltip(String string) { 
     super(string); 
    } 

    @Override 
    protected void show() {   
     Window owner = getOwnerWindow();   
     if (owner.isFocused()) 
      super.show(); 
    }  

} 
+0

Điều này thậm chí giữ lại các sự kiện liên quan đến chuột như di chuột, nhập, thoát. Giải pháp tốt! – Selim

Các vấn đề liên quan