Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8097362

TableView look breaks when there is a horizontal scroll bar

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P3 P3
    • 8u20
    • 8u20
    • javafx
    • windows 7 jdk1.8.0_20-ea-b05

      It is also relevant with RT-36152.Also in this jdk If i have an horizontal scroll bar and i try to re-order the columns the alignment of the column headers often gets temporarily out of sync. That is, the header cells and the column cells don't line up anymore--in fact the headers may not even appear over the correct columns. This glitch is easiest to see if you scroll all the way over to the right and then grab Column 14 and swap its position.
      Also an another problem is that you can not click in a cell of the most right column.For example try to click in a cell of colimn 13.
      All these I tried with the code below:
      fxml file :
      ///////////////////////////////////////////////////

      <?xml version="1.0" encoding="UTF-8"?>

      <?import java.lang.*?>
      <?import javafx.scene.control.*?>
      <?import javafx.scene.layout.*?>

      <AnchorPane id="AnchorPane" prefHeight="385.0" prefWidth="432.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="tableviewsample.FXMLDocumentController">
      <children><TableView fx:id="table" editable="true" layoutX="19.0" layoutY="58.0" prefHeight="200.0" prefWidth="394.0">
        <columns>
          <TableColumn fx:id="c1" text="C1" /><TableColumn fx:id="c2" prefWidth="131.0" text="C2" /><TableColumn fx:id="c3" prefWidth="63.0" text="C3" /><TableColumn fx:id="c4" prefWidth="31.0" text="C4" /><TableColumn fx:id="c5" prefWidth="75.0" text="C5" /><TableColumn fx:id="c6" prefWidth="75.0" text="C6" /><TableColumn fx:id="c7" prefWidth="75.0" text="C7" /><TableColumn fx:id="c8" prefWidth="75.0" text="C8" /><TableColumn fx:id="c9" prefWidth="75.0" text="C9" />
          <TableColumn fx:id="c10" prefWidth="70.0" text="C10" /><TableColumn fx:id="c11" prefWidth="75.0" text="C11" /><TableColumn fx:id="c12" prefWidth="75.0" text="C12" /><TableColumn fx:id="c13" prefWidth="75.0" text="C13" /><TableColumn fx:id="c14" prefWidth="75.0" text="C14" />
        </columns>
      </TableView>
      </children>
      </AnchorPane>


      ///////////////////////////////////////////////////

      controller of fxml:
      //////////////////////////////////////////////////

      package tableviewsample;

      import java.net.URL;
      import java.util.ResourceBundle;
      import javafx.collections.FXCollections;
      import javafx.collections.ObservableList;
      import javafx.event.EventHandler;
      import javafx.fxml.FXML;
      import javafx.fxml.Initializable;
      import javafx.scene.control.ListCell;
      import javafx.scene.control.SelectionMode;
      import javafx.scene.control.TableCell;
      import javafx.scene.control.TableColumn;
      import javafx.scene.control.TablePosition;
      import javafx.scene.control.TableView;
      import javafx.scene.control.TextField;
      import javafx.scene.control.cell.ComboBoxTableCell;
      import javafx.scene.control.cell.PropertyValueFactory;
      import javafx.scene.control.cell.TextFieldTableCell;
      import javafx.scene.input.KeyCode;
      import javafx.scene.input.KeyEvent;
      import javafx.scene.input.MouseDragEvent;
      import javafx.scene.input.MouseEvent;
      import javafx.util.Callback;

      /**
       *
       * @author Georgios Dimos
       */
      public class FXMLDocumentController implements Initializable {

          @FXML
          private TableView<Item> table;
          @FXML
          private TableColumn<Item, String> c1;
          @FXML
          private TableColumn<Item, String> c2;
          @FXML
          private TableColumn<Item, String> c3;
          @FXML
          private TableColumn<Item, String> c4;
          @FXML
          private TableColumn<Item, String> c5;
          @FXML
          private TableColumn<Item, String> c6;
          @FXML
          private TableColumn<Item, String> c7;
          @FXML
          private TableColumn<Item, String> c8;
          @FXML
          private TableColumn<Item, String> c9;
          @FXML
          private TableColumn<Item, String> c10;
          @FXML
          private TableColumn<Item, String> c11;
          @FXML
          private TableColumn<Item, String> c12;
          @FXML
          private TableColumn<Item, String> c13;
          @FXML
          private TableColumn<Item, String> c14;
          private ObservableList<Item> items = FXCollections.observableArrayList(new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item(), new Item());
          private ObservableList<String> strings = FXCollections.observableArrayList("1", "2", "3");

          @Override
          public void initialize(URL url, ResourceBundle rb) {
              Callback<TableColumn<Item, String>, TableCell<Item, String>> cellFactory = new DragSelectionCellFactory();
              System.out.println("");
              c1.setCellValueFactory(new PropertyValueFactory("c1"));
              c2.setCellValueFactory(new PropertyValueFactory("c2"));
              c3.setCellValueFactory(new PropertyValueFactory("c3"));
              c4.setCellValueFactory(new PropertyValueFactory("c4"));
              c5.setCellValueFactory(new PropertyValueFactory("c5"));
              c6.setCellValueFactory(new PropertyValueFactory("c6"));
              c7.setCellValueFactory(new PropertyValueFactory("c7"));
              c8.setCellValueFactory(new PropertyValueFactory("c8"));
              c9.setCellValueFactory(new PropertyValueFactory("c9"));
              c10.setCellValueFactory(new PropertyValueFactory("c10"));
              c11.setCellValueFactory(new PropertyValueFactory("c11"));
              c12.setCellValueFactory(new PropertyValueFactory("c12"));
              c13.setCellValueFactory(new PropertyValueFactory("c13"));
              c14.setCellValueFactory(new PropertyValueFactory("c14"));

              c1.setCellFactory(cellFactory);
              c2.setCellFactory(cellFactory);
              c3.setCellFactory(cellFactory);
              c4.setCellFactory(cellFactory);
              c5.setCellFactory(TextFieldTableCell.forTableColumn());
              c6.setCellFactory(TextFieldTableCell.forTableColumn());
              c7.setCellFactory(TextFieldTableCell.forTableColumn());
              c8.setCellFactory(TextFieldTableCell.forTableColumn());
              c9.setCellFactory(TextFieldTableCell.forTableColumn());
              c10.setCellFactory(TextFieldTableCell.forTableColumn());
              c11.setCellFactory(TextFieldTableCell.forTableColumn());
              c12.setCellFactory(TextFieldTableCell.forTableColumn());
              c13.setCellFactory(TextFieldTableCell.forTableColumn());
              c14.setCellFactory(ComboBoxTableCell.forTableColumn(strings));
              table.setItems(items);
              table.getSelectionModel().setCellSelectionEnabled(true);
              table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
          }

          public static class DragSelectionCellFactory implements Callback<TableColumn<Item, String>, TableCell<Item, String>> {

              @Override
              public TableCell<Item, String> call(final TableColumn<Item, String> col) {

                  return new EditingCell();
              }

          }

          /**
           *
           * @author Georgios Dimos
           */
          public static class EditingCell extends TableCell<Item, String> {

              private TextField textField;
              private int column = 0;
              private int row = 0;

              public EditingCell() {

                  setOnDragDetected(new EventHandler<MouseEvent>() {
                      @Override
                      public void handle(MouseEvent event) {
      // System.err.println("SET ON DRAG DETECTED ");
                          startFullDrag();
                          getTableColumn().getTableView().getSelectionModel().select(getIndex(), getTableColumn());
                          ObservableList<TablePosition> posList = getTableColumn().getTableView().getSelectionModel().getSelectedCells();
                          column = posList.get(0).getColumn();
                          row = getIndex();

                      }
                  });
                  setOnMouseDragEntered(new EventHandler<MouseDragEvent>() {
                      @Override
                      public void handle(MouseDragEvent event) {
      // System.err.println("SET ON MOUSE DRAG ENTERED ");
                          getTableColumn().getTableView().getSelectionModel().select(getIndex(), getTableColumn());

                      }
                  });

                  setOnMouseDragExited(new EventHandler<MouseDragEvent>() {
                      @Override
                      public void handle(MouseDragEvent event) {
      // System.err.println("SET ON DRAG EXITED ");
                          ObservableList<TablePosition> posList = getTableColumn().getTableView().getSelectionModel().getSelectedCells();

                          //we want the column and the row of the first selected and the last
                          column = posList.get(0).getColumn();
                          row = posList.get(0).getRow();
                          getTableColumn().getTableView().getSelectionModel().clearSelection();

                          int rowLast = getIndex();
                          int j;
                          ObservableList<TableColumn<Item, ?>> columns = getTableColumn().getTableView().getColumns();
                          for (int i = row; i <= rowLast; i++) {
                              j = column;

                              while (j < columns.size()) {
                                  if (columns.get(j) != getTableColumn()) {
                                      getTableColumn().getTableView().getSelectionModel().select(i, columns.get(j));
                                  } else {
                                      getTableColumn().getTableView().getSelectionModel().select(i, columns.get(j));
                                      break;
                                  }
                                  j++;
                              }
                          }
                      }
                  });

              }

              @Override
              public void startEdit() {

                  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, false);

                  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();

                  textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);

                  textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
                      @Override
                      public void handle(KeyEvent t) {
                          if (t.getCode() == KeyCode.ENTER) {
                              commitEdit(textField.getText());
                          } else if (t.getCode() == KeyCode.ESCAPE) {
                              cancelEdit();
                          }
                      }
                  });
      // 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().toString();

              }
          }

      }


      /////////////////////////////////////////////////

      Model of table file :
      ////////////////////////////////////////////////



      package tableviewsample;

      import javafx.beans.property.SimpleStringProperty;
      import javafx.beans.property.StringProperty;

      /**
       *
       * @author Georgios Dimos
       */
      public class Item {
          private SimpleStringProperty c1=new SimpleStringProperty();
          private SimpleStringProperty c2=new SimpleStringProperty();
          private SimpleStringProperty c3=new SimpleStringProperty();
          private SimpleStringProperty c4=new SimpleStringProperty();
          private SimpleStringProperty c5=new SimpleStringProperty();
          private SimpleStringProperty c6=new SimpleStringProperty();
          private SimpleStringProperty c7=new SimpleStringProperty();
          private SimpleStringProperty c8=new SimpleStringProperty();
          private SimpleStringProperty c9=new SimpleStringProperty();
          private SimpleStringProperty c10=new SimpleStringProperty();
          private SimpleStringProperty c11=new SimpleStringProperty();
          private SimpleStringProperty c12=new SimpleStringProperty();
          private SimpleStringProperty c13=new SimpleStringProperty();
          private SimpleStringProperty c14=new SimpleStringProperty();

          public Item(){
              c1.set("c1");
              c2.set("c2");
              c3.set("c3");
              c4.set("c4");
              c5.set("c5");
              c6.set("c6");
              c7.set("c7");
              c8.set("c8");
              c9.set("c9");
              c10.set("c10");
              c11.set("c11");
              c12.set("c12");
              c13.set("c13");
              c14.set("c14");
              
              
          }
          public StringProperty c1Property() {
              return c1;
          }

          public void setC1(String c1) {
              this.c1.set(c1);
          }

          public StringProperty c2Property() {
              return c2;
          }

          public void setC2(String c2) {
              this.c2.set(c2);
          }

          public StringProperty c3Property() {
              return c3;
          }

          public void setC3(String c3) {
              this.c3.set(c3);
          }

          public StringProperty c4Property() {
              return c4;
          }

          public void setC4(String c4) {
              this.c4.set(c4);
          }

          public StringProperty c5Property() {
              return c5;
          }

          public void setC5(String c5) {
              this.c5.set(c5);
          }

          public StringProperty c6Property() {
              return c6;
          }

          public void setC6(String c6) {
              this.c6.set(c6);
          }

          public StringProperty c7Property() {
              return c7;
          }

          public void setC7(String c7) {
              this.c7.set(c7);
          }

          public StringProperty c8Property() {
              return c8;
          }

          public void setC8(String c8) {
              this.c8.set( c8);
          }

          public StringProperty c9Property() {
              return c9;
          }

          public void setC9(String c9) {
              this.c9.set(c9);
          }

          public StringProperty c10Property() {
              return c10;
          }

          public void setC10(String c10) {
              this.c10.set(c10);
          }

          public StringProperty c11Property() {
              return c11;
          }

          public void setC11(String c11) {
              this.c11.set(c11);
          }

          public StringProperty c12Property() {
              return c12;
          }

          public void setC12(String c12) {
              this.c12.set(c12);
          }

          public StringProperty c13Property() {
              return c13;
          }

          public void setC13(String c13) {
              this.c13.set(c13);
          }

          public StringProperty c14Property() {
              return c14;
          }

          public void setC14(String c14) {
              this.c14.set(c14);
          }
          
          
      }


      /////////////////////////////////////////////////

      And the main file:
      ////////////////////////////////////////////////

      /*
       * To change this license header, choose License Headers in Project Properties.
       * To change this template file, choose Tools | Templates
       * and open the template in the editor.
       */

      package tableviewsample;

      import javafx.application.Application;
      import javafx.fxml.FXMLLoader;
      import javafx.scene.Parent;
      import javafx.scene.Scene;
      import javafx.stage.Stage;

      /**
       *
       * @author Georgios Dimos
       */
      public class TableViewSample extends Application {
          
          @Override
          public void start(Stage stage) throws Exception {
              Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
              
              Scene scene = new Scene(root);
              
              stage.setScene(scene);
              stage.show();
          }

          /**
           * @param args the command line arguments
           */
          public static void main(String[] args) {
              launch(args);
          }
          
      }


      ///////////////////////////////////////////////


      Finally an another problem I saw is that I want to select a lot of cells by mouse and with the code below
      I could in jdk1.8.0 and earlier versions but in this jdk I cannot.

            jgiles Jonathan Giles
            duke J. Duke
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported: