2015-03-03 7 views
7

मैं एक साधारण सूची दृश्य बनाना चाहता हूं। मैंने सोचा है कि मैं विधि सेटेलफैक्टरी() विधि का उपयोग कर सकता हूं लेकिन मुझे समझ में नहीं आता कि उन्हें सही तरीके से कैसे उपयोग किया जाए। अब तक मेरे पास है:जावाएफएक्स 8, चेकबॉक्स के साथ ListView

myListView.setCellFactory(CheckBoxListCell.forListView(property)); 

के साथ "संपत्ति" कुछ किया जा रहा है एक कॉलबैक कहा जाता है - मुझे लगता है कि कॉलबैक द्विदिश सीमांकन के साथ कुछ है। तो मैं एक

property = new CallBack<String, ObservableValue<Boolean>>(); 

मेरे संकलक कह रहा है कि अगर मैं एक नया कॉलबैक बनाने के लिए, मैं विधि कॉल के ऊपर लिख करने की आवश्यकता है बनाया।

और यहां मैं फंस गया हूं। मैं उस विधि कॉल के साथ क्या करूँ? मैं इसे कार्यान्वित कर सकता हूं, लेकिन मुझे वापस क्या करना चाहिए, या इसका उपयोग करना चाहिए? मैं किसी भी सूची में अपने चेकबॉक्स पर क्लिक करना चाहता हूं और इसे कंसोल में "हाय" प्रदर्शित करना है।

उत्तर

18

आप एक ListView<String> है, तो ListView में प्रत्येक आइटम एक String है, और CheckBoxListCell.forListView(...) विधि एक Callback<String, ObservableValue<Boolean>> की उम्मीद है।

चीजों के बारे में सोच के पूर्व जावा 8 तरह, एक Callback<String, ObservableValue<Boolean>> एक अंतरफलक है कि एक ही विधि को परिभाषित करता है,

public ObservableValue<Boolean> call(String s) ; 

तो तुम कुछ है कि है कि इंटरफ़ेस को लागू करता है की जरूरत है, और आप की एक वस्तु में पारित उस प्रकार।

documentation भी आपको बताता है कि कि कॉलबैक प्रयोग किया जाता है:

एक कॉलबैक कि, प्रकार टी की एक वस्तु (जो ListView.items सूची के बाहर ले जाया एक मूल्य है) को देखते हुए, एक वापस आ जाएगी ObservableValue जो दर्शाता है कि दिया गया आइटम चयनित है या नहीं। यह ObservableValue द्विपक्षीय रूप से (जिसका अर्थ है कि सेल में चेकबॉक्स उपयोगकर्ता की इंटरैक्शन के आधार पर इस प्रॉपर्टी को सेट/अनसेट करेगा, और चेकबॉक्स ऑब्जर्वेबल वैल्यू की स्थिति को प्रतिबिंबित करेगा, अगर यह बाहरी रूप से बदलता है)।

(चूंकि आप एक ListView<String> है, यहाँ TString है।) तो, सूची दृश्य में प्रत्येक तत्व (प्रत्येक तत्व एक String है) के लिए, कॉलबैक एक ObservableValue<Boolean> जो दोनों ओर के लिए बाध्य है निर्धारित करने के लिए प्रयोग किया जाता है चेकबॉक्स की स्थिति। अर्थात। यदि चेकबॉक्स चेक किया गया है, तो वह संपत्ति true पर सेट की गई है, और यदि अनचेक किया गया है तो यह false पर सेट है। इसके विपरीत, यदि संपत्ति true (या false) पर प्रोग्रामेटिक रूप से सेट की गई है, तो चेकबॉक्स चेक किया गया है (या अनचेक)।

सामान्य उपयोग केस यह है कि ListView में आइटम का प्रकार BooleanProperty होगा जो इसके राज्य के हिस्से के रूप में होगा। तो अगर आप आम तौर पर इस कस्टम वर्ग अपने डेटा का प्रतिनिधित्व करने के कुछ प्रकार के साथ, भीतर Item वर्ग के साथ इस प्रकार का प्रयोग करेंगे:

import javafx.application.Application; 
import javafx.beans.property.BooleanProperty; 
import javafx.beans.property.SimpleBooleanProperty; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 
import javafx.beans.value.ObservableValue; 
import javafx.scene.Scene; 
import javafx.scene.control.ListView; 
import javafx.scene.control.cell.CheckBoxListCell; 
import javafx.scene.layout.BorderPane; 
import javafx.stage.Stage; 
import javafx.util.Callback; 

public class ListViewWithCheckBox extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     ListView<Item> listView = new ListView<>(); 
     for (int i=1; i<=20; i++) { 
      Item item = new Item("Item "+i, false); 

      // observe item's on property and display message if it changes: 
      item.onProperty().addListener((obs, wasOn, isNowOn) -> { 
       System.out.println(item.getName() + " changed on state from "+wasOn+" to "+isNowOn); 
      }); 

      listView.getItems().add(item); 
     } 

     listView.setCellFactory(CheckBoxListCell.forListView(new Callback<Item, ObservableValue<Boolean>>() { 
      @Override 
      public ObservableValue<Boolean> call(Item item) { 
       return item.onProperty(); 
      } 
     })); 

     BorderPane root = new BorderPane(listView); 
     Scene scene = new Scene(root, 250, 400); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public static class Item { 
     private final StringProperty name = new SimpleStringProperty(); 
     private final BooleanProperty on = new SimpleBooleanProperty(); 

     public Item(String name, boolean on) { 
      setName(name); 
      setOn(on); 
     } 

     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 BooleanProperty onProperty() { 
      return this.on; 
     } 

     public final boolean isOn() { 
      return this.onProperty().get(); 
     } 

     public final void setOn(final boolean on) { 
      this.onProperty().set(on); 
     } 

     @Override 
     public String toString() { 
      return getName(); 
     } 

    } 

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

