2015-02-19 12 views
5

amacım sürükle ve bırak bir tableView sıralamak etmektir. Ben bu örneği takip: sürükle için http://docs.oracle.com/javafx/2/fxml_get_started/fxml_tutorial_intermediate.htmsıralama tableview (satırlar)

ve ben

<TableView fx:id="tableView" onDragDetected="#dragDetected" onDragDropped="#dragDropped" onDragOver="#dragOver" 

Sahne Builder aracılığıyla fxml eklendi bırakın ve kontrolörleri

@FXML 
    private void dragDetected(MouseEvent event) { 
     System.out.println("dragDetected"); 

     Integer idx; 
     idx = tableView.getSelectionModel().getFocusedIndex(); 
     Dragboard db = tableView.startDragAndDrop(TransferMode.MOVE); 
     ClipboardContent content = new ClipboardContent(); 
     content.putString(idx.toString()); 
     db.setContent(content); 

     System.out.println(idx); 
//  System.out.println(event.getPickResult()); 
     event.consume(); 
    } 

    @FXML 
    private void dragOver(DragEvent event) { 
     event.acceptTransferModes(TransferMode.COPY_OR_MOVE); 
     event.consume(); 
    } 

    @FXML 
    private void dragDropped(DragEvent event) { 
     System.out.println("dragDropped"); 

     System.out.println(event.getTarget()); 
     System.out.println(event.getPickResult()); 
    } 

