2012-11-20 5 views
0

테이블보기가 있고 그 안에는 TextField로 채워진 하나의 열이 있습니다.스크롤 후 TableView가 사라지는 TextField JavaFX

데이터가 거의없고 테이블에 스크롤 막대가 없어도 모든 TextField가 나타납니다.

테이블을 아래로 스크롤 한 다음 다시 올라가면 일부 TextField가 누락됩니다. 정말 감사

purchaseQtyCol.setCellFactory(
       new Callback<TableColumn< TransactionModel, TextField>, TableCell< TransactionModel, TextField>>() { 
        @Override 
        public TableCell< TransactionModel, TextField> call(final TableColumn< TransactionModel, TextField> p) { 
         TableCell<TransactionModel, TextField> cell = new TableCell<TransactionModel, TextField>() { 


          @Override 
          public void updateItem(TextField item, boolean empty) { 
           super.updateItem(item, empty); 
           if (item != null) { 
            /** 
            * for(CheckBox cbb : canceledCB) { 
            * if(item.equals(cbb)) 
            * System.out.println("aa" + 
            * this.indexProperty().getValue() + " " + 
            * item.isSelected()); }* 
            */ 
            this.setGraphic(item); 
           } 

          } 

         }; 

         cell.setAlignment(Pos.CENTER); 
         return cell; 
        } 
       }); 

     purchaseQtyCol.setCellValueFactory(new Callback<CellDataFeatures<TransactionModel, TextField>, ObservableValue<TextField>>() { 
      @Override 
      public ObservableValue<TextField> call(final CellDataFeatures<TransactionModel, TextField> p) { 

        System.out.println("new textfield"); 
        final TextField qtyField = new TextField() { 
         @Override 
         public void replaceText(int start, int end, String text) { 

          if (text.matches("[0-9]") || text.equals("")) { 
           super.replaceText(start, end, text); 
           if (this.getText().isEmpty()) { 
            p.getValue().setPurchaseQty(0); 
            p.getValue().setTotalPrice(0); 
           } else { 
            p.getValue().setPurchaseQty(Integer.parseInt(this.getText())); 
            p.getValue().setTotalPrice(p.getValue().purchaseQtyProperty().intValue() * p.getValue().basePriceProperty().intValue()); 
           } 
           recountTotals(); 
          } 
         } 

         @Override 
         public void replaceSelection(String text) { 

          if (text.matches("[0-9]") || text.equals("")) { 
           super.replaceSelection(text); 
           if (this.getText().isEmpty()) { 
            p.getValue().setPurchaseQty(0); 
            p.getValue().setTotalPrice(0); 
           } else { 
            p.getValue().setPurchaseQty(Integer.parseInt(this.getText())); 
            p.getValue().setTotalPrice(p.getValue().purchaseQtyProperty().intValue() * p.getValue().basePriceProperty().intValue()); 
           } 
           recountTotals(); 
          } 
         } 
        }; 

        qtyField.setText("" + p.getValue().purchaseQtyProperty().getValue()); 
        qtyField.setAlignment(Pos.CENTER_RIGHT); 

       return new SimpleObjectProperty(qtyField); 
      } 
     }); 

너희들로부터 도움 :

다음은 텍스트 필드로 채워진 컬럼 내 코드입니다.

감사합니다,

Chrisma Andhika

답변

1

Chrisma! 사용자가 직면하는 문제는 JavaFX가 tableview에서 항목을 업데이트하는 것과 관련된 유명한 문제입니다. 이미 그것에 대한 해결 방법이 있습니다 (예 : here). 이 솔루션은

tableview.getColumns().get(0).setVisible(false); 
tableview.getColumns().get(0).setVisible(true); 

가있는 tableview의 내부 업데이트 메커니즘을 트리거하는 것이었다 그러나 지금까지의 내가이 솔루션을 데이터의 영향만을 변화의 tableview의 노드가 아닌 스타일을 이해할 수있다.

나는 또한 내 구현
@Override 
public void updateItem(Object item, boolean empty) 

을 사용하지만, 테이블 및 스크롤 막대에 너무 많은 행이있을 때 행의 갱신이 절대 엉망이되었다 나타나 있기 때문에, 충분하지 않았다.

내가 필요한 것은 모두 이 보이도록 행이 CSS를 사용하여 몇 가지 기준을 만족시키는 것으로 강조 표시하는 것입니다. 나는 다음과 같은 방법으로 그것을 달성 :

Callback<TableView<Person>, TableRow<Person>> callBack = 
    new Callback<TableView<Person>, TableRow<Person>>() { 
     @Override 
     public TableRow<Person> call(TableView<Person> tableView) { 
       final TableRow<Person> row = new TableRow<Person>() { 
        @Override 
        public void updateItem(Person item, boolean empty) { 
          super.updateItem(item, empty); 
          if(!empty && item.getFirstName() == "John") { 
           getStyleClass().add("john"); 
          } 
        } 
       }; 
       row.visibleProperty().addListener(new ChangeListener() { 
        @Override 
        public void changed(ObservableValue observableValue, Object t, Object t1) { 
         Boolean oldValue = (Boolean)t; 
         Boolean newValue = (Boolean)t1; 
         if(oldValue && !newValue) { 
          row.getStyleClass().remove("john"); 
         } 
         if(!oldValue && newValue) { 
          if(row.getItem().getFirstName() == "John") 
           row.getStyleClass().add("john"); 
         } 
        } 
       }); 
       return row; 
     } 
}; 
tableview.setRowFactory(callBack); 

CSS 파일은 다음 행을 포함해야합니다 : 물론

.john { 
-fx-background-color: forestgreen; 
-fx-text-fill: white; 
-fx-border-style: solid; 
} 

당신은 행의 다른 스타일을 선택할 수 있습니다. 당신은 내가 각 행의 CSS의 동작을 제어하는 ​​행의 VisibleProperty에 리스너를 추가 볼 수 있듯이

Person 클래스는

public SimpleStringProperty firstNameProperty() { 
    return firstName; 
} 

을 포함해야합니다. 어쩌면이 아이디어는 행 스타일링이 아닌 테이블 뷰에서 데이터 업데이트를 해결하는 데 도움이 될 수 있습니다.

위의 코드에서 NullPointerExceptionpublic void changed 메서드로 받기 시작했음을 추가해야하지만, 내 프로그램의 결과에는 영향을주지 않습니다.

나는 그것이 당신을 도울 것이라는 희망, Chrisma! 그리고 다른 사람들도!

0

방금 ​​확인란에 문제가있었습니다. 그들은 큰 테이블을 빠르게 스크롤 할 때 무작위로 사라졌습니다.난 그냥 내 cellFactory에서이 줄을 삭제하여 그것을 해결 :

@Override 
    public void updateItem(Boolean item, boolean empty) { 
     super.updateItem(item, empty); 
     if (empty) { 
      setText(null); 
      // setGraphic(null); (This line causes weird behaviour in scrolling, delete it) 
     } else { 
      checkBox.setSelected(item); 
     } 
    } 
0

글쎄, 나는 또한 명백하게 만 보이는 텍스트 필드를 그릴, 같은 문제를 가지고 우리는 장면을 그리기 때문에, 표시되지 않습니다 스크롤을 사용할 때 하지만 textinputcontrol, 그래서 내 해결책은 스크롤 이벤트를 캡처하고 텍스트 필드의 크기를 조정하고 원래 크기로, 따라서 개체를 다시 칠해 강제로 그것을 사용하여 지금은 textinputcontrol.forcing 개체를 다시 칠해와 함께 표시됩니다 textinputcontrol과 함께 나타납니다.

tableview.addEventFilter(ScrollEvent.ANY, new EventHandler<ScrollEvent>() { 
     @Override 
     public void handle(ScrollEvent scrollEvent) { 
      System.out.println("Scrolled."); 
      for(ObservableList<TextField> i:data) 
        { 
        for(TextField j: i) 
        { 
        j.setPrefSize(141, 31); 
        j.setPrefSize(140, 30); 
        } 
        } 
     } 
}); 
관련 문제