2017-05-22 4 views
0

Ich schreibe eine Anwendung von Swing nach javafx um.Rechtsklick Event und Doppelklick Event auf Tabellenansicht javafx

Ich verstehe nicht, wie ein Doppelklick-Ereignis und ein Rechtsklick-Ereignis in derselben Zeile einer Tabellenansicht implementiert werden. Separat funktionieren sie ok.

Thi ist mein Code für Rechtsklickverhalten.

words_table.setRowFactory(
new Callback<TableView<WordsToFind>, TableRow<WordsToFind>>() { 
@Override 
public TableRow<WordsToFind> call(TableView<WordsToFind> tableView) { 
final TableRow<WordsToFind> row = new TableRow<>(); 
final ContextMenu rowMenu = new ContextMenu(); 
MenuItem removeItem = new MenuItem("Delete"); 
removeItem.setOnAction(e -> { 
int wordid = words_table.getSelectionModel().getSelectedItem().getWordToFindId(); 
deleteWord(wordid); 
words_table.getItems().remove(row.getItem()); 
}); 
rowMenu.getItems().addAll(removeItem); 
row.contextMenuProperty().bind(
    Bindings.when(Bindings.isNotNull(row.itemProperty())) 
    .then(rowMenu) 
    .otherwise((ContextMenu)null)); 
return row; 
    }  
}); 

Dies ist mein Code für Doppelklickverhalten

words_table.setRowFactory( 
new Callback<TableView<WordsToFind>, TableRow<WordsToFind>>() { 
@Override 
public TableRow<WordsToFind> call(TableView<WordsToFind> tableView) { 
final TableRow<WordsToFind> row = new TableRow<>(); 
row.setOnMouseClicked(new EventHandler<MouseEvent>(){ 
    @Override 
     public void handle(MouseEvent event){ 
      if (event.getClickCount() == 2 && (! row.isEmpty())) { 
       some code here ..... 
      } 
    } 
}); 
return row; 
    }  
}); 

Dank Alb

+0

einfach den 'row.setOnMouseClicked' Anruf setzen in der Methode 'call()' der Factory der ersten Zeile. –

+0

Kein Glück James, ich habe beide Lösungen ausprobiert, deine und Oswalds, beide kompilieren aber nur den Doppelklick; wenn ich den rechten klick drücke, nichts hannens. – gocan76

+0

Dann tun Sie etwas anderes falsch in einem anderen Teil Ihres Codes. Sie sollten ein [MCVE] von Grund auf neu erstellen, das das Problem veranschaulicht. –

Antwort

0

Sie beide Veranstaltungen von row.setOnMouseClicked(..) selbst unter

wie gezeigt tun, um die Zeile hinzufügen können
words_table.setRowFactory( 
    new Callback<TableView<WordsToFind>, TableRow<WordsToFind>>() { 
    @Override 
    public TableRow<WordsToFind> call(TableView<WordsToFind> tableView) { 
    final TableRow<WordsToFind> row = new TableRow<>(); 
    row.setOnMouseClicked(new EventHandler<MouseEvent>(){ 
     @Override 
      public void handle(MouseEvent event){ 

       if (event.getClickCount() == 2 && (! row.isEmpty())) { 
        //double click code here 
       } 
       else if(event.isSecondaryButtonDown()){ 
        //right click code here 
       } 
     } 
    }); 
    return row; 
     }  
    }); 
+0

Ihre Lösung ist interessant, aber es funktioniert nicht. Ich habe ein Paar System.out.println, 1 für das "if" und eins für das "else if" gesetzt, leider wird nur das erste verarbeitet, beim Rechtsklick kommt nichts heraus. – gocan76

1

Setzen Sie einfach den row.setOnMouseClicked Anruf in die call() Methode der Fabrik der ersten Reihe.

