2017-04-19 18 views
0

私は個々のセル編集でデータを受け入れるTableViewを持っています。今度は、以下のようにファイルから貼り付けてデータを入力したいと思っています。JAVAFXを使用してTableViewにテキストデータを貼り付け

11.12 23.32 15.43 
22.23 24.45 26.65 

たとえば、CTRL+Vを使用してデータを貼り付けたいとします。私は既にpost in StackOverflowまたはthe GIT repoのような投稿を見ました。複数行のデータを貼り付けることができませんでした。

ここで私はメインコードを与えています。

package testmatrix; 

import javafx.application.Application; 
import javafx.collections.*; 
import javafx.event.*; 
import javafx.scene.Scene; 
import javafx.scene.control.TableColumn.CellEditEvent; 
import javafx.scene.control.*; 
import javafx.scene.control.cell.*; 
import javafx.scene.layout.*; 
import javafx.stage.Stage; 

public class TestMATRIX extends Application { 
TableView<CommonDataClass> matrixData = new TableView<CommonDataClass>(); 
final ObservableList<CommonDataClass> matData = FXCollections. 
     observableArrayList(); 
TableColumn[] matrixDataColumns = new TableColumn[6]; 
int numColVal = 0; 
int theNDX = 0; 
int maxRowNum = 0; 
TextField TC1 = new TextField(); 
TextField TC2 = new TextField(); 
TextField TC3 = new TextField(); 
TextField TC4 = new TextField(); 
TextField TC5 = new TextField(); 
TextField TC6 = new TextField(); 
boolean numColStatus = false; 
int oldRowVal = 0; 
int oldColVal = 0; 
boolean newRow = false; 
boolean newCol = false; 

@Override 
public void start(Stage primaryStage) { 
    final BorderPane root = new BorderPane(); 

    TextField myTextField = new TextField(); 
    Label colL = new Label("Column Number->"); 
    TextField colNumT = new TextField(); 
    Button getNum = new Button("SET"); 
    colNumT.setMaxWidth(40); 
    TableUtils.doCopyPasteHandler (matrixData, matData); 
    matrixData.setVisible(true); 
    matrixData.setEditable(true); 
    matrixData.getSelectionModel().setCellSelectionEnabled(true); 
    matrixData.getSelectionModel().setSelectionMode (SelectionMode.MULTIPLE); 

    HBox hb1 = new HBox(); 
    HBox hb2 = new HBox(); 
    hb1.getChildren().add(matrixData); 
    hb2.getChildren().addAll(colL, colNumT, getNum); 

    root.setCenter(hb1); 
    root.setRight(hb2); 
    getNum.addEventHandler(ActionEvent.ACTION, e -> { 
     numColStatus = (colNumT.getText().isEmpty()) ? false : true; 
     numColVal = (numColStatus) ? Integer.parseInt(colNumT.getText()): 0; 

     if (numColStatus) { 
      addRowBelow(); 
      matrixData.getColumns().clear(); 
      for (int ii = 0; ii < numColVal; ii++) { 
       matrixDataColumns[ii] = createCol(ii); 
       editCommit(ii); 
      } 
      matrixData.setItems(matData); 
      if (numColStatus) { 
       for (int ii = 0; ii < numColVal; ii++) { 
        matrixData.getColumns().add(matrixDataColumns[ii]); 
       } 
      } 
      matrixData.refresh(); 
     } 
    }); 
    Scene scene = new Scene(root, 1200, 400); 
    primaryStage.setTitle("Hello World!"); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 

TableColumn<CommonDataClass, String> createCol(int icol) { 
    TableColumn<CommonDataClass, String> column = new TableColumn<>(); 
    column.setMinWidth(30); 
    column.setStyle(
      "-fx-alignment: CENTER-RIGHT;-fx-font-family: monospace; -fx-font-size: 10px; "); 
    String nameC = "myD" + (icol + 1); 
    System.out.println("colName->" + nameC); 
    column.setCellValueFactory(
      new PropertyValueFactory<CommonDataClass, String>(nameC)); 

    column.setCellFactory(
      new DragSelectionCellFactory<CommonDataClass, String>(TextFieldTableCell.forTableColumn() 
      ) 
    ); 
    column.setMinWidth(120); 
    return column; 
} 

private void editCommit(int ii) { 
    System.out.println("Command came here"); 
    matrixDataColumns[ii].setOnEditCommit(
      new EventHandler<CellEditEvent<CommonDataClass, String>>() { 
     @Override 
     public void handle(CellEditEvent<CommonDataClass, String> event) { 
      int colNum = event.getTablePosition().getColumn(); 
      switch (colNum) { 
       case 0: 
        event.getTableView().getItems().get(event.getTablePosition().getRow()).setMyD1(event.getNewValue()); 
        break; 
       case 1: 
        event.getTableView().getItems().get(event.getTablePosition().getRow()).setMyD2(event.getNewValue()); 
        break; 
       case 2: 
        event.getTableView().getItems().get(event.getTablePosition().getRow()).setMyD3(event.getNewValue()); 
        break; 
       case 3: 
        event.getTableView().getItems().get(event.getTablePosition().getRow()).setMyD4(event.getNewValue()); 
        break; 
       case 4: 
        event.getTableView().getItems().get(event.getTablePosition().getRow()).setMyD5(event.getNewValue()); 
        break; 
       case 5: 
        event.getTableView().getItems().get(event.getTablePosition().getRow()).setMyD6(event.getNewValue()); 
        break; 
      } 
      matrixData.setItems(matData); 
      matrixData.refresh();    
      if (!event.getNewValue().isEmpty()) { 
       addRowBelow(); 
      } 
     } 
    }); 
} 

void addRowBelow() { 
    matData.add(new CommonDataClass(
      TC1.getText(), TC2.getText(), TC3.getText(), 
      TC4.getText(), TC5.getText(), TC6.getText() 
    )); 
} 

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

} 

ここでは、TableViewのデータ構造を示しています。

package testmatrix; 
import javafx.beans.property.*; 

public class CommonDataClass { 

private final SimpleStringProperty myD1; 
private final SimpleStringProperty myD2; 
private final SimpleStringProperty myD3; 
private final SimpleStringProperty myD4; 
private final SimpleStringProperty myD5; 
private final SimpleStringProperty myD6; 

public CommonDataClass(String myStr1, String myStr2, String myStr3, String myStr4, String myStr5, String myStr6) { 
    this.myD1 = new SimpleStringProperty(myStr1); 
    this.myD2 = new SimpleStringProperty(myStr2); 
    this.myD3 = new SimpleStringProperty(myStr3); 
    this.myD4 = new SimpleStringProperty(myStr4); 
    this.myD5 = new SimpleStringProperty(myStr5); 
    this.myD6 = new SimpleStringProperty(myStr6); 
} 

public String getMyD1(){ 
    return myD1.get(); 
} 
public String getMyD2(){ 
    return myD2.get(); 
} 
public String getMyD3(){ 
    return myD3.get(); 
} 
public String getMyD4(){ 
    return myD4.get(); 
} 
public String getMyD5(){ 
    return myD5.get(); 
} 
public String getMyD6(){ 
    return myD6.get(); 
} 
public void setMyD1(String myStr){ 
    myD1.set(myStr); 
} 
public void setMyD2(String myStr){ 
    myD2.set(myStr); 
} 
public void setMyD3(String myStr){ 
    myD3.set(myStr); 
} 
public void setMyD4(String myStr){ 
    myD4.set(myStr); 
} 
public void setMyD5(String myStr){ 
    myD5.set(myStr); 
} 
public void setMyD6(String myStr){ 
    myD6.set(myStr); 
} 


public StringProperty dataNameProperty(int index) { 
    StringProperty strProp = null; 

    switch (index) { 
     case 0: 
      strProp = myD1; 
      break; 
     case 1: 
      strProp = myD2; 
      break; 
     case 2: 
      strProp = myD3; 
      break; 
     case 3: 
      strProp = myD4; 
      break; 
     case 4: 
      strProp = myD5; 
      break; 
     case 5: 
      strProp = myD6; 
      break; 
    } 
    return strProp; 
} 
} 

ここでは、セルのDrageSelectionのコードを指定しています。

package testmatrix; 
import javafx.scene.control.TableCell; 
import javafx.scene.input.*; 

public class DragSelectionCell extends TableCell<CommonDataClass, String> { 

public DragSelectionCell() { 
    setOnDragDetected ((MouseEvent event) -> { 
     startFullDrag(); 
     getTableColumn().getTableView().getSelectionModel().select (
       getIndex(), getTableColumn()); 
    }); 
    setOnMouseDragEntered ((MouseDragEvent event) -> { 
     getTableColumn().getTableView().getSelectionModel().select (
       getIndex(), getTableColumn()); 
    }); 
} 

@Override 
public void updateItem(String item, boolean empty) { 
    super.updateItem (item, empty); 
    if (empty) { 
     setText (null); 
    } else { 
     setText (item); 
    } 
} 
} 

ここではDragSelectionCellfactoryコードを指定しています。

package testmatrix; 
import javafx.scene.control.*; 
import javafx.util.Callback; 


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

private final Callback<TableColumn<CommonDataClass, String>, TableCell<CommonDataClass, String>> factory; 

public DragSelectionCellFactory(
     Callback<TableColumn<CommonDataClass, String>, TableCell<CommonDataClass, String>> factory) { 
    this.factory = factory; 
} 

public DragSelectionCellFactory() { 
    this (col -> new TableCell<CommonDataClass, String>() { 
     @Override 
     protected void updateItem(String item, boolean empty) { 
      super.updateItem (item, empty); 
      if (empty || item == null) { 
       setText (null); 
      } else { 
       setText (item.toString()); 
      } 
     } 
    }); 
} 

@Override 
public TableCell<CommonDataClass, String> call(
     final TableColumn<CommonDataClass, String> col) { 
    TableCell<CommonDataClass, String> cell = factory.call (col); 
    cell.setOnDragDetected (event -> { 
     cell.startFullDrag(); 
     col.getTableView().getSelectionModel().select (cell.getIndex(), 
       col); 
    }); 
    cell.setOnMouseDragEntered (event -> { 
     col.getTableView().getSelectionModel().select (cell.getIndex(), 
       col); 
    }); 

    cell.setOnMouseEntered (e -> { 
     String item = cell.getItem(); 
     if (item != null) { 
     } 
    }); 

    return cell; 
} 
} 

