2013-03-27 25 views
17

Her ListView Öğesinden sonra bir Görüntü Düğmesi eklenmesi mümkün olup olmadığını bilmek istiyorum. Örneğin, bu kırmızı karelerin bunun yerine bir düğmesinin olması gerektiği yerde sampleJavaFX - Bir Görüntü Düğmesi ile ListView Öğesi

. Mümkünse, öğenin düğmesinin tıklama etkinliğini nasıl ele alabilirim?

DÜZENLEME: Yapabilecek başka bir denetim varsa, lütfen bana bildirin. TableView'ı test ediyorum.

Şimdiden teşekkürler!

cevap

27

Bunu yakın zamanda test ediyordum. Benim çözüm:

import javafx.application.Application; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.Label; 
import javafx.scene.control.ListCell; 
import javafx.scene.control.ListView; 
import javafx.scene.layout.HBox; 
import javafx.scene.layout.Pane; 
import javafx.scene.layout.Priority; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 
import javafx.util.Callback; 

public class SO extends Application { 
    static class XCell extends ListCell<String> { 
     HBox hbox = new HBox(); 
     Label label = new Label("(empty)"); 
     Pane pane = new Pane(); 
     Button button = new Button("(>)"); 
     String lastItem; 

     public XCell() { 
      super(); 
      hbox.getChildren().addAll(label, pane, button); 
      HBox.setHgrow(pane, Priority.ALWAYS); 
      button.setOnAction(new EventHandler<ActionEvent>() { 
       @Override 
       public void handle(ActionEvent event) { 
        System.out.println(lastItem + " : " + event); 
       } 
      }); 
     } 

     @Override 
     protected void updateItem(String item, boolean empty) { 
      super.updateItem(item, empty); 
      setText(null); // No text in label of super class 
      if (empty) { 
       lastItem = null; 
       setGraphic(null); 
      } else { 
       lastItem = item; 
       label.setText(item!=null ? item : "<null>"); 
       setGraphic(hbox); 
      } 
     } 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     StackPane pane = new StackPane(); 
     Scene scene = new Scene(pane, 300, 150); 
     primaryStage.setScene(scene); 
     ObservableList<String> list = FXCollections.observableArrayList(
       "Item 1", "Item 2", "Item 3", "Item 4"); 
     ListView<String> lv = new ListView<>(list); 
     lv.setCellFactory(new Callback<ListView<String>, ListCell<String>>() { 
      @Override 
      public ListCell<String> call(ListView<String> param) { 
       return new XCell(); 
      } 
     }); 
     pane.getChildren().add(lv); 
     primaryStage.show(); 
    } 

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

hücreleri aşağıdaki gibi görünecektir:

Custom List Cell with Button

ilgili kısmı XCell.updateItem yöntemi ve setGraphic çağrıdır. setGraphic() ile genellikle bir etiket için bir simge belirlenir, ancak karmaşık bir Düğüm ayarlamak için eşit derecede iyi çalışır - bu durumda etiketli ve düğmeli HBox.

Button olay işleyicisinin listedeki doğru öğeye başvurduğundan emin olmanız gerekir. Aşağıdaki ilk bağlantıda, şu an seçili olan öğenin şimdilik yeterli olabileceği belirtilmektedir. Bu yüzden, düğmenin olayını ele alırken o anda seçili dizini listede getir.

Sen bunlara bakmak hoşunuza gidebilir: my liste büyük değildi zaman

+1

Mükemmel! Kodlama için çok teşekkürler! İyi çalıştı! – Leonardo

+0

Geçerli öğeyi 'lastItem' alanında saklamanıza gerek yoktur. Doğrudan düğme işleyicisinde 'getItem()' yi çağırabilirsiniz. –

0

önceki çözüm iyi çalıştı ve yapım daha Kontroller eklemeyen Düğüm daha karmaşık. Daha fazla Kontrol eklediğimde eşzamanlılık ile ilgili bir problem buldum, belki de 12000'den fazla nesneye (çizgiler ve çokgenler) sahip haritalar çiziyorum. Sorun (görebildiğim), ListView'deki öğelerin bazılarının dahili olarak tekrarlanmasının, hücre yapısının iki kez yaratılacağı ve/veya oluşturulmayacağı anlamına geldiğiydi. İş parçacığının kuyruğunda "updateItem" en son görünüyor. Yani, bu soruna geçici bir çözüm bulmak için ListView'u oluşturmadan önce düğüm oluşturmak zorundayım. Böyle bir şey:

ObservableList<Node> list = FXCollections.observableArrayList(); 
    for (AisaLayer layer : listLayers) { 
     mapLayers.put(layer.getLayerName(), layer); 
     list.add(new AisaNode(layer)); 
     System.out.println("Ordered:" + layer.getLayerName()); 
    } 
    lv.setItems(list); 
    lv.setCellFactory(new Callback<ListView<Node>, ListCell<Node>>() { 
     @Override 
     public ListCell<Node> call(ListView<Node> param) { 
      return new DefaultListCell<>(); 
     } 
    }); 

Basit DefaultListCell fxexperience.com

2

Ayrıca, özel HBox nesnelerin listesi kullanabilirsiniz tavsiye kullandı. Aşağıdaki örnek, böyle bir özel HBox iç sınıfının ve bu gibi nesnelerin yuvalama listesinin ListView kontrolüne kullanımını göstermektedir. Bu uygulamanın sonucu

import java.util.ArrayList; 
import java.util.List; 
import javafx.application.Application; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.Label; 
import javafx.scene.control.ListView; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.HBox; 
import javafx.scene.layout.Priority; 
import javafx.stage.Stage; 


public class ListViewDemo extends Application { 

    public static class HBoxCell extends HBox { 
      Label label = new Label(); 
      Button button = new Button(); 

      HBoxCell(String labelText, String buttonText) { 
       super(); 

       label.setText(labelText); 
       label.setMaxWidth(Double.MAX_VALUE); 
       HBox.setHgrow(label, Priority.ALWAYS); 

       button.setText(buttonText); 

       this.getChildren().addAll(label, button); 
      } 
    } 

    public Parent createContent() { 
      BorderPane layout = new BorderPane(); 

      List<HBoxCell> list = new ArrayList<>(); 
      for (int i = 0; i < 12; i++) { 
       list.add(new HBoxCell("Item " + i, "Button " + i)); 
      } 

      ListView<HBoxCell> listView = new ListView<HBoxCell>(); 
      ObservableList<HBoxCell> myObservableList = FXCollections.observableList(list); 
      listView.setItems(myObservableList); 

      layout.setCenter(listView); 

      return layout; 
    } 

    @Override 
    public void start(Stage stage) throws Exception { 
      stage.setScene(new Scene(createContent())); 
      stage.setWidth(300); 
      stage.setHeight(200); 
      stage.show(); 
    } 

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

aşağıdaki gibi görünecektir:

enter image description here

Ancak sırayla etkinliğine Düğmeler etkinliklerden haberdar HBoxCustom yapıcı yöntemine içine ek özel Düğme nesnesi ekleyerek düşünmelisiniz yönetmek, ve düğmelerin tıklama etkinliklerini kontrol etmenizi sağlayacak uygun bir yöntem oluşturun.

İlgili konular