2017-09-25 50 views
0

我如何做编辑TableView的按钮动作。当我触摸按钮时,我需要将TextArea的文字放到表格中。如果把System.out.println放在inputToTable()这是工作。在InputController通过主FXML文件fx:include一次,一次,通过你的tableControllerInit()方法创建FXMLLoader控制器之间的JavaFx动作

public class InputController { 

    public TextArea inputArea; 
    public Button inputButton; 
    private TableController tableController; 

    public void initialize() { 
     tableControllerInit(); 
    } 

    public void inputToTable() { 
     if(inputArea.getText() != "") { 
      tableController.tableInfo.setItems(FXCollections.observableArrayList(new InputObject(inputArea.getText()))); 
     } 
    } 

    private void tableControllerInit() { 
     try { 
      FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("table.fxml")); 
      fxmlLoader.load(); 
      tableController = fxmlLoader.getController(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

public class TableController { 

    @FXML TableView<InputObject> tableInfo; 
    @FXML TableColumn<InputObject, String> col1; 

    public void initialize() { 
     col1.setCellValueFactory(new PropertyValueFactory<>("text")); 
    } 
} 

public class Controller implements Initializable { 

    @Override 
    public void initialize(URL location, ResourceBundle resources) { 

    } 
} 

public class InputObject { 
    String text; 

    public InputObject(String text) { 
     this.text = text; 
    } 

    public String getText() { 
     return text; 
    } 

    public void setText(String text) { 
     this.text = text; 
    } 
} 



<BorderPane fx:controller="sample.Controller" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"> 
    <left> 
     <fx:include source="table.fxml"/> 
    </left> 
    <center> 
     <fx:include source="input.fxml"/> 
    </center> 
</BorderPane> 

<TableView fx:controller="sample.TableController" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:id="tableInfo" prefHeight="400.0" prefWidth="330.0"> 
    <columns> 
     <TableColumn fx:id="col1" prefWidth="75.0" text="Output" /> 
    </columns> 
    <columnResizePolicy> 
     <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /> 
    </columnResizePolicy> 
</TableView> 

<VBox fx:controller="sample.InputController" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" alignment="TOP_CENTER" prefHeight="200.0" prefWidth="100.0" BorderPane.alignment="CENTER"> 
    <children> 
     <TextArea fx:id="inputArea" prefHeight="188.0" prefWidth="270.0" /> 
     <Button fx:id="inputButton" onAction="#inputToTable" mnemonicParsing="false" text="Input"> 
      <VBox.margin> 
       <Insets bottom="30.0" left="30.0" right="30.0" top="30.0" /> 
      </VBox.margin> 
     </Button> 
    </children> 
</VBox> 

回答

1

您加载table.fxml两次。因此,创建了两个TableController实例,一个与您从table.fxml加载的第一个UI相关联,另一个与您从table.fxml加载的第二个UI相关联。

您通过fx:include加载的UI显示在主FXML文件中定义的VBox中。您加载FXMLLoader的用户界面从不显示(实际上,您甚至不会保留对它的引用,只需调用loader.load()并放弃结果)。当您尝试更新表格的项目时(您是否真的打算替换所有现有的项目,顺便说一下?),您可以参考第二个控制器实例,该实例与从未显示的UI相关联。因此,您正在更新未显示的表格,并且您从未看到任何结果。

您真正需要做的是在与两个fx:include相关联的两个控制器之间共享相同的数据。您可以简单地将这两个控制器注入主控制器,如文档中的"Nested Controllers"部分所述。

首先,给fx:include元件fx:id属性:

<BorderPane fx:controller="sample.Controller" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"> 
    <left> 
     <fx:include fx:id="table" source="table.fxml"/> 
    </left> 
    <center> 
     <fx:include fx:id="input" source="input.fxml"/> 
    </center> 
</BorderPane> 

然后,可以通过用附加到fx:id"Controller"创建字段注入控制器到主控制器。建立一个单一的可观察到的列表,这将代表在表中显示的项目的列表中,并把它传递到每个控制器:

public class Controller implements Initializable { 

    @FXML 
    private TableController tableController ; 

    @FXML 
    private InputController inputController ; 

    @Override 
    public void initialize(URL location, ResourceBundle resources) { 
     ObservableList<InputObject> items = FXCollections.observableArrayList(); 
     tableController.setTableItems(items); 
     inputController.setTableItems(items); 
    } 
} 

最后,只定义在每个其它两个控制器的明显的方法:

public class TableController { 

    @FXML 
    private TableView<InputObject> tableInfo; 
    @FXML 
    private TableColumn<InputObject, String> col1; 

    public void initialize() { 
     col1.setCellValueFactory(new PropertyValueFactory<>("text")); 
    } 

    public void setTableItems(ObservableList<InputObject> tableItems) { 
     tableInfo.setItems(tableItems); 
    } 
} 

现在表格显示在主控制器的initalize()方法中创建的items列表的内容,并且InputController对同一列表有引用。所以你所要做的就是更新InputController中的列表。我以为你只是想添加项目表(不全部更换):

public class InputController { 

    @FXML 
    private TextArea inputArea; 
    @FXML 
    private Button inputButton; 

    private ObservableList<InputObject> tableItems ; 

    public void setTableItems(ObservableList<InputObject> tableItems) { 
     this.tableItems = tableItems ; 
    } 

    public void inputToTable() { 
     if(! inputArea.getText().isEmpty()) { 
      tableItems.add(new InputObject(inputArea.getText())); 
     } 
    } 


} 

更一般地,如果你有更多的数据不同的控制器之间共享,您将创建一个或多个“模型”类并与控制器共享模型实例。然后您可以观察模型的属性并更新它们。有关更全面的示例,请参阅Applying MVC With JavaFx

相关问题