2016-02-04 105 views
0

直到我向某人展示工作(ish)原型時,我始終沒有想過。他們詢問是否可以在當前Excel表格之上增加一個新的行,即Excel。插入TableView JavaFX

有問題的應用程序正在生成旅行itineries,所以如果有人忘記鍵入旅程中的一個特定的行程,他們現在將不得不刪除以下行並繼續正常(有點痛苦)。

在Google上做一些搜索並沒有真正幫助它指出在之前的一行之後添加一個新行,這可以做到。

例子:

04FEB London to New York 
    --> insert here (forgot new york to san fran). 
    23FEB San Francisco to New York 
    23FEB New York to London 

非常感謝

+0

你問在JavaFX中如何插入行到TableView? 你可以更具體嗎? – amkz

+1

表中的行只不過是作爲其中的項目設置的「ObservableList」中的數據。如果更改列表,則表中的項目/行會更改。 – ItachiUchiha

+0

您所要做的就是在適當的索引處將新項目插入表格的項目列表中。你能更具體地說明你希望用戶採取什麼行動來插入新行嗎? –

回答

-1

它通過數據表的修改是可能的。

+0

你是什麼意思「不支持開箱即用?」所有你需要的是'table.getItems()。add(index,new Item());' –

+0

客戶想要內聯編輯。沒有人想編輯一個表格,就像[這個帶外部控制的例子]一樣(https://docs.oracle.com/javafx/2/ui_controls/table-view.htm)。如果你向用戶表明他們嘲笑你並說「不,謝謝」。 – Roland

+0

OP沒有提到他們想要的編輯行爲,但是你只需要調用'table.edit(...)' –

0

基本上所有你需要做的,在適當的位置插入一個新的項目到表的項目列表:

table.getItems().add(index, newItem); 

你可以添加一些用戶的功能,比如在新項目啓動編輯,或如果需要,根據周圍的數據進行數據的最佳猜測初始化。例如:我把「插入行之前」和「插入行之後」的功能放入表格行的上下文菜單中,但很明顯,這是一個非常快速的(總共15分鐘編碼,因此顯然它可能包含一些錯誤)您可以將其掛接到您想要的任何用戶操作。

import java.util.function.Function; 

import javafx.application.Application; 
import javafx.beans.binding.Bindings; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 
import javafx.geometry.Insets; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.ContextMenu; 
import javafx.scene.control.Label; 
import javafx.scene.control.MenuItem; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableRow; 
import javafx.scene.control.TableView; 
import javafx.scene.control.cell.TextFieldTableCell; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.HBox; 
import javafx.stage.Stage; 

public class ItineraryBuilder extends Application { 

    private TableView<ItineraryLeg> table; 

    private void insert(int rowIndex, String origin, String destination, int editCol) { 
     table.getItems().add(rowIndex, new ItineraryLeg(origin, destination)); 
     table.getSelectionModel().clearAndSelect(rowIndex); 
     table.edit(rowIndex, table.getColumns().get(editCol)); 
    } 

    @Override 
    public void start(Stage primaryStage) { 
     table = new TableView<>(); 
     table.setEditable(true); 

     table.getColumns().add(column("Origin", ItineraryLeg::originProperty)); 
     table.getColumns().add(column("Destination", ItineraryLeg::destinationProperty)); 

     table.getItems().addAll(
       new ItineraryLeg("London","New York"), 
       new ItineraryLeg("San Francisco","New York"), 
       new ItineraryLeg("New York", "London")); 


     table.setRowFactory(tv -> { 
      TableRow<ItineraryLeg> row = new TableRow<>(); 
      MenuItem addBefore = new MenuItem("Insert leg before"); 
      MenuItem addAfter = new MenuItem("Insert leg after"); 
      ContextMenu menu = new ContextMenu(addBefore, addAfter); 
      addBefore.setOnAction(e -> { 
       String origin = row.getIndex() == 0 ? "" : table.getItems().get(row.getIndex()-1).getDestination(); 
       String destination = table.getItems().get(row.getIndex()).getOrigin() ; 
       insert(row.getIndex(), origin, destination, 0); 
      }); 
      addAfter.setOnAction(e -> { 
       String origin = table.getItems().get(row.getIndex()).getDestination(); 
       String destination = row.getIndex() == table.getItems().size()-1 
         ? "" 
         : table.getItems().get(row.getIndex()+1).getOrigin() ; 
       insert(row.getIndex()+1, origin, destination, 1); 
      }); 
      row.contextMenuProperty().bind(
        Bindings.when(row.emptyProperty()) 
        .then((ContextMenu)null) 
        .otherwise(menu)); 
      return row ; 
     }); 

     Label label = new Label("Build Itinerary"); 
     Button add = new Button("Add leg"); 
     HBox controls = new HBox(5, label, add); 
     controls.setPadding(new Insets(10)); 
     add.setOnAction(e -> insert(table.getItems().size(), "Origin", "Destination", 0)); 

     BorderPane root = new BorderPane(table); 
     root.setTop(controls); 
     Scene scene = new Scene(root, 600, 600); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 


    private static <S> TableColumn<S,String> column(String title, Function<S, StringProperty> property) { 
     TableColumn<S,String> col = new TableColumn<>(title); 
     col.setCellValueFactory(cellData -> property.apply(cellData.getValue())); 
     col.setCellFactory(TextFieldTableCell.forTableColumn()); 
     col.setPrefWidth(200); 
     return col ; 
    } 

    public static class ItineraryLeg { 
     private final StringProperty origin = new SimpleStringProperty(); 
     private final StringProperty destination = new SimpleStringProperty(); 

     public ItineraryLeg(String origin, String destination) { 
      setOrigin(origin); 
      setDestination(destination); 
     } 

     public final StringProperty originProperty() { 
      return this.origin; 
     } 


     public final String getOrigin() { 
      return this.originProperty().get(); 
     } 


     public final void setOrigin(final String origin) { 
      this.originProperty().set(origin); 
     } 


     public final StringProperty destinationProperty() { 
      return this.destination; 
     } 


     public final String getDestination() { 
      return this.destinationProperty().get(); 
     } 


     public final void setDestination(final String destination) { 
      this.destinationProperty().set(destination); 
     } 


    } 

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

「添加腿」按鈕確實具有魔力:桌面視圖焦點邊框閃爍,並且在某個時候您會看到滾動條。可能你必須先選擇一些東西。如果選擇第2行並點擊「之前插入腿」,它將在上面插入一行,但會聚焦在所選行上並使第二列可編輯。如果您在第一個表格行上單擊「插入腳後」,則會發生異常。顯示一個越野車的例子並沒有使我的觀點無效;-) – Roland

+0

正如我所說的,我在15分鐘內從頭開始將它扔在一起 - 關於極限我準備投資回答一個問題,顯示約15分鐘代碼;),很明顯,它可能是越野車。 OP沒有具體說明編輯的任何內容,我們都知道這很棘手 - 我只是把它作爲一個開始。關鍵是他實際要求的功能很容易,而不是像你聲稱的那樣不支持。你正在劫持他關於你想要的功能的咆哮的實際問題,而不是他要求的功能。 –

+0

聽起來不錯,謝謝。由於您對此感到困擾,我修改了我的答案並刪除了逗號後的所有內容。 – Roland