programing

JavaFX 2.1 TableView 새로 고침 항목

nasanasas 2020. 12. 10. 20:29
반응형

JavaFX 2.1 TableView 새로 고침 항목


나는이 일반적인 문제가있는 것처럼 보입니다. 항목을 재설정 한 후 테이블보기가 항목을 새로 고치지 않습니다. 나는 데이터를 확인했고 그것은 새로운 것입니다.

인터넷에서 여러 솔루션을 시도했지만 성공하지 못했습니다.

빈 하나를 추가하고 (이유를 알지 못함) 크기 조정이 중단되기 때문에 모든 열을 재설정 할 수 없습니다.

내 테이블은 편집 할 수 없습니다 . 새 데이터가 변경됩니다.

항목 의 순서 를 변경하고 행이 변경되면 (: |) 데이터가 새로 고쳐집니다 .

나는 단지 아이디어없이 남겨졌다.

현재 새로 고침 코드는 매우 간단합니다.

ObservableList<User> data = FXCollections.observableArrayList(User.getResellers());
reseller_table.setItems(data);

다시 새 데이터가 정확합니다. tableView를 선택하면 새 올바른 항목이 반환됩니다.


나는 상쾌함과 비슷한 문제가 있었다. 내 해결책은에서 ObservableList올바르게 작동하는 작업으로 작업 을 제한하는 것이 었 습니다 bind().

ObservableList obsList의 기본 목록 이라고 가정 합니다 TableView.

그런 다음
obsList.clear() (에서 상속이 java.util.List<>됩니다) 업데이트하지TableView올바르게하지만.

또한 호출 setItem(obsList)새로 고침을 트리거하는 데 작동 하지 않았지만 ...

obsList.removeAll(obsList)(덮어 쓰기 ObservableList) changeEvent를 올바르게 실행하기 때문에 제대로 작동 합니다.

완전히 새로운 콘텐츠로 목록을 채우면 다음과 같이 작동합니다.

  • obsList.removeAll(obsList);
  • obsList.add(...); //e.g. in a loop...

또는

  • obsList.removeAll(obsList);
  • FXCollections.copy(obsList, someSourceList)

감사합니다 Ingo


해결 방법 :

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

JavaFX 8u60사용할 수 있기 때문에 ( TableView 클래스 tableView의 인스턴스 라고 가정 ) :

tableView.refresh();

문서에서 :

refresh ()를 호출하면 TableView 컨트롤이 컨트롤의 시각적 경계를 채우는 데 필요한 셀을 다시 만들고 다시 채 웁니다. 즉, TableView가 사용자에게 표시되는 내용을 업데이트하도록합니다. 이는 기본 데이터 소스가 TableView 자체에서 관찰되지 않는 방식으로 변경된 경우에 유용합니다.


업데이트 :
마지막으로 테이블 뷰 새로 고침이 JavaFX 8u60 에서 해결되었으며 , 조기 액세스가 가능합니다.


새로 고침에 대해서는 Tableview에서 행 업데이트를 참조하십시오 .
빈 열에 대해서는 JavaFx 2에서 단일 열로 TableView를 만듭니다 . 기본적으로 열이 아닙니다. 즉,이 빈 열 항목을 클릭하여 항목을 선택할 수 없습니다. 행처럼 스타일이 지정된 빈 영역입니다.


업데이트 : 를 통해 tableView를 업데이트하는 경우을 reseller_table.setItems(data)사용할 필요가 없습니다 SimpleStringProperty. 하나의 행 / 항목 만 업데이트하는 경우 유용합니다. 다음은 테이블 데이터를 새로 고치는 작업의 전체 예입니다.

import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Dddeb extends Application {

    public static class Product {
        private String name;
        private String code;

        public Product(String name, String code) {
            this.name = name;
            this.code = code;
        }

        public String getCode() {
            return code;
        }

        public void setCode(String code) {
            this.code = code;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    private TableView<Product> productTable = new TableView<Product>();

    @Override
    public void start(Stage stage) {

        Button refreshBtn = new Button("Refresh table");
        refreshBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent arg0) {
                // You can get the new data from DB
                List<Product> newProducts = new ArrayList<Product>();
                newProducts.add(new Product("new product A", "1201"));
                newProducts.add(new Product("new product B", "1202"));
                newProducts.add(new Product("new product C", "1203"));
                newProducts.add(new Product("new product D", "1244"));

                productTable.getItems().clear();
                productTable.getItems().addAll(newProducts);
                //productTable.setItems(FXCollections.observableArrayList(newProducts));
            }
        });

        TableColumn nameCol = new TableColumn("Name");
        nameCol.setMinWidth(100);
        nameCol.setCellValueFactory(new PropertyValueFactory<Product, String>("name"));

        TableColumn codeCol = new TableColumn("Code");
        codeCol.setCellValueFactory(new PropertyValueFactory<Product, String>("code"));

        productTable.getColumns().addAll(nameCol, codeCol);
        productTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

        // You can get the data from DB
        List<Product> products = new ArrayList<Product>();
        products.add(new Product("product A", "0001"));
        products.add(new Product("product B", "0002"));
        products.add(new Product("product C", "0003"));

        //productTable.getItems().addAll(products);
        productTable.setItems(FXCollections.observableArrayList(products));

        final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.getChildren().addAll(productTable, refreshBtn);

        Scene scene = new Scene(new Group());
        ((Group) scene.getRoot()).getChildren().addAll(vbox);
        stage.setScene(scene);
        stage.setWidth(300);
        stage.setHeight(500);
        stage.show();
    }

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

참고

productTable.setItems(FXCollections.observableArrayList(newProducts));

productTable.getItems().clear();
productTable.getItems().addAll(newProducts);

거의 동일합니다. 그래서 처음으로 테이블을 채우는 데 하나를 사용하고 테이블을 새로 고칠 때 다른 하나를 사용했습니다. 데모 목적으로 만 사용됩니다. JavaFX 2.1에서 코드를 테스트했습니다. 마지막으로 질문에 대한 답변의 코드 조각을 이동하여 질문을 수정하여 개선 할 수 있습니다.


마침내 모든 행을 새로 고치는 추악한 해결 방법을 찾았습니다.

void refreshTable() {
    final List<Item> items = tableView.getItems();
    if( items == null || items.size() == 0) return;

    final Item item = tableView.getItems().get(0);
    items.remove(0);
    Platform.runLater(new Runnable(){
        @Override
        public void run() {
            items.add(0, item);
        }
    });
 }

oldItems.equals (newItems)와 관련하여 몇 가지 별도의 문제가있는 것 같습니다.

RT-22463 의 첫 번째 부분 : items.clear ()를 호출해도 tableView가 업데이트되지 않습니다.

// refresh table 
table.getItems().clear();
table.setItems(listEqualToOld);    

수정되었습니다. 새 목록을 설정하기 전에 이전 항목을 지우면 모든 이전 상태가 지워 지므로 테이블이 새로 고쳐집니다. 이것이 작동하지 않는 예는 회귀 일 수 있습니다.

여전히 작동하지 않는 것은 먼저 지우지 않고 항목을 재설정하는 것입니다.

// refresh table
table.setItems(listEqualToOld); 

즉, (예를 참조 테이블 항목의 동일한 결정에 포함되지 않은 특성을 나타내는 경우에 문제가있어 RT-22,463 또는 어빈의 ) 및 커버 - 희망 -하여 RT-39094

업데이트 : RT-390948u40에 대해 후자도 수정되었습니다! u12 등을 추측하면서 몇 주 안에 EA로 버블 링해야합니다.

기술적 인 이유는 셀 구현의 동등성 검사 인 것 같습니다. 성능 문제를 해결하기 위해 실제로 updateItem (T, boolean)을 호출하기 전에 항목의 변경 사항을 확인하는 기능이 도입되었습니다. 합리적이며 "변경"== old.equals (new)를 하드 코딩하면 일부 상황에서 문제가 발생합니다.

나에게 괜찮은 해결 방법 (공식 테스트가 아님!)은 신원 확인이 필요한 경우 뛰어 드는 사용자 지정 TableRow입니다.

/**
 * Extended TableRow that updates its item if equal but not same.
 * Needs custom skin to update cells on invalidation of the 
 * item property.<p>
 * 
 * Looks ugly, as we have to let super doing its job and then
 * re-check the state. No way to hook anywhere else into super 
 * because all is private. <p>
 * 
 * Super might support a configuration option to check against
 * identity vs. against equality.<p>
 * 
 * Note that this is _not_ formally tested! Any execution paths calling
 * <code>updateItem(int)</code> other than through 
 * <code>indexedCell.updateIndex(int)</code> are not handled.
 * 
 * @author Jeanette Winzenburg, Berlin
 */
public class IdentityCheckingTableRow<T>  extends TableRow<T> {

    @Override
    public void updateIndex(int i) {
        int oldIndex = getIndex();
        T oldItem = getItem();
        boolean wasEmpty = isEmpty();
        super.updateIndex(i);
        updateItemIfNeeded(oldIndex, oldItem, wasEmpty);

    }

    /**
     * Here we try to guess whether super updateIndex didn't update the item if
     * it is equal to the old.
     * 
     * Strictly speaking, an implementation detail.
     * 
     * @param oldIndex cell's index before update
     * @param oldItem cell's item before update
     * @param wasEmpty cell's empty before update
     */
    protected void updateItemIfNeeded(int oldIndex, T oldItem, boolean wasEmpty) {
        // weed out the obvious
        if (oldIndex != getIndex()) return;
        if (oldItem == null || getItem() == null) return;
        if (wasEmpty != isEmpty()) return;
        // here both old and new != null, check whether the item had changed
        if (oldItem != getItem()) return;
        // unchanged, check if it should have been changed
        T listItem = getTableView().getItems().get(getIndex());
        // update if not same
        if (oldItem != listItem) {
            // doesn't help much because itemProperty doesn't fire
            // so we need the help of the skin: it must listen
            // to invalidation and force an update if 
            // its super wouldn't get a changeEvent
            updateItem(listItem, isEmpty());
        }
    }


    @Override
    protected Skin<?> createDefaultSkin() {
        return new TableRowSkinX<>(this);
    }


    public static class TableRowSkinX<T> extends TableRowSkin<T> {

        private WeakReference<T> oldItemRef;
        private InvalidationListener itemInvalidationListener;
        private WeakInvalidationListener weakItemInvalidationListener;
        /**
         * @param tableRow
         */
        public TableRowSkinX(TableRow<T> tableRow) {
            super(tableRow);
            oldItemRef = new WeakReference<>(tableRow.getItem());
            itemInvalidationListener = o -> {
                T newItem = ((ObservableValue<T>) o).getValue();
                T oldItem = oldItemRef != null ? oldItemRef.get() : null;
                oldItemRef = new WeakReference<>(newItem);
                if (oldItem != null && newItem != null && oldItem.equals(newItem)) {
                    forceCellUpdate();
                }
            };
            weakItemInvalidationListener = new WeakInvalidationListener(itemInvalidationListener);
            tableRow.itemProperty().addListener(weakItemInvalidationListener);
        }

        /**
         * Try to force cell update for equal (but not same) items.
         * C&P'ed code from TableRowSkinBase.
         */
        private void forceCellUpdate() {
            updateCells = true;
            getSkinnable().requestLayout();

            // update the index of all children cells (RT-29849).
            // Note that we do this after the TableRow item has been updated,
            // rather than when the TableRow index has changed (as this will be
            // before the row has updated its item). This will result in the
            // issue highlighted in RT-33602, where the table cell had the correct
            // item whilst the row had the old item.
            final int newIndex = getSkinnable().getIndex();
            for (int i = 0, max = cells.size(); i < max; i++) {
                cells.get(i).updateIndex(newIndex);
            }
       }

    }

    @SuppressWarnings("unused")
    private static final Logger LOG = Logger
            .getLogger(IdentityCheckingListCell.class.getName());

}

 // usage
 table.setRowFactory(p -> new IdentityCheckingTableRow());

TableCell에는 유사한 하드 코딩 된 동등성 검사가 있으므로 사용자 지정 행이 충분하지 않은 경우 유사한 해결 방법으로 사용자 지정 TableCell을 사용해야 할 수 있습니다 (하지만 필요한 경우 예제에서는 실행되지 않음).


이 스레드 에는 테이블 새로 고침 문제에 대한 매우 좋은 설명 있다고 가정 합니다 .


무슨 버그! 다음은 또 다른 해결 방법입니다.

public void forceRefresh() {
  final TableColumn< Prospect, ? > firstColumn = view.getColumns().get( 0 );
  firstColumn.setVisible( false );
  new Timer().schedule( new TimerTask() { @Override public void run() {
     Platform.runLater( new Runnable() { @Override public void run() {
        firstColumn.setVisible( true  ); }});
     }}, 100 );
}

버그보여주기 위해 SSCCE수행했습니다 . 내 해결 방법이 매우 추악하기 때문에 모든 사람이 더 우아한 방법으로 수정하도록 권장합니다!


Aubin의 솔루션으로 도움이되지 않은 사용 사례가 있습니다. 나는이 방법을 적용하고 테이블의 항목 목록에 항목을 제거하고 추가하여 변경했습니다. 결국이 해킹으로 만 안정적으로 작동하므로 열 표시 토글이 처음에만 작업을 수행했습니다.

Jira 작업에서도보고했습니다 : https://javafx-jira.kenai.com/browse/RT-22463

 public <T> void tableItemsRefresh(final ObservableList<T> items) {

      if (items == null || items.size() == 0)
         return;

      int idx = items.size() -1;
      final T item = items.get(idx);
      items.remove(idx);

      new Timer().schedule(new TimerTask() {
         @Override
         public void run() {
            Platform.runLater(new Runnable() {
               @Override
               public void run() {
                  items.add(item);
               }
            });
         }
      }, 100);
   } 

나는 같은 문제가 있었고 몇 가지 검색 후 이것이 내 해결 방법입니다. 열을 제거한 다음 다시 추가하면 테이블이 업데이트된다는 것을 알았습니다.

public static <T,U> void refreshTableView(final TableView<T> tableView, final List<TableColumn<T,U>> columns, final List<T> rows) {

    tableView.getColumns().clear();
    tableView.getColumns().addAll(columns);

    ObservableList<T> list = FXCollections.observableArrayList(rows);
    tableView.setItems(list);
}


사용 예 :

refreshTableView(myTableView, Arrays.asList(col1, col2, col3), rows);

user1236048의 솔루션은 정확하지만 요점은 언급되지 않았습니다. 테이블의 관찰 가능 목록에 사용되는 POJO 클래스에서 getter 및 setter 메서드를 설정해야 할뿐만 아니라 Property라는 새 메서드를 설정해야합니다. Oracle의 tableview 자습서 ( http://docs.oracle.com/javafx/2/ui_controls/table-view.htm )에서 핵심 부분은 그대로 둡니다 !

Person 클래스는 다음과 같아야합니다.

public static class Person {

    private final SimpleStringProperty firstName;
    private final SimpleStringProperty lastName;
    private final SimpleStringProperty email;

    private Person(String fName, String lName, String email) {
        this.firstName = new SimpleStringProperty(fName);
        this.lastName = new SimpleStringProperty(lName);
        this.email = new SimpleStringProperty(email);
    }

    public String getFirstName() {
        return firstName.get();
    }

    public void setFirstName(String fName) {
        firstName.set(fName);
    }

    public SimpleStringProperty firstNameProperty(){
        return firstName;
    }

    public String getLastName() {
        return lastName.get();
    }

    public void setLastName(String fName) {
        lastName.set(fName);
    }

    public SimpleStringProperty lastNameProperty(){
        return lastName;
    }

    public String getEmail() {
        return email.get();
    }

    public void setEmail(String fName) {
        email.set(fName);
    }

    public SimpleStringProperty emailProperty(){
            return email;
        }

}


Jira에서이 문제를 살펴보세요 : https://bugs.openjdk.java.net/browse/JDK-8098085

댓글 2012-09-20 08:50은 작동하는 해결 방법을 제공했습니다.

//wierd JavaFX bug
reseller_table.setItems(null); 
reseller_table.layout(); 

ObservableList<User> data = FXCollections.observableArrayList(User.getResellers());
reseller_table.setItems(data);

3-4 시간 동안 tableView (ScalaFx)를 새로 고치는 방법을 찾으려고했습니다. 마침내 나는 대답을 얻었다. 이미 몇 시간을 낭비했기 때문에 솔루션을 게시하고 싶습니다.

-데이터베이스에서 행을 검색하기 위해 ObservableBuffer를 반환하는 메서드를 선언했습니다.

내 JDBC 클래스

    //To get all customer details
def getCustomerDetails : ObservableBuffer[Customer] = {

val customerDetails = new ObservableBuffer[Customer]()
  try {

    val resultSet = statement.executeQuery("SELECT * FROM MusteriBilgileri")

    while (resultSet.next()) {

      val musteriId = resultSet.getString("MusteriId")
      val musteriIsmi = resultSet.getString("MusteriIsmi")
      val urununTakildigiTarih = resultSet.getDate("UrununTakildigiTarih").toString
      val bakimTarihi = resultSet.getDate("BakimTarihi").toString
      val urununIsmi = resultSet.getString("UrununIsmi")
      val telNo = resultSet.getString("TelNo")
      val aciklama = resultSet.getString("Aciklama")

      customerDetails += new Customer(musteriId,musteriIsmi,urununTakildigiTarih,bakimTarihi,urununIsmi,telNo,aciklama)

    }
  } catch {
    case e => e.printStackTrace
  }

  customerDetails
}

-그리고 TableView 개체를 만들었습니다.

var table = new TableView[Customer](model.getCustomerDetails)
table.columns += (customerIdColumn,customerNameColumn,productInstallColumn,serviceDateColumn,
        productNameColumn,phoneNoColumn,detailColumn)

-그리고 마침내 해결책을 얻었습니다. 새로 고침 버튼에이 코드를 삽입했습니다.

table.setItems(FXCollections.observableArrayList(model.getCustomerDetails.delegate))

모델은 내 jdbc 연결 클래스의 참조입니다.

val model = new ScalaJdbcConnectSelect

이것은 scalafx 코드이지만 javafx에 대한 아이디어를 제공합니다.


JavaFX8

DialogBox로 새 항목을 추가하고 있습니다. 다음은 내 코드입니다.

ObservableList<Area> area = FXCollections.observableArrayList();

initialize () 또는 setApp ()에서

this.areaTable.setItems(getAreaData());

getAreaData ()

private ObservableList<Area> getAreaData() {
    try {
        area = AreaDAO.searchEmployees(); // To inform ObservableList
        return area;
    } catch (ClassNotFoundException | SQLException e) {
        System.out.println("Error: " + e);
        return null;
    }
}

추가 대화 상자.

@FXML
private void handleNewArea() {
    Area tempArea = new Area();
    boolean okClicked = showAreaDialog(tempArea);
    if (okClicked) {
        addNewArea(tempArea);
        this.area.add(tempArea); // To inform ObservableList
    }

}

Area일반적인 JavaFX POJO입니다. 이것이 누군가를 돕기를 바랍니다.


initialize () 메서드

fullNameColumn = new TableColumn("Full name");
fullNameColumn.setCellValueFactory(new PropertyValueFactory<User, String>("fullName"));
usernameColumn = new TableColumn("Username");
usernameColumn.setCellValueFactory(new PropertyValueFactory<User, String>("test"));
emailColumn = new TableColumn("Email");
emailColumn.setCellValueFactory(new PropertyValueFactory<User, String>("email"));
reseller_table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
reseller_table.getColumns().addAll(usernameColumn, fullNameColumn, emailColumn);

ObservableList<User> data = FXCollections.observableArrayList(User.getResellers());
reseller_table.setItems(data);

사용자 클래스 (Hibernate POJO 클래스)

private SimpleStringProperty test;

public void setFullName(String fullName) {
  this.fullName = fullName;
  this.test = new SimpleStringProperty(fullName);    
}

public SimpleStringProperty testProperty() {
  return test;
}

refresh () 메서드

ObservableList<User> data = FXCollections.observableArrayList(User.getResellers());
reseller_table.setItems(data);

수동으로 새로 고치는 대신 관찰 가능한 속성을 사용해야합니다. 이 질문에 대한 답변은 목적 : SimpleStringProperty 및 SimpleIntegerProperty TableView JavaFX


Daniel De León의 답변을 바탕으로

public static void refresh_table(TableView table)
{
        for (int i = 0; i < table.getColumns().size(); i++) {
    ((TableColumn)(table.getColumns().get(i))).setVisible(false);
    ((TableColumn)(table.getColumns().get(i))).setVisible(true);
    }
}

내 솔루션은 Daniel De León 의 해결 방법과 유사 하지만 첫 번째 열을 숨겨야 할 때도 작동합니다 (그의 예에서는 인덱스 0). 물론 그의 솔루션에서 인덱스를 변경할 수 있지만 열을 다시 정렬하는 경우 내 솔루션이 더 잘 작동 할 수 있습니다. 아이디어는 열을 숨기고 인덱스로 표시하는 대신 이름으로 숨기고 표시하는 것입니다.

private void updateMyTableView() {
    // update table view WORKAROUND !!!
    if (myTableView != null) {
        ObservableList<TableColumn<Entry, ?>> columns = myTableView.getColumns();
        for (TableColumn<Entry, ?> column : columns) {
            // at this point, we look for the specific column, which should
            // always be visible
            // therefore we use the "Column Title" String, e.g. "First name"
            if (column.getText().equals("Column Title")) {
                column.setVisible(false);
                column.setVisible(true);
            }
        }
    }
}

UI 업데이트 스레드에서 테이블을 업데이트하는 것이 가장 좋습니다. 그러나 updateMyTableView();JavaFX는 어쨌든 UI 스레드에서 업데이트되는 것처럼 보이기 때문에 테이블에서 무언가를 변경 한 후 호출하여 작동 합니다 (확실하지 않음).

Platform.runLater(new Runnable() {
    public void run() {
         updateMyTableView();
    }
});

이것이 귀하의 상황에 적용되는지 확실하지 않지만 저에게 도움이 된 내용을 게시하겠습니다.

쿼리 / 검색을 기반으로 테이블보기를 데이터베이스로 변경합니다. 예를 들어, 데이터베이스 테이블에는 환자 데이터가 포함됩니다. 내 프로그램의 초기 테이블보기에는 모든 환자가 포함됩니다. 그런 다음 firstName 및 lastName으로 환자에 대한 쿼리를 검색 할 수 있습니다. 이 쿼리의 결과를 사용하여 Observable 목록을 다시 채 웁니다. 그런 다음 tableview.setItems (observableList)를 호출하여 tableview의 항목을 재설정합니다.

/**
 * Searches the table for an existing Patient.
 */
@FXML
public void handleSearch() {
    String fname = this.fNameSearch.getText();
    String lname = this.lNameSearch.getText();
    LocalDate bdate = this.bDateSearch.getValue();

    if (this.nameAndDOBSearch(fname, lname, bdate)) {
        this.patientData = this.controller.processNursePatientSearch(fname, lname, bdate);
    } else if (this.birthDateSearch(fname, lname, bdate)) {
        this.patientData = this.controller.processNursePatientSearch(bdate);
    } else if (this.nameSearch(fname, lname, bdate)) {
        this.patientData = this.controller.processNursePatientSearch(fname, lname);
    }

    this.patientTable.setItems(this.patientData);
}

if 블록은 쿼리 결과로 ObservableList를 업데이트합니다.


여기에서 같은 문제, 몇 가지 해결책을 시도했으며 나에게 가장 적합한 것은 다음과 같습니다.

컨트롤러의 initialize-method에서 빈 observableList를 만들고 테이블에 설정합니다.

    obsBericht = FXCollections.observableList(new ArrayList<Bericht>(0));
    tblBericht.setItems(obsBericht);

업데이트 방법에서 observableList를 사용하고 지우고 새로 고친 데이터를 추가하십시오.

        obsBericht.clear();
        obsBericht.addAll(FXCollections.observableList(DatabaseHelper.getBerichte()));
//      tblBericht.setItems(obsBericht);

테이블의 항목을 다시 설정할 필요가 없습니다.


Daniel De León의 답변에 따라 ...

  • 모델에 더미 속성 "modelChangedProperty"를 도입했으며
  • 해당 속성의 값을 변경하는 내 모델에서 메서드 refresh ()를 만들었습니다.
  • 내 컨트롤러에서 테이블 뷰를 업데이트하는 더미 속성에 리스너를 추가했습니다.

-

/**
 * Adds a listener to the modelChangedProperty to update the table view
 */
private void createUpdateWorkAroundListener() {

    model.modelChangedProperty.addListener(
            (ObservableValue<? extends Boolean> arg0, final Boolean oldValue, final Boolean newValue) -> updateTableView()
            );
}

/**
 * Work around to update table view
 */
private void updateTableView() {
    TableColumn<?, ?> firstColumn = scenarioTable.getColumns().get(0);
    firstColumn.setVisible(false);
    firstColumn.setVisible(true);
}

나는이 질문이 4 살이라는 것을 알고 있지만 동일한 문제가 있으며 위에서 해결책을 시도했지만 작동하지 않았습니다. 나는 또한 refresh () 메서드를 호출했지만 여전히 예상 결과가 아닙니다. 그래서 여기에 내 솔루션이 누군가를 도울 것입니다.

Question db = center.getSelectionModel().getSelectedItem();
new QuestionCrud().deleteQ(db.getId());
ObservableList<Question> aftDelete = FXCollections.observableArrayList(
        (new QuestionCrud()).all()
        );
center.setItems(aftDelete);

이전에도 ObeservableList의 다른 변수를 사용하여 tableview에 항목을 설정했지만이를 "더러운 방법"이라고 부르지 만 더 나은 솔루션을 얻을 때까지 괜찮습니다.


가능한 모든 해결책을 찾은 후에. 먼저 데이터 지우기를 시도한 다음 tableView.getItems().clear();여전히 내 문제를 해결하지 못하는 tableview에 추가했습니다 . 여기에 제공된 모든 답변을 시도했지만 나를 위해 일하지 않았으며 아래 이미지와 같이 테이블에 여전히 오래된 개체가 있습니다.

여기에 이미지 설명 입력

이를 수정하기 위해 DUMMY 레이블을 만들고 setGraphic다음과 같이 사용 했습니다.

여기에 이미지 설명 입력


我 始終 認為 利用 更改 TableColumn의 가시적 屬性 的 方法 違反 databinding의 精神 , 若 這 是 JavaFX 的 bug 那 也 早就 該 接 決 了 接 決 了 鄂 到 為該 拖到

자바 FX 的 소스 코드를 後, 並 沒有 發現 버그. 利用 리스너 等 方法 觀察 也 沒有 異樣. 也 嘗試 利用 JFace는 中 的 의해 PropertyChangeSupport 方式 宣告 POJO 內容 變更 也 沒有 效果. 最後 將 DoubleProperty 改為 WritableObjectValue, 問 提 就 解決 了 추적 經過。

                                                           解決於台灣台北

사용 변경 열 Visable Property가 데이터 바인딩 자동화 목적을 준수하지 않습니다.

JavaFX TableView 소스 코드를 추적 한 후. Tableview 바인딩 문제에 대한 문제 코드를 발견하지 못했습니다. 4 주 전 POJO 필드의 유형을 DoubleProperty에서 WritableObjectValue로 변경하여 문제가 해결되었습니다.

                                               resolve in Taiwan Taipei.

샘플 코드 :

public class CostAnalytics{
protected WritableObjectValue<Double> subtotal=new SimpleObjectProperty<Double>();//利用WritableObjectValue達到自動更新目的,不需要使用個別Column操作setVisable(false)及setVisable(true)
//...
public void setQuantity(double quantity) {
    this.pcs.firePropertyChange("quantity", this.quantity, quantity);
    this.quantity.set(quantity);
    this.calsSubtotal();
}
public WritableObjectValue<Double> getSubtotal() {//利用WritableObjectValue達到自動更新目的,不需要使用個別Column操作setVisable(false)及setVisable(true)
    return subtotal;
}
///...
}


TableColumn<CostAnalytics, Double> subtotal = new TableColumn<CostAnalytics, Double>(
            "小計");
subtotal.setCellValueFactory(new Callback<CellDataFeatures<CostAnalytics, Double>, ObservableValue<Double>>() {

        public ObservableValue<Double> call(
                CellDataFeatures<CostAnalytics, Double> p) {
            WritableObjectValue<Double> result = p.getValue().getSubtotal();// //利用WritableObjectValue達到自動更新目的,不需要使用個別Column操作setVisable(false)及setVisable(true)
            // return (ObservableValue<Double>)
            // result;//利用WritableObjectValue達到自動更新目的,不需要使用個別Column操作setVisable(false)及setVisable(true)
            // return new
            // ReadOnlyObjectWrapper<Double>(p.getValue().getSubtotal());//造成無法自動更新
            return (ObservableValue<Double>) p.getValue().getSubtotal();// 利用WritableObjectValue達到自動更新目的,不需要使用個別Column操作setVisable(false)及setVisable(true)
        }

    });

참고 URL : https://stackoverflow.com/questions/11065140/javafx-2-1-tableview-refresh-items

반응형