words_table.setRowFactory(tableView -> { 
    final TableRow<WordsToFind> row = new TableRow<>(); 
    final ContextMenu rowMenu = new ContextMenu(); 
    MenuItem removeItem = new MenuItem("Delete"); 
    removeItem.setOnAction(e -> { 
     int wordid = words_table.getSelectionModel().getSelectedItem().getWordToFindId(); 
     deleteWord(wordid); 
     words_table.getItems().remove(row.getItem()); 
    }); 

    rowMenu.getItems().addAll(removeItem); 
    row.contextMenuProperty().bind(
     Bindings.when(Bindings.isNotNull(row.itemProperty())) 
       .then(rowMenu) 
       .otherwise((ContextMenu)null)); 

    row.setOnMouseClicked(event -> { 
     if (event.getClickCount() == 2 && (! row.isEmpty())) { 
      // some code here ..... 
     } 
    }); 

    return row; 
}); 

(umgerechnet ich die anonymen inners Klassen Lambda-Ausdrücke für die Lesbarkeit.)

Hier ist ein vollständiges Beispiel, das dieses Arbeits zeigt:

import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 
import java.util.function.Function; 

import javafx.application.Application; 
import javafx.beans.binding.Bindings; 
import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 
import javafx.beans.value.ObservableValue; 
import javafx.scene.Scene; 
import javafx.scene.control.ContextMenu; 
import javafx.scene.control.MenuItem; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableRow; 
import javafx.scene.control.TableView; 
import javafx.stage.Stage; 

public class RowFactoryExample extends Application { 

    @Override 
    public void start(Stage primaryStage) { 

     TableView<Item> table = new TableView<>(); 
     table.getColumns().add(column("Item", Item::nameProperty)); 
     table.getColumns().add(column("Value", Item::valueProperty)); 
     table.getItems().setAll(createData()); 

     table.setRowFactory(tableView -> { 
      final TableRow<Item> row = new TableRow<>(); 
      final ContextMenu rowMenu = new ContextMenu(); 
      MenuItem removeItem = new MenuItem("Delete"); 
      removeItem.setOnAction(e -> { 
       table.getItems().remove(row.getItem()); 
      }); 

      rowMenu.getItems().addAll(removeItem); 
      row.contextMenuProperty().bind(
       Bindings.when(Bindings.isNotNull(row.itemProperty())) 
         .then(rowMenu) 
         .otherwise((ContextMenu)null)); 

      row.setOnMouseClicked(event -> { 
       if (event.getClickCount() == 2 && (! row.isEmpty())) { 
        System.out.println("Double click on "+row.getItem().getName()); 
       } 
      }); 

      return row; 
     }); 

     Scene scene = new Scene(table, 600, 600); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    private <S,T> TableColumn<S,T> column(String text, Function<S, ObservableValue<T>> prop) { 
     TableColumn<S,T> col = new TableColumn<>(text); 
     col.setCellValueFactory(cellData -> prop.apply(cellData.getValue())); 
     return col ; 
    } 

    private List<Item> createData() { 
     Random rng = new Random(); 
     List<Item> data = new ArrayList<>(); 
     for (int i = 1 ; i <= 100; i++) { 
      data.add(new Item("Item "+i, rng.nextInt(1000))) ; 
     } 
     return data ; 
    } 

    public static class Item { 

     private final StringProperty name = new SimpleStringProperty(); 
     private final IntegerProperty value = new SimpleIntegerProperty(); 

     public Item(String name, int value) { 
      setName(name); 
      setValue(value); 
     } 

     public final StringProperty nameProperty() { 
      return this.name; 
     } 


     public final String getName() { 
      return this.nameProperty().get(); 
     } 


     public final void setName(final String name) { 
      this.nameProperty().set(name); 
     } 


     public final IntegerProperty valueProperty() { 
      return this.value; 
     } 


     public final int getValue() { 
      return this.valueProperty().get(); 
     } 


     public final void setValue(final int value) { 
      this.valueProperty().set(value); 
     } 



    } 

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

Es funktioniert, danke James. Ich habe nichts anderes im Code geändert. Morgen werde ich versuchen zu verstehen, was die Unterschiede sind. – gocan76