September 1, 2013

Day 7 ComboBox Control

ပြီးခဲ့သော ဘလောဂ်ဖြင့် JavaFX တွင် အသုံးပြုနိုင်သော ListView အကြောင်းကို ဖော်ပြခဲ့၏။ ယခုတစ်ခေါက်တွင်လည်း ဆက်လက်၍ ComboBox အကြောင်းကို ဖော်ပြပါဦးမည်။ JavaFX တွင် ComboBox အဖြစ်အသုံးပြုနိုင်သည်မှာ javafx.scene.control.ComboBox ဖြစ်ပါသည်။ ComboBox သည် အခြေခံအားဖြင့် ListView နှင့် အသုံးပြုပုံမှာ ဆင်တူပါသည်။

ListView နည်းတူ ObservableList ၏ Object အား Data အနေဖြင့် အသုံးပြုသလို၊ Item တစ်ခုချင်းအား ဖော်ပြရာတွင်လည်း ListCell ၏ Object အား အသုံးပြုပါသည်။ ထို့အပြင် ComboBox တွင် တစ်ခုတည်းသာ ရွေးချယ်နိုင်သောကြောင့် ListView နှင့် နှိုင်းယှဉ်လျှင် သုံးရလွယ်ကူပါသည်။

ComboBox အား ရေးသားခြင်း

ComboBox အား ရေးသားရာတွင် အခြားသော JavaFX Component များအား ရေးသားသကဲ့သို့ပင် Java Language ဖြင့် ရေးသားနိုင်သလို၊ FXML တွင် ရေးသား၍သော်၎င်း၊ SceneBuilder အား အသုံးပြု၍ FXML အား ပြုပြင်၍သော်၎င်း ရေးသားနိုင်ပါသည်။
  ComboBox<String> stringCombo = new ComboBox<>();
  stringCombo.getItems().addAll("Yangon", "Mandalay", "Pagoo");
  stringCombo.setPrefWidth(120);
  stringCombo.getSelectionModel().selectFirst();
  
  ComboBox<Data> enumCombo = new ComboBox<>();
  enumCombo.getItems().addAll(Data.values());
  enumCombo.setPrefWidth(120);
  enumCombo.getSelectionModel().selectLast();;
  
  ComboBox<Integer> intCombo = new ComboBox<>();
  intCombo.getItems().addAll(3,4,5,6,7);
  intCombo.setPrefWidth(120);
  intCombo.getSelectionModel().select(3);
Swing တွင် ရေးသားသကဲ့သို့ပင် ComboBox အား new လုပ်၍ ရေးသားနိုင်ပါသည်။ တဖန်၎င်း၏ member များအားလည်း getter/setter များအား အသုံးပြု၍ ဆက်သွယ်နိုင်ပါသည်။

ComboBox#getItens အား အသုံးပြုခြင်းအားဖြင့် အသုံးပြုနေသော ObservableList အား ရရှိနိုင်မည် ဖြစ်ပြီး၊ ObservabeList#add အား အသုံးပြု၍ Element တစ်ခုချင်းသော်၎င်း၊  ObservabeList#addAll အား အသုံးပြု၍ Collection ကိုသော်၎င်း ဖြည့်စွက်နိုင်ပါသည်။

SceneBuilder အား  အသုံးပြုမည် ဆိုပါက Items အနေဖြင့် အလိုအလျှောက် Create လုပ်ပေးသော Sample Data များပါဝင်နေတတ်ပါသည်။ အကဲ၍ မိမိ အသုံးပြုနေသော Data Type နှင့် မတူပါက Error ဖြစ်တတ်ပါသည်။ ထိုအခါမျိုးတွင် FXML ဖိုင်အား ဖွင့်၍ ComboBox အတွင်းရှိ Item များအား ဖျက်ပေးရန် လိုအပ်ပါသည်။


Custom Object များအား အသုံးပြုနိုင်သော Combobox

ComboBox များတွင် Custom Object များအားလည်း Data အနေဖြင့် အသုံးပြုနိုင်ပါသည်။ အောက်ပါ Class မှာ Custom Object အနေဖြင့် အသုံးပြုမည့် Class ဖြစ်ပါသည်။
public class Site {
    
        private String name;
        private String url;
        
        public Site(String name, String url) {
            this.name = name;
            this.url = url;
        }

        public String getName() {
            return name;
        }

        public String getUrl() {
            return url;
        }
}
၎င်းအား အသုံးပြုပုံမှာ အောက်ပါအတိုင်း ဖြစ်ပါသည်။ ယခင် ရေးသားခဲ့သည်နှင့် သိပ်ပြီး မကွာလှပေ။
        ComboBox<Site> combo = new ComboBox<>();
        combo.getItems().add(new Site("Facebook", "http://www.facebook.com/"));
        combo.getItems().add(new Site("Youtube", "http://www.youtube.com/"));
        combo.getItems().add(new Site("Twitter", "https://twitter.com/"));
        combo.getItems().add(new Site("My Space", "https://myspace.com/"));
ဤသို့ရေးသားရာတွင် ComboBox ၏ Item များအား ဖော်ပြရာတွင်၎င်း၊ Combo Button တွင် ရွေးချယ်ထားသော Button ၏ စာသားကို ဖော်ပြရာတွင်၎င်း Default အတိုင်း ခေါ်ပါလိမ့်မည်။ Default အတွင်းတွင် Item Object ၏ toString ကို ခေါ်ယူပါလိမ့်မည်။ ထို့ကြောင့် ဖော်ပြလိုသော စာသားကို ဖော်ပြနိုင်ခြင်း မရှိပဲ အောက်ပါအတိုင်း ဖြစ်နေပါလိမ့်မည်။


ထို့ကြောင့် မှန်ကန်စွာဖော်ပြနိုင်ရန် Object ၏ toString အား Override လုပ်၍သော်၎င်း၊ Cell Factory နှင့် Button Cell များအား သတ်မှတ်ပေး၍သော်၎င်း ရေးသားနိုင်ပါသည်။ ရေးသားကြည့်ပါမည်။
        combo.setCellFactory(new Callback<ListView<Site>, ListCell<Site>>() {
            @Override
            public ListCell<Site> call(ListView<Site> arg0) {
                return new ListCell<Site>() {
                    @Override
                    protected void updateItem(Site item, boolean upd) {
                        super.updateItem(item, upd);
                        if(null != item)
                            setText(item.getName());
                    }
                };
            }
        });
ပြီးခဲ့သောတစ်ခေါက် ListView တွင်ရေးသားသကဲ့သို့ပင် setCellFactory တွင် CallBack ၏ Anonymous Class အား Parameter အဖြစ် set လုပ်ပေးနေခြင်း သာဖြစ်သည်။ Override လုပ်ထားသော call method အတွင်းမှာမူ ListCell ၏ Anonymous Class အား Object အဖြစ်ပြောင်း၍ ပြန်ပို့ပေးနေပါသည်။ ၎င်းအတွင်းတွင် updateItem method အား Override လုပ်ထားပြီး၊ List Cell တွင်ဖော်ပြလိုသည်ကို ဤနေရာတွင် setText လုပ်နေခြင်းသာ ဖြစ်ပါသည်။




List View တွင် ဖော်ပြလိုသည်ကို ဖော်ပြနိုင်သော်လည်း၊ ရွေးချယ်လိုက်သော Item အား Combo Button တွင်ဖော်ပြရာ၌ ပြဿနာ ဖြစ်နေပါသေးသည်။ ထို့အတွက် ComboBox#setButtonCell အား ရေးသားပေးရန် လိုအပ်ပါသည်။ Parameter အဖြစ် အထက်တွင်အသုံးပြုခဲ့သော ListCell အား ပြန်လည်အသုံးပြုပါသည်။
        combo.setButtonCell(new ListCell<Site>() {
            @Override
            protected void updateItem(Site item, boolean upd) {
                super.updateItem(item, upd);
                if(null != item)
                    setText(item.getName());
            }
        });



ComboBox ၏ ပြောင်းလည်းမှု့ Action အား Trigger အဖြစ်အသုံးချခြင်း


ကျွှန်တော်တို့ အထက်တွင် ရေးသားထားသော ComboBox ၏ Item များအား ပြောင်းလည်း ရွေးချယ်ပါက၊ Web Browser ပေါ်တွင် ပြောင်းလည်းပေးနိုင်သည်ကို စမ်းကြည့်ပါမည်။ ဤကဲ့သို့ရေးသားရာတွင် ComboBox ၏ SelectionModel မှတဆင့် SelectedItemProperty အား ခေါ်ယူကာ ၎င်းအတွင်းတွင် ChangeListener အား Listener အဖြစ် သတ်မှတ်ပေးရပါသည်။ ရေးသားနေသည်မှာ အောက်ပါအတိုင်း ဖြစ်ပါသည်။
        combo.getSelectionModel()
            .selectedItemProperty().addListener(new ChangeListener<Site>() {
            @Override
            public void changed(ObservableValue<? extends Site> obj,
                    Site oldObj, Site newObj) {
                web.getEngine().load(newObj.getUrl());
            }
        });

ရေးသားထားသော Source များအား GitHub မှ ဒေါင်းလုဒ်လုပ်ယူနိုင်ပါသည်။
https://github.com/minlwin/mmju/tree/master/javafx-day7

ဆက်ပါဦးမည်။ လေးစားစွာဖြင့်
မင်းလွင်

No comments:

Post a Comment