2016-11-02 4 views
0

У меня есть проект Java, над которым я работаю, который использует JavaFX для создания пользовательского интерфейса. Я не очень программист на Java (не большая часть программиста в целом - я студент CS), так что это немного учебный опыт, но, как правило, я отвечаю на свои вопросы, когда я иду. Тем не менее, я теперь сталкиваюсь с липким пятном с TableView, и немного теряюсь - в частности, я не могу представить никаких действий в ответ на взаимодействие с TableView.Определение TableView onMouseПредусмотренные действия в FXML

Текущий макет моего проекта - Main.java, Controller.java и UI.fxml. В главном окне панель/сцена загружается из UI.fxml при запуске программы. (Технически проект содержит несколько других битов кода, но я пытаюсь только после того, что релевантно.) У меня есть TableView определено в UI.fxml, как так:

<TableView fx:id="queueTable"> 
    <columns> 
     <TableColumn text="Title"> 
      <cellValueFactory> 
       <PropertyValueFactory property="tableTitle"/> 
      </cellValueFactory> 
     </TableColumn> 
     <TableColumn text="Artist"> 
      <cellValueFactory> 
       <PropertyValueFactory property="tableArtist"/> 
      </cellValueFactory> 
     </TableColumn> 
     <TableColumn text="Album"> 
     <cellValueFactory> 
       <PropertyValueFactory property="tableAlbum"/> 
      </cellValueFactory> 
     </TableColumn> 
    </columns> 
</TableView> 

Аналогично у меня есть несколько кнопок, определенных в интерфейсе .fxml с OnAction, как так:

<Button fx:id="buttonQueueAdd" text="Add" onAction="#addMediaToQueue"/> 

в моем предыдущем коде я был в состоянии определить событие для того, когда был выбран элемент в TableView, в способе, где мой TableView был быть сгенерирован. Теперь, однако, все создание пользовательского интерфейса выполняется через файл FXML. Файл FXML имеет класс контроллера, к которому он относится (Controller.java), где все действия определены для разных кнопок, но я не могу заставить его принимать какие-либо атрибуты, такие как onAction, setOnMousePressed и т. Д. В FXML файл для TableView, так как он принимает атрибут 'onAction' для Button.

Кажется, что я могу получить обходное решение, определяя действие в моем основном классе (или создавая метод в моем классе Controller, который вызывается в классе Main, когда создается сцена), но это не будет работайте, если я не сделаю queueTable статичным в моем классе контроллера ..., который затем разбивает все функции, которые обрабатывают элементы в TableView - например, я больше не могу добавлять элементы в TableView/пользовательский интерфейс не обновляется, чтобы показать, что элементы добавлены.

Похоже, лучшее решение - не иметь TableView, созданного в FXML, вместо этого создать TableView и все его события onMousePressed и т. Д., Установленные за пределами файла FXML, и добавить их в сцену в моем Метод основного класса start. Это было сделано ранее, и тогда это было приемлемо. Однако это кажется беспорядочным и приводит к тому, что мои элементы пользовательского интерфейса усеяны несколькими классами и/или файлом FXML - это проект, над которым я работаю с несколькими другими учениками, и я стараюсь держать все как упорядоченное/организованное насколько это возможно. Должен ли я укусить пулю и сделать это «грязным» способом, или есть лучший вариант?

ответ

0

Вы все еще можете сгенерировать TableView с помощью fxml, но добавьте метод initialize к контроллеру. Этот метод вызывается FXMLLoader после того, как будет сделано созданием объекта stucture и может быть использовано для модификации структуры объекта, что вы не можете сделать из FXML:

@FXML 
private void initialize() { 
    queueTable.getSelectionModel().selectedIndexProperty().addListener((observable, oldValue, newValue) -> { 
     ... 
    }); 
} 

В случае, если вам нужно добавить этот приемник от Main, вы можете добавить метод к контроллеру и получить контроллер из экземпляра FXMLLoader, который вы используете для создания fxml.

Контроллер

public void addSelectedIndexListener(ChangeListener<? super Number> listener) { 
    queueTable.getSelectionModel().selectedIndexProperty().addListener(listener); 
} 

Главная

FXMLLoader loader = new FXMLLoader(fxmlUrl); 
myNode = loader.load(); 
Controller controller = loader.getController(); 
controller.addSelectedIndexListener((observable, oldValue, newValue) -> { 
    ... 
}); 

Обратите внимание, что это свойство свойство должно зависеть от свойства модели выбора, вы можете быть в состоянии использовать expression binding для достижения желаемого эффекта.

<BorderPane xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1"> 
    <center> 
     <TableView fx:id="table" BorderPane.alignment="CENTER"> 
      <columns> 
       <TableColumn text="value"> 
        <cellValueFactory> 
         <PropertyValueFactory property="value"/> 
        </cellValueFactory> 
       </TableColumn> 
      </columns> 
      <items> 
       <FXCollections fx:factory="observableArrayList"> 
        <Item value="Hello World"/> 
        <Item value="42"/> 
       </FXCollections> 
      </items> 
     </TableView> 
    </center> 
    <left> 
     <Button mnemonicParsing="false" text="Remove" BorderPane.alignment="CENTER" disable="${table.selectionModel.selectedIndex+0&lt;0}" /> 
    </left> 
</BorderPane> 

Обратите внимание, что table.selectionModel.selectedIndex+0<0 часть обходной путь используется, поскольку JavaFX в настоящее время не использует null -Safe проверки равенства (table.selectionModel.selectedItem==null не работает) и не может получить тип 0 постоянного права для сравнения (table.selectionModel.selectedIndex<0), поэтому в настоящее время это не похоже на хороший вариант.