JavaFX8의 TableView에서 JDK-88144681 오류 방지

4073 단어 JavaFXtableViewJava
JavaFX8로 비즈니스 애플리케이션을 만들 때 밟은 버그JDK-8144681.
제가 취한 회피 대책과 원본 코드를 소개하겠습니다.

1. 질문 JDK-88144681은?

javafx.scene.control.TableView<S>에서 열을 재배열할 때 발생하는 문제.

전제 조건

  • 여러 TableView의 셀 선택(SelectionMode.MULT IPLE) 허용
  • 재현 순서

  • 여러 TableView 데이터 셀 선택
  • 머리글 셀을 드래그하여 열을 정렬
  • → 드래그 앤 드롭 시 ArrayIndexOutOfBoundsException 발생

    2. 회피 전략


    JavaFX8 라이브러리의 소스 코드 때문에 근본 원인을 수정하기가 어렵습니다.
    따라서 예외가 발생하지 않도록 기피 대책이 필요하다.
  • 열 재배열 비활성화
  • 열을 재배열하기 전에 선택 해제
  • 열의 재배열 이벤트 발생 시 선택 해제
  • 이번에는 열을 다시 배열하기 전에 선택상태를 해제하는 대책을 채택했다.

    채용하지 않는 이유


    사용할 수 없음


    말하자면 다시 배열하지 않으면 일어나지 않을 거야!
    그러나 JavaFX8의 TableView 기본 동작인 정렬 기능을 사용할 수 없게 되면 가용성이 떨어집니다.그래서 이번에 나는 이 방안을 포기했다.

    이벤트 발생 시 상태 선택 취소


    조사 결과 열을 다시 배열할 때'다시 배열'을 나타내는 활동이 발생하지 않았다는 것을 알게 됐다.
    그래서 바늘로 잡고 다시 배열하지 못한 동작

    3. 소스 코드


    드래그 사건은 대원 TableView에서 발생했습니다.
    다른 드래그 이벤트와 구별하기 위해서, 이벤트 원본이 헤더에 속하는지 확인하고 작업을 실행합니다.
    FxApplication.java
    // [JDK-8144681] 不具合回避のため reordering直前にselect/focusを解除する
    tableView.addEventFilter(MouseEvent.MOUSE_DRAGGED, event -> {
        boolean isHeaderNode = false;
    
        // 親ノードを探索し TableColumnHeaderに属しているかを調べる
        for (Node node = (Node) event.getTarget() ; ; node = node.getParent()) {
            if(node == null || node instanceof TableView) {
                break;
            }
            if(node instanceof TableColumnHeader){
                isHeaderNode = true;
                break;
            }
        }
        if(! isHeaderNode) return;
    
        tableView.getSelectionModel().clearSelection();
        tableView.getFocusModel().focus(-1);
    });
    

    총결산


    상당히 제한된 조건에서 발생한 문제지만 JDK8에서 타블뷰를 사용하면 반드시 발생할 것이기 때문에 대책상 손해는 없을 것이라고 생각한다.

    좋은 웹페이지 즐겨찾기