yapılmış ama sürükle azından ben satırını alınamıyor düştü nesneyi düşürdüğüm yer. Tek istediğim hücre bilgisi. Text[text="Smith", x=0.0, y=0.0, ...

Bu iş nasıl alabilirim? Belki Class TableRow<T> yardımcı olabilir ama ben proberly nasıl kullanılacağını anlamıyorum. Eğer şüpheli olarak

cevap

21

, cevap TableRow kullanmaktır. Bunu, tablo satırlarını ihtiyaç duydukları şekilde oluşturmak için kullanılan, tablonuzdaki bir satır fabrikasını ayarlayarak yaparsınız. Bunları oluşturmadan önce oluşturabilir ve sürükleme işleyicilerini üzerlerine yükleyebilirsiniz. Bu nedenle, onDragDetected, onDragDropped vb. Özniteliklerini FXML'den kaldırın ve denetleyicideki başlatma yönteminde satırdaki sürükleme işleyicilerini ayarlayın. İşte

Oracle öğreticiler her zamanki örneği kullanılarak, tam bir örnektir. Bu örnekte FXML kullanmamıştım (tablo görünümünü doğrudan Java sınıfında oluşturdum), ancak tüm tablo görünümü konfigürasyonunu başlatma metoduna taşıyabilirsiniz.

import java.util.function.Function; 

import javafx.application.Application; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 
import javafx.beans.value.ObservableValue; 
import javafx.scene.Scene; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableRow; 
import javafx.scene.control.TableView; 
import javafx.scene.input.ClipboardContent; 
import javafx.scene.input.DataFormat; 
import javafx.scene.input.Dragboard; 
import javafx.scene.input.TransferMode; 
import javafx.scene.layout.BorderPane; 
import javafx.stage.Stage; 

public class TableViewDragRows extends Application { 

    private static final DataFormat SERIALIZED_MIME_TYPE = new DataFormat("application/x-java-serialized-object"); 

    @Override 
    public void start(Stage primaryStage) { 
     TableView<Person> tableView = new TableView<>(); 
     tableView.getColumns().add(createCol("First Name", Person::firstNameProperty, 150)); 
     tableView.getColumns().add(createCol("Last Name", Person::lastNameProperty, 150)); 
     tableView.getColumns().add(createCol("Email", Person::emailProperty, 200)); 

     tableView.getItems().addAll(
      new Person("Jacob", "Smith", "[email protected]"), 
      new Person("Isabella", "Johnson", "[email protected]"), 
      new Person("Ethan", "Williams", "[email protected]"), 
      new Person("Emma", "Jones", "[email protected]"), 
      new Person("Michael", "Brown", "[email protected]") 
     ); 

     tableView.setRowFactory(tv -> { 
      TableRow<Person> row = new TableRow<>(); 

      row.setOnDragDetected(event -> { 
       if (! row.isEmpty()) { 
        Integer index = row.getIndex(); 
        Dragboard db = row.startDragAndDrop(TransferMode.MOVE); 
        db.setDragView(row.snapshot(null, null)); 
        ClipboardContent cc = new ClipboardContent(); 
        cc.put(SERIALIZED_MIME_TYPE, index); 
        db.setContent(cc); 
        event.consume(); 
       } 
      }); 

      row.setOnDragOver(event -> { 
       Dragboard db = event.getDragboard(); 
       if (db.hasContent(SERIALIZED_MIME_TYPE)) { 
        if (row.getIndex() != ((Integer)db.getContent(SERIALIZED_MIME_TYPE)).intValue()) { 
         event.acceptTransferModes(TransferMode.COPY_OR_MOVE); 
         event.consume(); 
        } 
       } 
      }); 

      row.setOnDragDropped(event -> { 
       Dragboard db = event.getDragboard(); 
       if (db.hasContent(SERIALIZED_MIME_TYPE)) { 
        int draggedIndex = (Integer) db.getContent(SERIALIZED_MIME_TYPE); 
        Person draggedPerson = tableView.getItems().remove(draggedIndex); 

        int dropIndex ; 

        if (row.isEmpty()) { 
         dropIndex = tableView.getItems().size() ; 
        } else { 
         dropIndex = row.getIndex(); 
        } 

        tableView.getItems().add(dropIndex, draggedPerson); 

        event.setDropCompleted(true); 
        tableView.getSelectionModel().select(dropIndex); 
        event.consume(); 
       } 
      }); 

      return row ; 
     }); 


     Scene scene = new Scene(new BorderPane(tableView), 600, 400); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    private TableColumn<Person, String> createCol(String title, 
      Function<Person, ObservableValue<String>> mapper, double size) { 

     TableColumn<Person, String> col = new TableColumn<>(title); 
     col.setCellValueFactory(cellData -> mapper.apply(cellData.getValue())); 
     col.setPrefWidth(size); 

     return col ; 
    } 


    public class Person { 
     private final StringProperty firstName = new SimpleStringProperty(this, "firstName"); 
     private final StringProperty lastName = new SimpleStringProperty(this, "lastName"); 
     private final StringProperty email = new SimpleStringProperty(this, "email"); 

     public Person(String firstName, String lastName, String email) { 
      this.firstName.set(firstName); 
      this.lastName.set(lastName); 
      this.email.set(email); 
     } 

     public final StringProperty firstNameProperty() { 
      return this.firstName; 
     } 

     public final String getFirstName() { 
      return this.firstNameProperty().get(); 
     } 

     public final void setFirstName(final String firstName) { 
      this.firstNameProperty().set(firstName); 
     } 

     public final StringProperty lastNameProperty() { 
      return this.lastName; 
     } 

     public final String getLastName() { 
      return this.lastNameProperty().get(); 
     } 

     public final void setLastName(final String lastName) { 
      this.lastNameProperty().set(lastName); 
     } 

     public final StringProperty emailProperty() { 
      return this.email; 
     } 

     public final String getEmail() { 
      return this.emailProperty().get(); 
     } 

     public final void setEmail(final String email) { 
      this.emailProperty().set(email); 
     } 

    } 

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

ne koymak için nereye daha detaylı açıklayabilir misiniz. (. Aptal soru muhtemelen) Benim IDE ben özel TableView tableView @FXML 'sonra işleyicisi koyarsanız bir sınıf' tv' oluşturmak için sever; ' – schasoli

+0

kontrolörün' başlatmak() 'yönteminde işleyicileri koyun. –

+1

Merhaba @James_D, sormak istiyorum: neden SERIALIZED_MIME_TYPE 'kullanıyoruz? Bu ne için ? – mynameisJEFF

1

FMXL içine (James_D itibaren) 1 cevabı çalışma:

<TableView fx:id="tableView" GridPane.columnIndex="0" GridPane.rowIndex="1">

public class FXMLTableViewController implements Initializable { 
    private static final DataFormat SERIALIZED_MIME_TYPE = new DataFormat("application/x-java-serialized-object"); 

    @Override 
    public void initialize(URL url, ResourceBundle resourceBundle) { 
     tableView.setRowFactory(tv -> { 
     ... 
      return row ; 
     }); 
    } 

    @FXML 
    private TableView<Person> tableView; 
    ... 
+0

Sadece FXML tabanlı sürümü göstermek için cevabı düzenlemek için geri geliyordum, ama evet, bu tam olarak doğru. –