December 13, 2013

Day 8 TableView

အခုတလော အခြားအလုပ်တစ်ခုနဲ့ အလုပ်တွေအရမ်းများနေခဲ့တဲ့အတွက် ပရိုဂရမ်တောင် သိပ်ပြီးမရေး ဖြစ်ပါ။ ပြီးခဲ့တဲ့နေ့က နည်းနည်း အချိန်ရတာနဲ့ Java EE 7 ရဲ့ Injection အကြောင်းကို Java EE 7 General ခေါင်းစဉ်နဲ့ ရေးဖြစ်ခဲ့၏။ ဒီနေ့လည်း အချိန်နည်းနည်း ရလာပြန်သည်။ ဒါနဲ့ ဘာဆက်ရေးရင်ကောင်းမလဲ စဉ်းစားရင်း Java EE ရဲ့ JPA ကို စရင်ကောင်းမလား၊ Database လည်း အခြေခံကို ပြီးပြီဖြစ်တဲ့အတွက် Relational Data Modeling အကြောင်းကို စရင်ကောင်းမလား။ Component Base Software Science အကြောင်းကို ရေးရင်ကောင်းမလား စဉ်းစားနေခဲ့မိပါသည်။ ဒါနဲ့ ပြီးခဲ့တဲ့ ဘလောဂ်တွေပြန်ကြည့်ရင်း အား Java FX ဟာ ရေးစရာ တွေကျန်နေသေးပါလားဟု Java FX အကြောင်းကို ဆက်ရေးရန် ဆုံးဖြတ်ခဲ့ပါသည်။

ယခုဆိုလျှင် Java FX အကြောင်းရေးလာသည်မှာ ၈ ကြိမ်မြောက်ကိုရောက်လာပြီဖြစ်၏။ Control အကြောင်းမှာ အတော်လေးကို ကြာနေခဲ့ပါသည်။ Controls အကြောင်းကို ရေးမည်ဆိုလျှင် အများကြီးရေးရပေမည်။ အစကတည်းက အားလုံးကို ရေးရန် မလွယ်မှန်းသတိထားခဲ့မိ၍ Enterprise App တွေမှာ မရှိမဖြစ်လိုအပ်တဲ့၊ List, Combo နဲ့ Table ကို အသေးစိတ်ရေးပြီး၊ ကျန်တဲ့ Controls တွေကိုတော့ အခြားအခန်းတွေရေးရင်း မိတ်ဆက်သွားမည် ဟုစဉ်းစားထားခဲ့ပါသည်။ ယခုတခေါက်မှာတော့ TableView အကြောင်းကို ဆက်လက်ရေးသားသွားပါဦးမည်။

TableView

ယခင်ရေးသားခဲ့သော Controls များသည် Swing တွင်ရေးသားခဲ့သော Component များနှင့် သိပ်ပြီးကွာခြားလှသည် မဟုတ်ပေ။ သို့ရာတွင် TableView မှာမူ ယနေ့တိုင်းအသုံးပြုခဲ့သည့် JTable နှင့် များစွာကွာခြားလှပေသည်။

အဓိကကွာခြားသည်မှာ Data Model ပင်ဖြစ်၏။ JTable သည် အသုံးပြုမည့် Data များအား javax.swing.table.TableModel အနေဖြင့် အသုံးပြုရန် လိုအပ်ခဲ့၏။ ထို့အတွက် မိမိ၏ Data များအား Wrap လုပ်ရန် လိုအပ်ခဲ့ပေသည်။ သို့ရာတွင် JavaFX ၏ TableView မှာမူ Data Model အား အသုံးမပြုပဲ နှစ်သက်ရာ Object အား အသုံးပြုနိုင်၏။

နမှုနာ အနေဖြင့် Address Book အပလီ တစ်ခု ရေးကြည့်ပါမည်။ အမည်နှင့် လိပ်စာကို Input Form အတွင်း ရေးပြီး သိမ်းပါက ဖိုင်တွင် သွားသိမ်းထားပြီး၊ အပလီအား ပြန်ပြီး Run သည့်အခါ ဖိုင်အတွင်းမှ လိပ်စာ စာရင်းအား ခေါ်၍ Table အတွင်းတွင် ဖော်ပြမည့် အပလီ ဖြစ်ပါသည်။

ဦးစွာ Scene Builder အား အသုံးပြု၍ အသုံးပြုမည့် View အား ရေးသားကြည့်ပါမည်။

ဦးစွာ ခေါင်းစဉ် အဖြစ် Lable တစ်ခုအား နေရာချ၍ Text နေရာတွင် My First Address Book ဟု ရေးသားပါမည်။ ပြီးပါက Input များအား ရေးသားပါသည်။ Input များ အနေဖြင့် Name, Phone နှင့် Address အား ရေးသား ပါသည်။ တဖန် Save Button အား နေရာချပါသည်။ နောက်ဆုံးတွင် TableView တစ်ခုအား နေရာချ၍ အတွင်းတွင် TableColumn သုံးခုအား နေရာချကာ အသီးသီး အမည်များအား ပြောင်းလိုက်ပါသည်။ အားလုံးအား Drug And Drop ဖြင့်သာ ရေးသားသွားပါသည်။

ပြီးပါက Controller အဖြစ်အသုံးပြုရန် AddressBook Class အား Java FX Main Class အဖြစ် ရေးသားပါသည်။

public class AddressBook extends Application implements Initializable {

    @FXML
    private TextField name;
    @FXML
    private TextField phone;
    @FXML
    private TextField address;

    @FXML
    private TableView<Address> table;
    @FXML
    private TableColumn<Address, String> cName;
    @FXML
    private TableColumn<Address, String> cPhone;
    @FXML
    private TableColumn<Address, String> cAddress;

ဦးစွာ View  အတွင်းမှ အသုံးပြုလိုသည့် Component များအား @FXML အား အသုံးပြု၍ Declare လုပ်ပါသည်။ ဤကဲ့သို့ Declare လုပ်ထားရုံဖြင့် Controller အတွင်းမှ အသုံးပြုနိုင်မည် ဖြစ်သည်။ တစ်ခု သတိထားရန် လိုအပ်သည်မှာ JavaFX သည် FXML အား ဖတ်၍ Container မှ Create လုပ်ပေးပါသဖြင့် Constructor အတွင်း တွင် Component များအား Data ဖြည့်ခြင်းများ ပြုလုပ်၍မရပေ။ Initializable Interface အား implements လုပ်၍ initialize method အတွင်းတွင် ရေးသားရပါသည်။ ဤနေရာတွင် TableView တွင် Address Object အား အသုံးပြုနိုင်ရန်အတွက် Generics Type အနေဖြင့် Address အား အသုံးပြုထား၏။ TableColumn တွင်လည်း <Address,String> အား အသုံးပြုထား၏။

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        cName.setCellValueFactory(new PropertyValueFactory<Address, String>(
                "name"));
        cPhone.setCellValueFactory(new PropertyValueFactory<Address, String>(
                "phone"));
        cAddress.setCellValueFactory(new PropertyValueFactory<Address, String>(
                "address"));
        
        fm = new FileManager();
        this.table.getItems().addAll(fm.getAllData());
ပြီးပါက initialize method အတွင်းတွင် TableColumn များ၏ Cell Value Factory အား သတ်မှတ်ပေးရပါသည်။ အသုံးပြုသည့် Class မှာ PropertyValueFactory ဖြစ်ပြီး Generics Type မှာ TableColumn နည်းတူ <Address,String> ဖြစ်ပါသည်။ Constructor Argument အနေဖြင့် String အား ရေးသားရန်လိုပြီး၊ Address Class ၏ အသုံးပြုလိုသည့် Member ၏ အမည်အား ရေးသားရပါသည်။ ဤနည်းအားဖြင့် Address Class ၏ Member က Column အတွင်းတွင် ဖော်ပြနိုင်မည် ဖြစ်ပါသည်။

နောက်ဆုံးတွင် TableView#getItems ဖြင့် Data Model အား ခေါ်ယူကာ ၎င်းအတွင်းတွင် FileManager#getAllData ဖြင့် ရယူထားသော Address List အား ထည့်ပေးနေပါသည်။ ဤနည်းအားဖြင့် TableView အတွင်း Address ၏ အချက်အလက်များအားဖော်ပြပေးနိုင်မည် ဖြစ်သည်။


Swing အား အသုံးပြုပါက တကူးတက DataModel အဖြစ်ပြောင်းရန် လိုအပ်ခဲ့သော်လည်း JavaFX မှာမူ Object များအား ထိုအတိုင်း အသုံးပြုနိုင်သောကြောင့် အလွန်အစဉ်ပြေပါသည်။ ထို့အပြင် View Component များအားလည်း FXML ဖြင့် ရေးသားနိုင်သောကြောင့် View အတွက် ရေးသားရသော Code များ အလွန်နည်းပါးသွားပါသည်။


Table အတွင်းသို့ Data ဖြည့်စွက်ခြင်း


TableView ပေါ်မှာ Data ကို ဖော်ပြီးတဲ့အခါမှာ Input တွေကနေ ဖြည့်ထားတဲ့ အချက်အလက်တွေကို File ထဲမှာ သိမ်းပြီး၊ TableView ထဲကို ပြန်ဖြည့်တဲ့ အပိုင်းကို ရေးပါမယ်။ Button ကို နှိပ်တဲ့အခါမှာ အလုပ်လုပ်မယ့် save method  ကို အသစ်ရေးသားပါတယ်။ ပြီးတော့ Save Button ရဲ့ On Action မှာ save လို့ ရေးပြီး Save လုပ်ပါတယ်။

အဲ့ဒီလိုရေးလိုက်တာနဲ့ Save Button ကို နှိပ်တဲ့အခါမှာ save method ကို ခေါ်မှာဖြစ်ပါတယ်။


ပြီးတဲ့ အခါ Controller Class ထဲမှာ save method ကို အောက်ပါတတိုင်း ဆက်ရေးပါတယ်။