次のコードブロックは、最初に説明したコピー/ペーストルーチンのテーブルユーティリティと同様です。しかし、ペースト部分は機能していなかったので、修正しようとしました。今私は完全に混乱している。コピーパーツはコピーされていましたが、上のリファレンスに示されているコードごとのペーストパーツはすべての行と列を貼り付けることができませんでした。

package testmatrix; 
import java.util.StringTokenizer; 
import javafx.beans.property.StringProperty; 
import javafx.beans.value.ObservableValue; 
import javafx.collections.*; 
import javafx.event.EventHandler; 
import javafx.scene.control.*; 
import javafx.scene.input.*; 

public class TableUtils extends TableCell<CommonDataClass, String> { 
ObservableList<CommonDataClass> datTab = FXCollections. 
     observableArrayList(); 

public static void doCopyPasteHandler(TableView<?> table, 
     ObservableList<CommonDataClass> myData) { 

    table.setOnKeyPressed (new TableKeyEventHandler()); 
} 

public static class TableKeyEventHandler implements EventHandler<KeyEvent> { 
    KeyCodeCombination copyCode = new KeyCodeCombination (KeyCode.C, 
      KeyCodeCombination.CONTROL_ANY); 
    KeyCodeCombination pasteCode = new KeyCodeCombination (KeyCode.V, 
      KeyCodeCombination.CONTROL_ANY); 

