编辑文本单元格时Javafx TableView滚动错误

时间:2016-09-12 10:48:04

标签: javafx scroll tableview textfield mousewheel

当我在Javafx TableView中编辑Textfield单元格时,我注意到如果我使用鼠标滚轮滚动,那么它会将焦点更改为同一列中的另一个单元格。

这对我来说似乎是个错误。

在我的具体情况下,我设置了一个表格,我只想要一些行可编辑。这通常可以正常工作,除非您能够通过单击编辑可编辑行然后滚动鼠标滚轮来破坏此约束。然后,您可以编辑不应编辑的行。

甚至可以通过运行这个简单的例子来证明这一点 Oracle TableView docs

运行示例并添加额外的行,直到它需要显示垂直滚动条。然后开始编辑单元格并使用鼠标滚轮滚动

有没有人知道修复/解决这个问题?

我在1.8.0_92上运行

更新了示例说明:

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import javafx.util.Callback;

public class TableViewExample extends Application {

  private TableView<Person> table = new TableView<Person>();
  private ObservableList<Person> people = FXCollections.observableArrayList();

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

  public TableViewExample() {
    for (int id = 0; id < 100; id++) {
      people.add(new Person(String.valueOf(id)));
    }
  }

  @Override
  public void start(Stage stage) {
    Scene scene = new Scene(new Group());
    stage.setTitle("Table View Sample");

    table.setEditable(true);

    TableColumn idColumn = new TableColumn("Id");
    idColumn.setPrefWidth(400);
    idColumn.setCellValueFactory(new PropertyValueFactory<Person, String>("id"));
    idColumn.setCellFactory(
          new Callback<TableColumn, TableCell>() {
            public TableCell call(TableColumn p) {
              return new EditingCell();
            }
          }
    );
    idColumn.setOnEditCommit(
          new EventHandler<CellEditEvent<Person, String>>() {
            @Override
            public void handle(CellEditEvent<Person, String> t) {
              Person person =
                    ((Person) t.getTableView().getItems().get(t.getTablePosition().getRow()));
              person.setId(t.getNewValue());
            }
          }
    );

    table.setItems(people);
    table.getColumns().addAll(idColumn);
    ((Group) scene.getRoot()).getChildren().addAll(table);
    stage.setScene(scene);
    stage.show();
  }

  public static class Person {

    private final SimpleStringProperty id;

    private Person(String id) {
      this.id = new SimpleStringProperty(id);
    }

    public String getId() {
      return id.get();
    }

    public void setId(String id) {
      this.id.set(id);
    }
  }

  class EditingCell extends TableCell<Person, String> {

    private TextField textField;

    public EditingCell() {
    }

    @Override
    public void startEdit() {
      if (!isEmpty()) {
        super.startEdit();
        createTextField();
        setText(null);
        setGraphic(textField);
        textField.selectAll();
      }
    }

    @Override
    public void cancelEdit() {
      super.cancelEdit();

      setText((String) getItem());
      setGraphic(null);
    }

    @Override
    public void updateItem(String item, boolean empty) {
      super.updateItem(item, empty);

      if (empty) {
        setText(null);
        setGraphic(null);
      } else {
        if (isEditing()) {
          if (textField != null) {
            textField.setText(getString());
          }
          setText(null);
          setGraphic(textField);
        } else {
          setText(getString());
          setGraphic(null);
        }
      }
    }

    private void createTextField() {
      textField = new TextField(getString());
      textField.setMinWidth(getWidth() - getGraphicTextGap() * 2);
      textField.focusedProperty().addListener(new ChangeListener<Boolean>(){
        @Override
        public void changed(ObservableValue<? extends Boolean> arg0,
              Boolean arg1, Boolean arg2) {
          if (!arg2) {
            commitEdit(textField.getText());
          }
        }
      });
    }

    private String getString() {
      return getItem() == null ? "" : getItem();
    }
  }
}

运行示例:

单击以编辑单元格中的值

enter image description here

向下滚动鼠标滚轮,注意另一个单元格已在编辑模式下聚焦

enter image description here

1 个答案:

答案 0 :(得分:2)

在我的情况下,以下代码解决了问题:

 table.addEventFilter(ScrollEvent.ANY, scrollEvent -> {
            table.refresh();

            // close text box
            table.edit(-1, null);
        });