2016-02-04 103 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