    //@Override 
    public void handle(KeyEvent event) { 
     if (copyCode.match (event)) { 
      if (event.getSource() instanceof TableView) { 
       copySelection2Clipboard ((TableView<?>) event.getSource()); // this will copy to clipboard 
       event.consume(); // After using event please consume 
      } 
     } else if (pasteCode.match (event)) { 
      if (event.getSource() instanceof TableView) { 
       pasteFromClipboard ((TableView<?>) event.getSource()); 
       event.consume(); 
      } 
     } 
    } 
} 

public static void copySelection2Clipboard(TableView<?> table) { 
    StringBuilder clipboardString = new StringBuilder(); 
    ObservableList<TablePosition> positionList = table.getSelectionModel(). 
      getSelectedCells(); 
    int prevRow = -1; 
    for (TablePosition pos : positionList) { 
     int row = pos.getRow(); 
     int col = pos.getColumn(); 
     if (prevRow == row) { // determine whether we advance in a row or col (newline) 
      clipboardString.append ('\t'); 
     } else if (prevRow != -1) { 
      clipboardString.append ('\n'); 
     } 
     String text = ""; 
     Object obsValue = (Object) table.getColumns().get (col). 
       getCellObservableValue (row); 
     if (obsValue == null) { 
      text = ""; 
     } else if (obsValue instanceof StringProperty) { 
      text = ((StringProperty) obsValue).get(); 
     } else { 
      System.out.println ("Unsupported observable value: " + obsValue); 
     } 
     clipboardString.append (text); 
     prevRow = row; 
    } 
    ClipboardContent clipboardContent = new ClipboardContent(); 
    clipboardContent.putString (clipboardString.toString()); 
} 


public static void pasteFromClipboard(TableView<?> table) { 
    if (table.getSelectionModel().getSelectedCells().size() == 0) { 
     return; 
    } 
    TablePosition pasteCellPosition = table.getSelectionModel(). 
      getSelectedCells().get (0);  // get cell position at start 
    String pasteString = Clipboard.getSystemClipboard().getString(); 
    StringTokenizer rowTokenizer = new StringTokenizer (pasteString, "\n"); 
    int rowNum = rowTokenizer.countTokens() + 1; 
    int rowCB = -1; 
    while (rowTokenizer.hasMoreTokens()) { 
     rowCB++; 
     String rowString = rowTokenizer.nextToken(); 
     StringTokenizer colTokenizer = new StringTokenizer (rowString, "\t"); 
     int colCB = -1; 
     while (colTokenizer.hasMoreTokens()) { 
      colCB++; 
      String clpCellCont = colTokenizer.nextToken(); 
      int rowTable = pasteCellPosition.getRow() + rowCB; 
      int colTable = pasteCellPosition.getColumn() + colCB; 
      if (rowTable >= table.getItems().size()) { 
       continue; 
      } 
      if (colTable >= table.getColumns().size()) { 
       continue; 
      } 

      TableColumn tabCol = table.getVisibleLeafColumn (colTable); 
      ObservableValue obsVal = tabCol. 
        getCellObservableValue (rowTable);    
     } 

    } 
} 

}

