2013-03-13 46 views
2

On JavaFX: How to change the focus traversal policy? Alexander Kirov演示瞭如何爲JavaFX應用程序定製焦點遍歷策略。它工作正常,但不適用於TitledPane s。如果TitledPane中的節點具有焦點,則不會調用設置的TraversalEngineTitledPane中的焦點遍歷策略

這是一個完整的例子來說明這一現象:

package org.example; 

import com.sun.javafx.scene.traversal.Direction; 
import com.sun.javafx.scene.traversal.TraversalEngine; 

import javafx.application.Application; 
import javafx.scene.Node; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.TitledPane; 
import javafx.scene.layout.Pane; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 

public class FocusTest extends Application { 
    @Override 
    public void start(Stage primaryStage) throws Exception { 
     // Create UI 
     final VBox root = new VBox(); 
     final Button foo = new Button("foo"); 
     foo.setId("foo"); 
     root.getChildren().add(foo); 
     final Button bar = new Button("bar"); 
     bar.setId("bar"); 
     final Pane content = new Pane(); 
     content.getChildren().add(bar); 
     final TitledPane tp = new TitledPane("tp", content); 
     root.getChildren().add(tp); 

     // Set TraversalEngine 
     final TraversalEngine te = new TraversalEngine(root, false) { 
      @Override 
      public void trav(Node owner, Direction direction) { 
       System.out.printf("trav owner: %s, direction: %s%n", 
         owner.getId(), direction); 
       switch (direction) { 
       case DOWN: 
       case RIGHT: 
       case NEXT: 
        if (owner == foo) { 
         bar.requestFocus(); 
        } else if (owner == bar) { 
         foo.requestFocus(); 
        } 
        break; 
       case LEFT: 
       case PREVIOUS: 
       case UP: 
        if (owner == foo) { 
         bar.requestFocus(); 
        } else if (owner == bar) { 
         foo.requestFocus(); 
        } 
        break; 
       } 
      } 
     }; 
     root.setImpl_traversalEngine(te); 

     // Show Scene 
     final Scene scene = new Scene(root); 
     primaryStage.setHeight(200); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

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

現場的根是一個VBox和自定義TraversalEngine設置它。如果按鈕foo有焦點,並且我按[Tab],則調用te.trav並將焦點設置爲bar。這就是我的預期。但是當bar有重點時,te.trav未被調用。 barTitledPane的子女。此行爲顯示在1中。

有沒有人爲此提供解決方案?

Focus Traversal in TitledPane

回答

1

這是一個棘手的解決方案,與TitledPane小號涉及:

@SuppressWarnings("deprecation") 
private static void registerTraversalEngine(final Parent parent, 
     final TraversalEngine te) { 
    parent.setImpl_traversalEngine(te); 
    for (Node child : parent.getChildrenUnmodifiable()) { 
     if (child instanceof Parent) { 
      registerTraversalEngine((Parent) child, te); 
     } 
    } 
    if (parent instanceof TitledPane) { 
     final TitledPane tp = (TitledPane) parent; 
     if (tp.getContent() instanceof Parent) { 
      registerTraversalEngine((Parent) tp.getContent(), te); 
     } 
    } 
} 

我覺得跟TitltedPane S上的問題是,內容是不是在設置兒童:

TitledPane.getChildrenUnmodifiable().contains(TitledPane.getContent()) is always false 
0

我在該字段中保存了fx:id:

nombreDelPropietario.setUserData("#rbTodos"); 

我設置在操作事件這樣的功能:

public void procesaEnter(ActionEvent event) { 

     /* Obtiene el Objeto que recibió el Enter */ 

     Node source = (Node) event.getSource(); 

     /* Obtiene el ID del objeto al que hay que ir */ 

     String idDestino = (String) source.getUserData(); 

     /* Si está informado */ 

     if (idDestino != null) { 

      /* Recupera el Nodo */ 

      Node destino = (Node) ((Scene) source.getScene()).lookup(idDestino); 

      /* Si está el nodo activo, accede al nodo seleccionado */ 

      if (destino != null) { 
       destino.requestFocus(); 
      } 

     } 

    } 
0

如果你想專注於組件是Swing的一個,你只需要重載其requestFocus()方法回調其SwingNode父級。沒有更多:

SwingNode n = new SwingNode() { 

     @Override 
     public void requestFocus() { 
      System.err.println("SwingNode.requestFocus "); // just to check 
      super.requestFocus(); 
     } 
    }; 
    JTextArea p = new JTextArea() { 

     @Override 
     public void requestFocus() { 
      System.err.println("JTextArea.requestFocus"); 
      n.requestFocus(); // <- HERE IS THE TRICK: use SwingNode focus instead of Swing component one 
     } 
    }; 
    n.setContent(p);