2014-04-25 6 views
5

कल्पना को परिभाषित करने के लिए माउस-मोड एक enum होने:बाइंड ToggleGroup दोनों ओर JavaFX में

public enum MouseMode { 
SELECTION, 
EDITING, 
DELETING } 

और एक टॉगल-समूह 3 बटन से बना होने की कल्पना:

ToggleButton selection = new ToggleButton("Select"); 
    ToggleButton editing = new ToggleButton("Edit"); 
    ToggleButton deleting = new ToggleButton("Delete"); 
    ToggleGroup mouseSelection = new ToggleGroup(); 

मैं एक क्षेत्र MouseMode currentMode चाहते होने के लिए टॉगल-समूह से द्विपक्षीय रूप से जुड़ा हुआ है। जब भी एक टॉगल सेट किया जाता है, तो वर्तमान मोड को तदनुसार स्विच किया जाता है, लेकिन अगर कुछ बाहरी प्रक्रिया वर्तमान मोड (शायद एक कुंजी प्रेस) बदलती है तो तौलिए समूह तदनुसार अनुकूल होता है।

2 श्रोताओं के साथ ऐसा कर सकते हैं, लेकिन मुझे आश्चर्य है कि एक कस्टम द्विदिश नक्शा बनाने के लिए एक तरह से वहाँ है यदि।

उत्तर

6

मुझे नहीं लगता कि यह सीधे करने के लिए एक रास्ता है। एक सामान्य प्रयोजन

Bindings.bindBidirectional(Property<S> property1, Property<T> property2, Function<S,T> mapping, Function<T,S> inverseMapping) 