私は任意のヘルプを取得する場合には、大きな助けになるでしょう。ありがとう、よろしくお願いします。

答えて

1

イベントハンドラに値を割り当てるコードがないため、値を挿入できませんでした。

さらにプロパティを使用しないため、操作が複雑になります。

あなたが新しい値割り当てるためのプロパティを使用することができますプロパティ

TableColumn<CommonDataClass, String> createCol(int icol) { 
    ... 
    column.setCellValueFactory(
      cd -> cd.getValue().dataNameProperty(icol)); 

使用する場合:既存の行に

public static <T> void pasteFromClipboard(TableView<T> table) { 
    if (table.getSelectionModel().getSelectedCells().isEmpty()) { 
     return; 
    } 
    TablePosition pasteCellPosition = table.getSelectionModel(). 
      getSelectedCells().get(0);  // get cell position at start 

    Clipboard cb = Clipboard.getSystemClipboard(); 

    // check, if clipboard contains a string 
    if (!cb.hasString()) { 
     return; 
    } 

    String pasteString = cb.getString(); 
    String[][] values = Stream.of(pasteString.split("\r?\n")) 
      .map(line -> line.split("\t")).toArray(String[][]::new); 

    final int offsetY = pasteCellPosition.getRow(); 
    final int offsetX = pasteCellPosition.getColumn(); 
    final int maxY = Math.min(table.getItems().size() - offsetY, values.length); 
    final int colMax = table.getColumns().size() - offsetX; 

    for (int y = 0; y < maxY; y++) { 
     String[] r = values[y]; 
     final int maxX = Math.min(colMax, r.length); 
     T rowObject = table.getItems().get(y+offsetY); 
     for (int x = 0; x < maxX; x++) { 
      Object property = table.getColumns().get(x + offsetX).getCellObservableValue(rowObject); 
      if (property instanceof StringProperty) { 
       // write value using the property 
       ((StringProperty) property).set(r[x]); 
      } 
     } 
    } 
} 

これだけ挿入値を...


ただし、実際にはnあなたのDragSelectionCellFactoryクラスの匿名の慣習に従ってください。つまり、タイプパラメータの名前として1文字を使用します。あなたのケースでは、タイプパラメータの名前はCommonDataClassStringとなります。つまり、既存のクラスの名前は混乱の原因になります。
おそらくあなたがが型パラメータを削除する必要があります:あなたがクリップボードの内容を設定するのを忘れているので

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

はさらに、コンテンツは動作しませんコピー:

ClipboardContent clipboardContent = new ClipboardContent(); 
clipboardContent.putString(clipboardString.toString()); 
Clipboard.getSystemClipboard().setContent(clipboardContent); 

はさらに、選択される保証はありませんセルは長方形の領域にあります。セルは、Ctrlを押し続けると任意に選択できます。

はまた

getNum.addEventHandler(ActionEvent.ACTION, e -> {...}); 

は(この場合には私見は、必要があります)最初に

getNum.setOnAction(e -> {...}); 
+0

に置き換えることができ、私はあなたの貴重な時間と親切な忍耐のためにどうもありがとうございました。私はあなたの意見に従った。 「11.12 \t 23.32 15.43 \ n 22.23 \t 24.45 26.65'のようにデータを入力したいと思います。コードは最初の行 '11.12 \t 23.32 \t 15.43'を貼り付け、残りを貼り付けるための新しい行を挿入しません。親切に確認できますか? – vegaonline

+0

@vegaonlineテーブルに追加した行の数はいくつですか?ボタンを1回だけクリックすると、挿入されるアイテムの2番目の行は表示されません。 – fabian

+0

最初にクリップボードに2行をコピーしました。最初に3列を選んで列が表示されました。最初の列の最初の行で、貼り付けが行われるように 'Ctrl + V 'を使いました。それはペースト、最初の行のみです。コピーしたデータごとに自動的に行を追加する必要があります。 – vegaonline