2015-02-23 58 views
2

是否可以更改JavaFX TextArea的默认行为,以便按下Tab将焦点传递给下一个组件?JavaFX 8 TextArea松散焦点在标签

+0

[JavaFX的文本区Tab键导航]的可能的复制(https://stackoverflow.com/questions/12860478/tab-key-navigation-in-javafx-textarea) – MarcG 2017-12-05 04:29:16

回答

5

虽然@ItachiUchiha解决方案工作,他指出,这取决于在布局(box他样品)。

根据此question,无论布局如何,都可以修改TextArea的默认行为。

但是,您需要使用这个私有API,这可能会随时更改,恕不另行通知。

在此示例中,TabShitf+Tab将具有所需行为,而Ctrl+Tab将在文本区域插入"\t"

@Override 
public void start(Stage primaryStage) { 
    TextArea area = new TextArea(); 
    area.addEventFilter(KeyEvent.KEY_PRESSED, (KeyEvent event) -> { 
     if (event.getCode() == KeyCode.TAB) { 
      TextAreaSkin skin = (TextAreaSkin) area.getSkin(); 
      if (skin.getBehavior() instanceof TextAreaBehavior) { 
       TextAreaBehavior behavior = (TextAreaBehavior) skin.getBehavior(); 
       if (event.isControlDown()) { 
        behavior.callAction("InsertTab"); 
       } else if (event.isShiftDown()) { 
        behavior.callAction("TraversePrevious"); 
       } else { 
        behavior.callAction("TraverseNext"); 
       } 
       event.consume(); 
      } 
     } 
    }); 

    VBox root = new VBox(20, new Button("Button 1"), area, new Button("Button 2")); 

    Scene scene = new Scene(root, 400, 300); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 
+0

不中的Java 9工作(2017),因为你不能'skin.getBehavior()'。 – MarcG 2017-12-05 04:31:11

1

那么,你绝对可以做到这一点,但它取决于TextArea添加到的布局。我创建了一个简单的示例,其中一个TextArea和一个TextField都被添加到VBox。有一个keyEventHandler它会监视TextAreakeyPress事件并发送focus下一个孩子(如果有的话)

import java.util.Iterator; 

import javafx.application.Application; 
import javafx.event.EventHandler; 
import javafx.scene.Node; 
import javafx.scene.Scene; 
import javafx.scene.control.TextArea; 
import javafx.scene.control.TextField; 
import javafx.scene.input.KeyCode; 
import javafx.scene.input.KeyEvent; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 

public class TextAreaTabFocus extends Application { 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     VBox box = new VBox(); 
     TextArea textArea = new TextArea(); 
     TextField textField = new TextField(); 
     box.getChildren().addAll(textArea, textField); 

     final EventHandler<KeyEvent> keyEventHandler = 
       keyEvent -> { 
        if (keyEvent.getCode() == KeyCode.TAB) { 
         Iterator<Node> itr = box.getChildren().iterator(); 
         while(itr.hasNext()) { 
          if(itr.next() == keyEvent.getSource()) { 
           if(itr.hasNext()){ 
            itr.next().requestFocus(); 
           } 
           //If TextArea is the last child 
           else { 
            box.getChildren().get(0).requestFocus(); 
           } 
           break; 
          } 
         } 
         keyEvent.consume(); 
        } 
       }; 
     textArea.setOnKeyPressed(keyEventHandler); 

     Scene scene = new Scene(box, 200, 200); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

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