JavaFx自定義Tab-Order



title: JavaFx自定義Tab-Order

Tab-order是什么?在界面上當你按tab鍵觸發焦點轉移的功能,這就是tab order。但是Javafx有個缺陷就是不方便自己設置tab-order的順序。

15年JDK爆出這個bug,有人提過:

  1. https://bugs.openjdk.java.net/browse/JDK-8090501
  2. https://bugs.openjdk.java.net/browse/JDK-8091673

最后JDK中迫不得已臨時把Parent類中的私有方法setImpl_traversalEngine設置為了public,讓用戶可以設置Node自己的tab-order順序。

相關解決方案 stackoverflow

示例:

  1. fxml文件
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.VBox?>
<?import java.net.URL?>
<BorderPane fx:id="root" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1"
            fx:controller="com.cmlanche.easymvvmfx.ui.login.LoginView">
    <center>
        <Label style="-fx-font-size: 32" text="hello world"/>
    </center>

    <bottom>
        <VBox fx:id="testbox">
            <Button fx:id="btn" text="tray">
            </Button>
            <TextField fx:id="t1"/>
            <TextField fx:id="t2"/>
            <TextField fx:id="t3"/>
        </VBox>

    </bottom>

</BorderPane>
  1. Controller文件
package com.cmlanche.easymvvmfx.ui.login;

import com.fx.base.mvvm.BaseView;
import com.sun.javafx.scene.traversal.Algorithm;
import com.sun.javafx.scene.traversal.Direction;
import com.sun.javafx.scene.traversal.ParentTraversalEngine;
import com.sun.javafx.scene.traversal.TraversalContext;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import tray.notification.NotificationType;
import tray.notification.TrayNotification;

/**
 * Created by cmlanche on 2016/12/9.
 */
public class LoginView extends BaseView<LoginViewModel> {

    @FXML
    Button btn;
    @FXML
    TextField t1;
    @FXML
    TextField t2;
    @FXML
    TextField t3;
    @FXML
    VBox testbox;


    @Override
    protected void onViewCreated() {
        t2.setFocusTraversable(true);
        t2.requestFocus();

        testbox.setImpl_traversalEngine(new ParentTraversalEngine(testbox, new Algorithm() {
            @Override
            public Node select(Node owner, Direction dir, TraversalContext context) {
                if ("t2".equals(owner.getId())) {
                    return t3;
                } else if ("t3".equals(owner.getId())) {
                    return t1;
                } else if ("t1".equals(owner.getId())) {
                    return btn;
                } else {
                    return t2;
                }
            }

            @Override
            public Node selectFirst(TraversalContext context) {
                return t2;
            }

            @Override
            public Node selectLast(TraversalContext context) {
                return t1;
            }
        }));
    }
}

原來的tab-order順序是btn->t1->t2->t3,現在的順序是t2->t3->t1->btn

javafx-taborder

需要注意的是

  1. setImpl_traversalEnginedeprecated方法,以后可能廢棄的api
  2. LoginView是我的框架easyMvvmFx構建的控制器,不能直接放在你代碼中運行。
歡迎加我的qq群探討JavaFx 最大最活躍的JavaFx社群 518914410


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM