javafx: двойной щелчок по пустой строке открывает предварительно выбранный объект - PullRequest
0 голосов
/ 01 сентября 2018

Учитывая TableView, мне нужно обнаружить двойной щелчок, чтобы открыть новое окно связанного объекта.

Но если я выберу объект, а затем щелкну пустое место в таблице, он откроет объект, который я выбрал ранее.

Я оглядывался по сторонам, и все определяют строку объекта для табличного представления, и когда строка пуста (row.isEmpty()), они решают проблему.

Итак, мой вопрос: могу ли я сделать то же самое, не указывая строки TableView?

Вот контроллер для моего стола:

Я итальянец, поэтому некоторые вещи написаны на итальянском (например, имя объекта и переменных) Я выделил ту часть, которая важна для создания таблицы следующим комментарием: / **** часть таблицы **** /

    package application;

    import java.net.URL;
    import java.util.ResourceBundle;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.fxml.FXML;
    import javafx.fxml.FXMLLoader;
    import javafx.fxml.Initializable;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.scene.image.Image;
    import javafx.scene.image.ImageView;
    import javafx.scene.input.MouseEvent;
    import javafx.stage.Stage;



    public class ControllerListaTest implements Initializable,EventHandler<ActionEvent>{

        private final Image immagine1  = new Image("https://pa1.narvii.com/6360/8fcb3b5341f11cbb119ff7139350c6d1296b338d_hq.gif");
        private final Image immagine2  = new Image("http://www.peency.com/images/2015/10/04/vegeta-majin-gif.gif");
        private final Image immagine3  = new Image("https://static.comicvine.com/uploads/original/11133/111334329/6132586-0162048443-9e374.gif");
    @FXML
    private Button bottone;
    //la creazione della tabella è stata fatta con scene builder le colonne sono state invece create direttamente dal file mostraopere.fxml
    /****creation of the table****/
    @FXML private TableView<Opera> tabella; //imposto il contenuto della tabella
    /****creation of the columns****/
    @FXML private TableColumn<Opera,ImageView> colonna1;//imposto il tipo della prima colonna
    @FXML private TableColumn<Opera,String> colonna2;//imposto il tipo della seconda colonna
    @FXML private TableColumn<Opera,String> colonna3;//imposto il tipo della terza colonna



    @Override
    public void initialize(URL url, ResourceBundle rb) {
    /****setting the table ****/
        tabella.setMaxWidth(600);
        tabella.setMinWidth(600);
        colonna1.setMinWidth(200);
        colonna1.setMaxWidth(200);
        colonna2.setMinWidth(200);
        colonna2.setMinWidth(200);
        colonna3.setMinWidth(200);
        colonna3.setMinWidth(200);

        bottone.setOnAction(this);
    }

    @Override
    public void handle(ActionEvent event) {
        // TODO Auto-generated method stub
        if(event.getSource()==bottone) {
            //creazione delle opere
            Opera opera = new Opera("Il SuperSayan","Giangiacomo Frizzantino",immagine1);
            Opera opera1 = new Opera("Goku è scarso ed ecco perchè","Pierpaolo stracazzi",immagine2);
            Opera opera2 = new Opera("mi piace la droga","Marzio Fannullone",immagine3);
            Opera opera3 = new Opera("10 cose positive della bestiality","Patrizio Fallo");
            //creazione del contenuto di un opera
            ContenutoOpera immagineuno = new ContenutoOpera(immagine1,opera,"1");
            ContenutoOpera immaginedue = new ContenutoOpera(immagine1,opera,"2");
            ContenutoOpera immaginetre = new ContenutoOpera(immagine1,opera,"3");
            ContenutoOpera immaginequattro = new ContenutoOpera(opera,"4");
            //caricamento dell contenuto di un opera nelle rispettive liste(Opere)
            opera.addImmagine(immagineuno);
            opera.addImmagine(immaginedue);
            opera.addImmagine(immaginetre);
            opera.addImmagine(immagineuno);
            opera.addImmagine(immaginedue);
            opera.addImmagine(immaginetre);
            opera.addImmagine(immagineuno);
            opera.addImmagine(immaginedue);
            opera.addImmagine(immaginetre);
            opera.addImmagine(immagineuno);
            opera.addImmagine(immaginedue);
            opera.addImmagine(immaginetre);
            opera.addImmagine(immagineuno);
            opera.addImmagine(immaginedue);
            opera.addImmagine(immaginedue);
            opera.addImmagine(immaginetre);
            opera.addImmagine(immagineuno);
            opera.addImmagine(immaginedue);
            opera.addImmagine(immaginetre);
            opera1.addImmagine(immaginetre);
            opera1.addImmagine(immaginetre);
            opera.addImmagine(immaginequattro);
            //indirizzo il contenuto delle colonne
            /****setting the column****/
            colonna1.setCellValueFactory(new PropertyValueFactory<>("Image"));
            colonna2.setCellValueFactory(new PropertyValueFactory<>("Opera"));
            colonna3.setCellValueFactory(new PropertyValueFactory<>("Autore"));
            //creo una lista di opere
            ObservableList<Opera> opere = FXCollections.observableArrayList();
            //aggiungo le opere alla lista
            opere.add(opera);
            opere.add(opera1);
            opere.add(opera2);
            opere.add(opera3);
            //TEST
            System.out.println(opera.getLista().size() + " (numero di elementi in opera)");
/****retrive the elements of a list and add them to the table****/
            tabella.getItems().setAll(opere);
            /****resulted from the click of the table****/
            tabella.setOnMousePressed(new EventHandler<MouseEvent>(){

                @Override
                public void handle(MouseEvent event) {                
                   // System.out.println(tabella.getSelectionModel().getSelectedItem().getNome());
                /****check the double click****
if(event.getClickCount() == 2){ 
                    if(tabella.getSelectionModel().getSelectedItem().getAutore()!="")  //ricordarsi di fare il controllo per verificare che l'oggetto è di tipo ContenutoOpera
                    try {
                            FXMLLoader fxmlLoader = new FXMLLoader();
                                    fxmlLoader.setLocation(getClass().getResource("ciao label.fxml"));
                                    Parent root1 = (Parent) fxmlLoader.load();

                                    Stage stage = new Stage();
                                    stage.setScene(new Scene(root1)); 
                                    Controllerlabel controller = fxmlLoader.getController();
         /****passes the selected object to another controller**** 
                    controller.initData(tabella.getSelectionModel().getSelectedItem());        
                                    stage.show();
                            } catch(Exception e) {
                               e.printStackTrace();
                              }
                        }
                    }
                }

            );


        }

    }
    public void pressButton(ActionEvent event) throws Exception {               
        try {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("ciao label.fxml"));
                Parent root1 = (Parent) fxmlLoader.load();
                Stage stage = new Stage();
                stage.setScene(new Scene(root1));  
                stage.show();
        } catch(Exception e) {
           e.printStackTrace();
          }
    }
    }

1 Ответ

0 голосов
/ 01 сентября 2018

Двойной щелчок по пустой строке приводит к тому, что вы открываете последний выбранный элемент, потому что вы добавляете EventHandler к TableView. Когда вы щелкаете в любом месте TableView, включая пустые строки, вызывается EventHandler. То, что вы хотите, это для каждой строки EventHandler, которая проверяет, является ли строка пустой или нет. Кроме того, поскольку каждый TableRow имеет ссылку на свой элемент, вам не нужно использовать модель выбора TableView. Вот пример:

import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;

public class Controller {

  @FXML
  private TableView<Object> table; // Using <Object> for example

  @FXML
  private void initialize() {
    EventHandler<MouseEvent> onClick = this::handleTableRowMouseClick;
    table.setRowFactory(param -> {
      TableRow<Object> row = new TableRow<>();
      row.setOnMouseClicked(onClick);
      return row;
    });
  }

  private void handleTableRowMouseClick(MouseEvent event) {
    if (event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2) {

      // We know it will be a TableRow<Object> since that is the only kind
      // of object we added the EventHandler to.
      @SuppressWarnings("unchecked")
      TableRow<Object> row = (TableRow<Object>) event.getSource();

      if (!row.isEmpty() && row.getItem() != null) {
        displayItem(row.getItem());
        event.consume();
      }
    }
  }

  private void displayItem(Object item) {
    // This is where you'd put your code that opens the item in
    // its own Stage.
  }

}

В этом примере EventHandler используется совместно с каждым TableRow, созданным rowFactory. Это нормально, поскольку мы можем получить источник (т. Е. TableRow, на который нажали), вызвав MouseEvent.getSource(). Я разделил вещи на несколько методов, чтобы сделать код более читабельным / поддерживаемым.

В примере проверяется, была ли кнопка мыши основной кнопкой. Если вам все равно, какая кнопка была нажата дважды, вы можете просто снять эту проверку.

...