आप वास्तव में एक ListView<String> है, तो यह वास्तव में स्पष्ट नहीं है क्या संपत्ति पर क्लिक करके आप सेट कर रहे हैं चेक बॉक्स पर होगा।

import javafx.application.Application; 
import javafx.beans.property.BooleanProperty; 
import javafx.beans.property.SimpleBooleanProperty; 
import javafx.beans.value.ObservableValue; 
import javafx.scene.Scene; 
import javafx.scene.control.ListView; 
import javafx.scene.control.cell.CheckBoxListCell; 
import javafx.scene.layout.BorderPane; 
import javafx.stage.Stage; 
import javafx.util.Callback; 

public class ListViewWithStringAndCheckBox extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     ListView<String> listView = new ListView<>(); 
     for (int i = 1; i <= 20 ; i++) { 
      String item = "Item "+i ; 
      listView.getItems().add(item); 
     } 

     listView.setCellFactory(CheckBoxListCell.forListView(new Callback<String, ObservableValue<Boolean>>() { 
      @Override 
      public ObservableValue<Boolean> call(String item) { 
       BooleanProperty observable = new SimpleBooleanProperty(); 
       observable.addListener((obs, wasSelected, isNowSelected) -> 
        System.out.println("Check box for "+item+" changed from "+wasSelected+" to "+isNowSelected) 
       ); 
       return observable ; 
      } 
     })); 

     BorderPane root = new BorderPane(listView); 
     Scene scene = new Scene(root, 250, 400); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

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

सूचना है कि इस मामले में, BooleanProperty रों संभावित बनाया है और अक्सर खारिज कर दिया जा रहा है: लेकिन वहाँ कुछ भी नहीं तुम सिर्फ चेक बॉक्स के चयनित राज्य के लिए बाध्य करने के उद्देश्य से कॉलबैक में एक बनाने को रोकने के लिए है। यह शायद अभ्यास में कोई समस्या नहीं है, लेकिन इसका मतलब है कि समर्पित मॉडल वर्ग के साथ पहला संस्करण बेहतर प्रदर्शन कर सकता है।

जावा 8 में, आप कोड को सरल बना सकते हैं। क्योंकि Callback इंटरफ़ेस में केवल एक सार विधि है (इसे कार्यात्मक इंटरफेस) बनाते हैं, तो आप को एक फ़ंक्शन के रूप में सोच सकते हैं जो Item लेता है और ObservableValue<Boolean> उत्पन्न करता है। तो पहले उदाहरण में सेल कारखाना एक lambda expression के साथ लिखा जा सकता है:

listView.setCellFactory(CheckBoxListCell.forListView(item -> item.onProperty())); 

या, और भी अधिक संक्षेप method references का उपयोग कर:

listView.setCellFactory(CheckBoxListCell.forListView(Item::onProperty)); 
+0

वाह, मुझे सच में कहना है कि यह मदद सिर्फ अच्छी नहीं थी, लेकिन अद्भुत! मैं जो कुछ लिखा है उसे समझता हूं और यह वास्तव में किसी भी तरह से मेरी समस्या हल करता है। बहुत बहुत धन्यवाद जेम्स! मैं इसे वोट करने जा रहा हूं, जितना तेज़ मैं कर सकता हूं (जैसा कि मैं नया हूं, मुझे अभी तक 15 प्रतिष्ठा याद आ रही है) – jan

2
listView.setCellFactory(CheckBoxListCell.forListView(new Callback<String, ObservableValue<Boolean>>() { 
     @Override 
     public ObservableValue<Boolean> call(String item) { 
      BooleanProperty observable = new SimpleBooleanProperty(); 
      observable.addListener((obs, wasSelected, isNowSelected) -> 
       System.out.println("Check box for "+item+" changed from "+wasSelected+" to "+isNowSelected) 
      ); 
      return observable ; 
     } 
    })); 

धन्यवाद! यह मेरी समस्या को हल करने में मेरी सहायता करता है।

0

पिछले उत्तरों के लिए धन्यवाद। मुझे सेट करने वाली जानकारी याद आती है CellValueFactory की आवश्यकता नहीं है, लेकिन निर्धारित मूल्य को सेटसेलफैक्टरी में भी किया जाना चाहिए। यहां मेरा दृष्टिकोण है (पिछले समाधान से बहुत अधिक प्रतिलिपि बनाई गई है)।

public TreeTableColumn<RowContainer, Boolean> treetblcolHide; 
... 
    treetblcolHide.setCellFactory(CheckBoxTreeTableCell.<RowContainer, Boolean>forTreeTableColumn(new Callback<Integer, ObservableValue<Boolean>>() { 
     @Override 
     public ObservableValue<Boolean> call(final Integer param) { 
      final RowContainer rowitem = treetblcolHide.getTreeTableView().getTreeItem(param).getValue(); 
      BooleanProperty observable = new SimpleBooleanProperty(); 
      observable.addListener(new ChangeListener<Boolean>() { 
             @Override 
             public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { 
              rowitem.setHideMenuItem(newValue.toString()); 
             } 
            } 
      ); 
      observable.setValue(Boolean.parseBoolean(rowitem.getHideMenuItem())); 
      return observable ; 
     } 
    })); 
संबंधित मुद्दे