    public void save() {
        // get data from inputs
        Address a = new Address(this.name.getText(), this.phone.getText(),
                this.address.getText());

        // add to table
        this.table.getItems().add(a);

        // save to file
        fm.AddData(a);

        // clear inputs
        this.name.clear();
        this.phone.clear();
        this.address.clear();
    }

ဦးစွာ Input တွေထဲက ဒေတာတွေကို ယူပြီး Address အဖြစ်ပြောင်းပါတယ်။ ထို့နောက် TableView#getItems#add ကို သုံးပြီး Address Object ကို TableView ထဲကို ဖြည့်စွက်ပါတယ်။ ပြီးတော့ အဲ့ဒီ Address object ကိုပဲ FileManager#addData ကို သုံးပြီး file မှာသွား save ပါတယ်။ နောက်ဆုံးမှာတော့ Input တွေထဲက Data တွေကို clear လုပ်ပစ်ပါတယ်။ FileManager Class ကတော့ JavaFX နဲ့ မဆိုင်တဲ့အတွက် ဒီနေရာမှာ မရှင်းတော့ပါဘူး။



TableView မှ ရွေးထားတဲ့ Record ကို ရယူခြင်း

TableView အတွင်းမှ Data များကို ရွေးပြီး၊ ပြင်လိုတဲ့အခါ ပြီးတော့ ပြန်ပြီး ဖျက်လိုတဲ့အခါမှာ TableView#getSelectionModel ကို အသုံးပြုနိုင်ပါတယ်။ ပြီးတော့ TableView မှာ Right Click ထောက်ပြီး Menu ကို ပေါ်အောင် ContextMenu ကို အသုံးပြုနိုင်ပါတယ်။

    // delete menu
        MenuItem delete = new MenuItem("Delete");
        delete.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent arg0) {
                Address selectedAddress = table.getSelectionModel()
                        .getSelectedItem();
                fm.delete(selectedAddress);
                table.getItems().clear();
                table.getItems().addAll(fm.getAllData());
            }
        });
ဦးစွာ Delete အမည်နဲ့ MenuItem ကို Create လုပ်ပါတယ်။ ပြီးတဲ့အခါမှာ အဲ့ဒီ Object မှာ EventHandler ကို Action Handler အနေနဲ့ သတ်မှတ်ပါတယ်။ ဒီမှာတော့ Anonymous Class အနေနဲ့ပဲ ရေးပြီး handle ထဲမှာတော့ လိုအပ်တဲ့ လော့ဂျစ်တွေကို ရေးသားပါတယ်။

TableView ထဲက ရွေးထားတဲ့ Object ကို ရယူလိုတဲ့ အခါမှာ TableView#getSelectionModel#getSelectedItem ကို အသုံးပြုနိုင်ပါတယ်။ ရွေးထားတဲ့ Address Object ကို FileManager#delete ကို သုံးပြီး File ထဲကနေ ဖျက်ထုတ်ပစ်ပါတယ်။ ပြီးတော့မှ TableView ထဲကနေ အားလုံးကို ဖျက်ထုတ်ပြီးမှ၊ FileManager#getAllData ကိုသုံးပြီး၊ ရလာတဲ့ Address တွေအားလုံးကို TableView ထဲကို ထည့်ပါတယ်။ တကယ်ဆိုရင်တော့ TableView#getItems#remove ကို သုံးမယ်ဆိုလဲ ရပါတယ်။ File နဲ့ View ကို Data အတူတူထားချင်တဲ့ အတွက် TableView ထဲက Data တွေကို Clear လုပ်ပြီး၊ File ထဲက ရလာတဲ့ Data တွေနဲ့ View ကို ပြန်ပြီးဖော်ပြစေတာဖြစ်ပါတယ်။


နောက်ဆုံး အလားတူ Edit MenuItem ကို ရေးသားပြီး၊ ContextMenu မှာ Add လုပ်ပါတယ်။ နောက်ဆုံးမှာတော့ TableView ရဲ့ Context Menu အနေနဲ့ သွားပြီး Set လုပ်ရုံပါပဲ။

    ContextMenu cm = new ContextMenu();
    cm.getItems().addAll(edit, delete);

    this.table.setContextMenu(cm);


ကျွှန်တော်တို့ TableView နဲ့ သိပ်ပြီး မဆိုင်တဲ့ အတွက် ဒီနေရာမှာတော့ Edit အကြောင်းကို မရေးတော့ပါဘူး။ နောက် Dialog အကြောင်းကို ရေးသားတော့မှပဲ Edit ကို ဆက်ပြီးရေသားပါတော့မယ်။

Source Code တွေ အားလုံးကိုတော့ Git Hub မှာ လေ့လာနိုင်ပါတယ်။

Address.java
AddressBook.java
AddressEditor.java
FileManager.java
AddressBook.fxml
AddressEditor.fxml

အခုတစ်ခေါက် အလုပ်များနေတာနဲ့ ဘလောဂ်မရေးဖြစ်ဘူးဖြစ်နေပါတယ်။ ဆက်ပါဦးမည်။

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

No comments:

Post a Comment