2017-04-19 1 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 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 클래스에 익명 규칙을 적용합니다. 즉, 유형 매개 변수의 이름으로 단일 문자를 사용합니다. 귀하의 경우 유형 매개 변수의 이름은 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 테이블에 몇 행을 추가 했습니까? 버튼을 한 번만 클릭하면 삽입 할 항목의 두 번째 행이 없습니다. – fabian

+0

먼저 두 행을 클립 보드에 복사했습니다. 열이 나타나도록 먼저 3 열을 선택했습니다. 그런 다음 첫 번째 열의 첫 번째 행에서 'Ctrl + V'를 사용하여 붙여 넣기를 시도했습니다. 첫 번째 행만 붙여 넣습니다. 복사 된 데이터 당 행을 자동으로 추가해야합니다. – vegaonline

관련 문제