एपीआई के लिए एक अच्छा इसके अतिरिक्त है सकता है, यहां तक ​​कि इस मामले में के रूप में ToggleGroup मदद नहीं होता है selectedProperty केवल (पढ़ने के लिए है चयन संभाला करने की आवश्यकता है के बाद से जब प्रत्येक Toggle ' रों setSelected(...) विधि, शुरू हो जाती है और साथ ही द्वारा ToggleGroup के selectedProperty)।

श्रोताओं की एक जोड़ी का उपयोग करते हुए इस मामले में जाने के लिए रास्ता है।

"कस्टम द्विदिश नक्शा" के निकटतम बात

Bindings.bindBiDirectional(StringProperty stringProperty, ObjectProperty<T> otherProperty, StringConverter<T> converter) 

तरीका है। ऐसे मामले में जहां आपके पास एक (लिखने योग्य) ObjectProperty<S> और (लिखने योग्य) ObjectProperty<T> है, तो आप सिद्धांत में दो बिडरेक्शनल बाइंडिंग और इंटरमीडिएट StringProperty का उपयोग करके उन्हें एक साथ जोड़ सकते हैं। अभ्यास में, यह केवल दो श्रोताओं का उपयोग करने से लगभग हमेशा अधिक कोड है, और यह भी कम कुशल है।

+1

धन्यवाद। हाँ, मैं एक customzied Bindings.bindBidirectional (संपत्ति property1, संपत्ति property2, समारोह मानचित्रण, समारोह inverseMapping) पर काम कर रहा हूँ, कुछ भाग्य के साथ यह ठीक बाहर काम करेंगे। लेकिन आप सही हैं, चयनित प्रॉपर्टी पढ़ी जाती है केवल इसलिए कि इससे मदद नहीं मिलेगी। – CarrKnight

2

मैं सफलतापूर्वक JFXtras परियोजना में ToggleGroupValue वर्ग का इस्तेमाल किया है। यह केवल 2.2 कोडेबेस में है, 8.0 नहीं, लेकिन यह आपके कोडबेस पर कॉपी करना काफी आसान है। https://github.com/JFXtras/jfxtras-labs/blob/2.2/src/main/java/jfxtras/labs/scene/control/ToggleGroupValue.java

यहाँ एक उदाहरण है:

import java.util.Arrays; 
import java.util.List; 
import javafx.application.Application; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 
import javafx.scene.Scene; 
import javafx.scene.control.Label; 
import javafx.scene.control.RadioButton; 
import javafx.scene.layout.GridPane; 
import javafx.stage.Stage; 

public class Main extends Application { 
    Child myChild = new Child(); 
    @Override 
    public void start(Stage stage) throws Exception { 
     stage.setTitle("ToggleGroupValue Example"); 
     GridPane gridPane = new GridPane(); 
     int rowIndex = 0; 
     gridPane.add(new Label("Nickname: "), 0, rowIndex); 

     ToggleGroupValue toggleGroupValue = new ToggleGroupValue(); 
     rowIndex = createAddRadioButtons(gridPane, rowIndex, toggleGroupValue); 

     gridPane.add(new Label("Selected Nickname: "), 0, rowIndex); 
     Label selectedNickNameValueLabel = new Label(); 
     gridPane.add(selectedNickNameValueLabel, 1, rowIndex); 

     myChild.nicknameProperty().bindBidirectional(toggleGroupValue.valueProperty()); 
     selectedNickNameValueLabel.textProperty().bind(toggleGroupValue.valueProperty()); 

     stage.setScene(new Scene(gridPane, 300, 100)); 
     stage.show(); 
    } 

    private int createAddRadioButtons(GridPane gridPane, int rowIndex, ToggleGroupValue toggleGroupValue) { 
     RadioButton radioButtonPunkin = new RadioButton(); 
     radioButtonPunkin.setUserData("Punkin"); 
     RadioButton radioButtonLittleBoy = new RadioButton(); 
     radioButtonLittleBoy.setUserData("Little Boy"); 
     RadioButton radioButtonBuddy = new RadioButton(); 
     radioButtonBuddy.setUserData("Buddy"); 
     List<RadioButton> radioButtons = Arrays.asList(radioButtonPunkin, radioButtonLittleBoy, radioButtonBuddy); 
     for (RadioButton radioButton : radioButtons) { 
      toggleGroupValue.add(radioButton, radioButton.getUserData()); 
      radioButton.setText(radioButton.getUserData().toString()); 
      gridPane.add(radioButton, 1, rowIndex++); 
     } 
     return rowIndex; 
    } 

    private static class Child { 
     private StringProperty nickname = new SimpleStringProperty(); 
     public StringProperty nicknameProperty() { 
      return nickname; 
     } 
     public String getNickname() { 
      return nickname.get(); 
     } 
     public void setNickname(String notesProperty) { 
      this.nickname.set(notesProperty); 
     } 
    } 

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

screenshot of javafx example application

+0

पानी के नीचे tbee? – kleopatra

+0

8.0 का हिस्सा भी बनता है http://jfxtras.org/doc/8.0/jfxtras-controls/jfxtras/scene/control/ToggleGroupValue.html – timdiels

0

मैं जावा सेम संपत्ति अनुकूलक का उपयोग कर रहा है, लेकिन आप सिर्फ इस कोड की अंतिम पंक्ति का उपयोग करें और यह बाध्य कर सकते हैं।

JavaBeanObjectProperty<fooEnum> property = null; 
    try { 
     property = new JavaBeanObjectPropertyBuilder<fooEnum>().bean(fooBean).name(fooField).build(); 
    } catch (NoSuchMethodException e1) { 
     e1.printStackTrace(); 
    } 
    property.addListener((obs, oldValue, newValue) -> { 
     System.out.println("Property value changed from " + oldValue + " to " + newValue); 
    }); 
BindingUtils.bindToggleGroupToProperty(fooToggleGroup, property); 

आपको ToggleGroup के लिए एक छोटी बाध्यकारी उपयोग कक्षा की आवश्यकता है।

public final class BindingUtils { 

private BindingUtils() { 
} 

public static <T> void bindToggleGroupToProperty(final ToggleGroup toggleGroup, final ObjectProperty<T> property) { 
    // Check all toggles for required user data 
    toggleGroup.getToggles().forEach(toggle -> { 
     if (toggle.getUserData() == null) { 
      throw new IllegalArgumentException("The ToggleGroup contains at least one Toggle without user data!"); 
     } 
    }); 
    // Select initial toggle for current property state 
    for (Toggle toggle : toggleGroup.getToggles()) { 
     if (property.getValue() != null && property.getValue().equals(toggle.getUserData())) { 
      toggleGroup.selectToggle(toggle); 
      break; 
     } 
    } 
    // Update property value on toggle selection changes 
    toggleGroup.selectedToggleProperty().addListener((observable, oldValue, newValue) -> { 
     property.setValue((T) newValue.getUserData()); 
    }); 
}