December 14, 2013

Day 9 JavaFX ၏ Property Class

ပြီးခဲ့သော အခန်းများအထိ Java FX နဲ့ပတ်သက်ပြီး View Component တွေရဲ့ အသုံးပြုပုံကို အဓိကထားဖော်ပြခဲ့၏။ View နှင့်ပတ်သက်ပြီး ဖော်ပြရန် အတော်ကျန်နေသေးသော်လည်း ယခုတစ်ခေါက်တွင် View ကနေ ခဏခွဲခွာပြီး Function ပိုင်းဆိုင်ရာ ဘက်ကို ခေတ္တရေးသားပါဦးမည်။

GUI အပလီကေးရှင်းများတွင် MVC Pattern အား အသုံးပြု၍ ရေးသားရာတွင် View တွင် ဖော်ပြမည့် အချက်အလက်များအား Model တွင် သိမ်းဆည်းထားလေ့ရှိ၏။ လက်တွေ့ ရေးကြည့်ရာတွင် Model အား View တွင် ဖော်ပြရသည်မှာ လွယ်သည့်ကိစ္စတစ်ခု တော့မဟုတ်ပါ။

ဤနေရာတွင် အသုံးဝင်သည်မှာ ယခုတစ်ခေါက် ဖော်ပြမည့် Java FX ၏ Binding Function ပင် ဖြစ်၏။

Binding သည် Variable နှစ်ခုအား Synchronize လုပ်ပေးနိုင်သည့် Function တစ်ခု ဖြစ်ပါသည်။ Variable တစ်ခုအား အခြားသော Variable နှင့် Bind လုပ်ထားပါက၊ Variable တစ်ခု၏ တန်ဖိုး ပြောင်းလည်းသွားသည်နှင့် အလိုအလျှောက် အခြားသော Variable ၏ တန်ဖိုးသည်လည်း ပြောင်းလည်းသွားမည် ဖြစ်ပါသည်။ သို့ရာတွင် Binding အား Variable အားလုံးတွင် အသုံးပြုနိုင်သည် မဟုတ်ပါ။ Binding အား အသုံးပြုနိုင်သော Variable များမှာ ယခုတစ်ခေါက် ဖော်ပြမည့် Property Variable များပင် ဖြစ်ကြ၏။

Property


Java ဘာသာရပ်တွင် Property များအား ဖော်ပြရန် Java Beans အား အသုံးပြုလာခဲ့ကြ၏။ အလားတူပင် JavaFX ၏ Property သည်လည်း Java Beans Technology အား အခြေခံထားပါသည်။ Jaba Beans အား အသုံးပြုပါက လိုအပ်သလို Java Beans အား ကိုယ်တိုင်ရေးသား ရပါသည်။ Java FX တွင်လည်း JavaFX မှ ပံ့ပိုးပေးထားသော Property Class အား အသုံးပြုနိုင်ပါသည်။

Property Class များအား javafx.bean.property Package အောက်တွင် ထားရှိပါသည်။ ဥပမာအားဖြင့် IntegerProperty ကဲ့သို့သော Primitive Data များအတွက် Property Class များလည်းရှိသကဲ့သို့၊ StringProperty ကဲ့သို့ String အား အသုံးပြုနိုင်သော Class နှင့် နှစ်သက်ရာ Object များကို အသုံးပြုနိုင်သော ObjectProperty Class များလည်း ရှိကြပါသည်။  အဆိုပါ Class များတွင် getter နှင့် setter method များကို ပိုင်ဆိုင်ပြီး၊ တန်ဖိုးများအား get နှင့် set လုပ်ဆောင်နိုင်ပါသည်။ သို့ရာတွင် ထို Class များသည် Abstract Class များဖြစ်ကြသောကြောင့် Instance များအား တိုက်ရိုက် ပြုလုပ်နိုင်ခြင်းမရှိပါ။ အသုံးပြုလိုပါက SimpleIntegerProperty နှင့် SimpleStringProperty ကဲ့သို့သော Sub Class များမှတဆင့် အသုံးပြုနိုင်ပါသည်။

လက်တွေ့ ရေးသားကြည့်ပါမည်။

    public static void main(String[] args) {
        // Integer Property
        IntegerProperty variable = new SimpleIntegerProperty(10);
        System.out.println(variable.get());
        
        // change property value
        variable.set(20);
        System.out.println(variable.get());
    }

အဘယ်ကြောင့် ရိုးရိုး Variable အား အသုံးမပြုပဲ Property Variable များအား အသုံးပြုနေပါသနည်း။ အကြောင်းရှိပါသည်။  ပထမ အဖြေမှာ ပြောင်းလည်းမှု့အား သိရှိစေနိုင်ခြင်း ဖြစ်ပြီး၊ နောက်အဖြေတစ်ခုမှာ Binding ဖြစ်၏။

GUI အပလီကေးရှင်းများတွင် ပြောင်းလည်းမှု့များအား သိရှိခြင်းသည် လွန်စွာမှ အရေးကြီးလှပါသည်။ Model ၏ တန်ဖိုးပြောင်းလည်းသွားပါက View တွင် ချက်ချင်းဖော်ပြရန် လိုအပ်သလို၊ အသုံးပြုသူ၏ လုပ်ဆောင်မှု့ကြောင့် View ၏ Input တန်ဖိုး ပြောင်းလည်းသွားပါက Model အား ချက်ချင်း ပြောင်လည်း ပေးရန် လိုအပ်ပါသည်။ ဤကဲ့သို့ ပြောင်းလည်းမှု့အား သိရှိစေရန်အတွက် Property အား အသုံးပြုရပါသည်။ Property ၏ တန်ဖိုးပြောင်းလည်းသွားပါက Property Object သည် Event အား ဖြစ်ပေါ်စေပြီး၊ ထို Event အား လုပ်ဆောင်စေနိုင်သည်မှာ ChangeListener Object များပင် ဖြစ်၏။

    public static void main(String[] args) {
        // Integer Property
        IntegerProperty variable = new SimpleIntegerProperty(10);
        
        variable.addListener(new ChangeListener<Number>() {

            @Override
            public void changed(ObservableValue<? extends Number> oveservable,
                    Number oldValue, Number newValue) {
                System.out.println("Ovservable Value : " + oveservable.getValue());
                System.out.println("Old Value        : " + oldValue);
                System.out.println("New Value        : " + newValue);
            }

        });
        
        // change property value
        variable.set(20);
        variable.set(30);
    }
ChangeListener Object အား Property တွင် အသုံးပြုလိုပါက addListener method အား အသုံးပြုရပါသည်။ အကြောင်းတစ်မျိုးမျိုးကြောင့် Property ၏ တန်ဖိုးတွင် ပြောင်းလည်းမှု့ကို ဖြစ်ပေါ်စေပါက အသုံးပြုနေသော ChangeListener ၏ changed method ကို ခေါ်ယူမည် ဖြစ်သည်။

changed method တွင် Argument ၃ ခုပါဝင်ပြီး၊ ဒုတိယ Argument မှာ မပြောင်းလည်းခင်တန်ဖိုး ဖြစ်ပြီး၊ တတိယ Argument မှာ ပြောင်းလည်းပြီး တန်ဖိုး ဖြစ်ပါသည်။ ပထမဦးဆုံး Argument မှာ ObservableValue Interface ဖြစ်ပြီး၊ အသုံးပြုနေသော Property Object ကိုယ်တိုင်ပင် ဖြစ်၏။ Property များသည် ObservableValue Interface အား Inplements လုပ်ထားသောကြောင့် ဤကဲ့သို့ အသုံးပြုနိုင်ခြင်း ဖြစ်ပါသည်။

တဖန် Property တန်ဖိုးများအား အသုံးပြု၍ View Component များအား ရေးသားကြည့်ပါဦးမည်။

package com.dtc.jfx.property;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.stage.Stage;

public class Main extends Application implements Initializable {

    @FXML
    private Slider slider;
    @FXML
    private Label label;

    @Override
    public void start(Stage primaryStage) throws IOException {
        primaryStage.setScene(new Scene((Parent) FXMLLoader.load(getClass()
                .getResource("Main.fxml"))));
        
        primaryStage.setTitle("Property Test");
        
        primaryStage.show();
    }

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        slider.valueProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> arg0,
                    Number arg1, Number arg2) {
                label.setText(String.valueOf(arg2));
            }
        });
    }

    public static void main(String[] args) {
        launch(args);
    }
}
လိုင်း နံပါတ် ၃၈ အားကြည့်ပါ။ Slider Object ၏ propertyValue အား ခေါ်ယူ၍ DoubleProperty Object အား ရယူပါသည်။ ထို့နောက် addListener method အား အသုံးပြု၍ ChangeListener အား ဖြည့်စွက်ပါသည်။ တဖန် ChangeListener ၏ changed method အတွင်းမှာမူ Lable Objecct ၏ တန်ဖိုးအား ပြောင်းလည်းသွားသည့် တန်ဖိုးဖြင့် ဖော်ပြစေနေပါသည်။

အဆိုပါ ပရိုဂရမ်အား အလုပ်လုပ်ခိုင်းကြည့်သည့် အခါ အောက်ပါအတိုင်း Slider အား ပြောင်းရွှေ့လိုက်သည့်အခါတိုင်း Lable ၏ တန်ဖိုးလည်း လိုက်၍ ပြောင်းသည်ကို တွေ့ရမည် ဖြစ်ပါသည်။




ကိုယ်ပိုင် Property Class များအား ရေးသားချင်း

အထက်တွင် ဖော်ပြသကဲ့သို့ပင် JavaFX မှ ပံ့ပိုးထားသော Property များအား အသုံးပြုနိုင်သကဲ့သို့ပင် ကိုယ်ပိုင် Custom Property Class များအား ရေးသားအသုံးပြုနိုင်ပါသည်။ ဤကဲ့သို့ ရေးသားရာတွင် လိုက်နာရန် စီးကမ်းများ ရှိကြပါသည်။

  • Member Filed များအား Property များကို သာအသုံးပြုနိုင်ပါသည်
  • getter နှင့် setter များမှာလည်း Java Beans Technology ၏ Naming Rule အား လိုက်နာရန် လိုအပ်ပြီး၊ Property ၏ တန်ဖိုးများအား Get Set လုပ်နိုင်မည် ဖြစ်သည်
  • Property Member များအား ရယူလိုသည့်အခါ variableProperty ဟု အမည်ပေးရန် လိုအပ်ပါသည်
package propertydemo;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;

class Bill {
    // Define a variable to store the property
    private DoubleProperty amountDue 
        = new SimpleDoubleProperty();
    
    // Define a getter for the property's value
    public final double getAmountDue(){
        return amountDue.get();
    }
    
    // Define a setter for the property's value
    public final void setAmountDue(double value){
        amountDue.set(value);
    }
    
    // Define a getter for the property itself
    public DoubleProperty amountDueProperty() {
        return amountDue;
    }
}

အထက်ပါအတိုင်း မိမိ၏ ကိုယ်ပိုင် Property Object များအား ရေးသားနိုင်ပါသည်။ JavaFX ၏ Standard API များတွင်လည်း အထက်ပါစီးမျဉ်းအား လိုက်နာ၍ ရေးသားထားပါသည်။


Property အား အသုံးပြုနိုင်သော Collection

JavaFX တွင် အသုံးပြုသော Collection များသည်လည်း Property များကဲ့သို့ပင် ပြောင်းလည်းမှု့အား သိရှိနိုင်ပါသည်။ JavaFX တွင် အသုံးပြုနိုင်သော Collection များမှာ ObservableList, ObservableMap နှင့် ObservableSet တို့ ဖြစ်ကြ၏။ အသုံးပြုပုံတို့မှာ အခြေခံအားဖြင့် သာမန် Collection များနှင့် အတူတူပင် ဖြစ်၏။ ထူးခြားသည်မှာ ၎င်းတို့အတွက် Implements လုပ်ထားသော Class များ ပံ့ပိုးထားခြင်းမရှိဆိုသည့် အချက်ပင် ဖြစ်၏။ ထို့ကြောင့် သာမန် Collection များကဲ့သို့ new လုပ်၍ မရခြင်း ပင်ဖြစ်၏။

JavaFX ၏ Collection များအား ရယူလိုပါက Utility Class ဖြစ်သော FXCollections Class မှ တဆင့် အသုံးပြုရမည် ဖြစ်ပါသည်။ ၎င်း၏ observableList, observableArrayList, observableMap နှင့် observableSet တို့အား အသုံးပြု၍ JavaFX Collection Object များအား ရယူနိုင်မည် ဖြစ်ပါသည်။

Collection များ၏ Element တန်ဖိုးများပြောင်းလည်းခြင်းအား Property များကဲ့သို့ပင် သိရှိနိုင်မည် ဖြစ်ပါသည်။ ပြောင်းလည်းခြင်း Event များအား အလုပ်လုပ်စေရန် ChangeListener များအား သတ်မှတ် အသုံးပြုနိုင်ပါသည်။ Observable Collection များတွင် အသုံးပြုနိုင်သော Change Listener များမှာ ListChangeListener, MapChangeListener နှင့် SetChangeListener တို့ ပင် ဖြစ်ကြ၏။

package com.dtc.jfx.property;

import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;

public class CollectionTest {

    public static void main(String[] args) {
        ObservableList<Integer> list = FXCollections.observableArrayList(1,2,3);
        list.addListener(new ListChangeListener<Number>() {

            @Override
            public void onChanged(
                    javafx.collections.ListChangeListener.Change<? extends Number> change) {
                while(change.next()) {
                    if(change.wasAdded()) {
                        System.out.println("Add : " + change.getAddedSubList());
                    }
                    
                    if(change.wasRemoved()) {
                        System.out.println("Removed : " + change.getRemoved());
                    }
                }
            }
        });
        
        // single value
        list.add(4);
        list.remove(0);
        
        // multiple value
        list.addAll(5,6,7);
        list.removeAll(2,3);
        
    }
}
အထက်ပါ Source Code ထဲတွင် ObservableList အား FXCollections#observableArrayList အား အသုံးပြု၍ ရယူပါသည်။ တဖန် ChangeListener အဖြစ် ListChangeListener အား အသုံးပြုပါသည်။ Collection ၏ Element များ အပြောင်းအလည်းရှိပါက onChange method အား ခေါ်ယူမည် ဖြစ်သည့်အတွက် လုပ်ဆောင်ချက်များကို ထို Method ထဲတွင် ရေးသားရပါမည်။

onChange method ၏ Argument သည် ListChangeListener.Change Class ဖြစ်ပြီး၊ ၎င်းတွင် ပြောင်းလည်းမှု့အား သိရှိစေနိုင်သော wasAdded, wasRemoved, wasReplased, wasUpdated နှင့် wasPermuted လုပ်ဆောင်ချက်များအား ပြင်ဆင်ထားပါသည်။ တဖန် ပြောင်းလည်းမှု့တန်ဖိုးများအား ရယူနိုင်ရန် အတွက် getAddedSubList နှင့် getRemoved အစရှိသည့် Method များအား ပြင်ဆင်ထားပါသည်။

အထက်ပါ Program အား Run ကြည့်သောအခါ အောက်ပါအတိုင်း အဖြေရမည် ဖြစ်ပါသည်။
Add : [4]
Removed : [1]
Add : [5, 6, 7]
Removed : [2, 3]
ယခု အခေါက်တွင် JavaFX ၏ အဓိက ဖန်ရှင်တစ်ခု ဖြစ်သော Property အကြောင်းကို ရေးသားဖော်ပြခဲ့၏။ Java ဘာသာရပ်အတွက် အလွန်အသုံးဝင်သော Function တစ်မျိုး ဖြစ်ပါသည်။ Property ၏ အရည်အသွေး အပြည့်အဝ အသုံးပြုရန်မှာ နောက်တစ်ကြိမ်ဖော်ပြရန် ရည်ရွယ်ထားသော Binding တွင် ဖြစ်ပါသည်။ ကျွှန်တော်ကိုယ်တိုင်လည်း Property အား လေ့လာရင်း ဤ Function သည် လွန်စွာမှ အသုံးဝင်သော ဖန်ရှင်တစ်ခု ဖြစ်သည်ဟု သဘောပေါက်မိပါသည်။ ဆက်ပါဦးမည်။

လေးစားစွာဖြင့်
မင်းလွင်

No comments:

Post a Comment