Java 导叶下拉列表

Java 导叶下拉列表,java,drop-down-menu,wicket,Java,Drop Down Menu,Wicket,在我的页面顶部,我想要一个下拉列表来更改首选语言。如果页面发生变化,将重新加载页面并使用选定的语言呈现。 但在我的解决方案中,该语言不会立即加载 @SuppressWarnings("serial") public class CurrentLanguageDropdown extends LanguageDropDown { private String sessionlanguage; private IModel<String> model; public CurrentL

在我的页面顶部,我想要一个下拉列表来更改首选语言。如果页面发生变化,将重新加载页面并使用选定的语言呈现。 但在我的解决方案中,该语言不会立即加载

@SuppressWarnings("serial")
public class CurrentLanguageDropdown extends LanguageDropDown {

private String sessionlanguage;
private IModel<String> model;

public CurrentLanguageDropdown(String id, Locale locale) {
    super(id, locale);
    this.sessionlanguage = locale.getCountry();
    GlobalAccountSession session = GlobalAccountSession.get();
    model = new SelectedLocaleModel("sessionlanguage", this, new     Model<Serializable>(session.getLocale()),
            locale.getCountry());
    setModel(model);
}

@Override
public void onSelectionChanged(String newSelection) {
    GlobalAccountSession session = GlobalAccountSession.get();
    model = new SelectedLocaleModel("sessionlanguage", this, new Model<Serializable>(session.getLocale()),
            newSelection);
}

@Override
protected boolean wantOnSelectionChangedNotifications() {
    return true;
}

String getSessionlanguage() {
    return sessionlanguage;
}

private class SelectedLocaleModel extends StringResourceModel {

    private String selectedValue = "";
    private Component parent;

    public SelectedLocaleModel(String resourceKey, Component parent, IModel<?> model, String selectedValue) {
        super(resourceKey, parent, model);
        this.selectedValue = selectedValue;
        this.parent = parent;
    }

    @Override
    public void setObject(java.lang.String object) {
        GlobalAccountSession session = GlobalAccountSession.get();
        Locale locale = new Locale(object.toString());
        session.setLocale(locale);
        selectedValue = locale.getLanguage();
    }

    @Override
    public String getObject() {
        GlobalAccountSession session = GlobalAccountSession.get();
        selectedValue = session.getLocale().getLanguage();
        return selectedValue;
    }
}
}
@SuppressWarnings(“串行”)
公共类CurrentLanguageDropdown扩展了LanguageDropDown{
私有字符串会话语言;
私有IModel模型;
public CurrentLanguage下拉列表(字符串id、区域设置){
super(id,locale);
this.sessionlanguage=locale.getCountry();
GlobalAccountSession=GlobalAccountSession.get();
model=newselectedlocalemodel(“sessionlanguage”,这个,新模型(session.getLocale()),
locale.getCountry());
setModel(model);
}
@凌驾
更改了选择时的公共无效(字符串newSelection){
GlobalAccountSession=GlobalAccountSession.get();
model=newselectedlocalemodel(“sessionlanguage”,这个,新模型(session.getLocale()),
新闻选举);
}
@凌驾
受保护的布尔wantOnSelectionChangedNotifications(){
返回true;
}
字符串getSessionlanguage(){
返回会话语言;
}
私有类SelectedLocaleModel扩展了StringResourceModel{
私有字符串selectedValue=“”;
私有组件父级;
public SelectedLocaleModel(字符串resourceKey、组件父级、IModel模型、字符串selectedValue){
超级(resourceKey、父级、模型);
this.selectedValue=selectedValue;
this.parent=parent;
}
@凌驾
public void setObject(java.lang.String对象){
GlobalAccountSession=GlobalAccountSession.get();
语言环境=新语言环境(object.toString());
session.setLocale(locale);
selectedValue=locale.getLanguage();
}
@凌驾
公共字符串getObject(){
GlobalAccountSession=GlobalAccountSession.get();
selectedValue=session.getLocale().getLanguage();
返回selectedValue;
}
}
}
查看我的代码,我看到首先调用getObject,然后调用setObject。因此,渲染似乎是在处理用户所做的更改之前完成的


谁能告诉我我做错了什么吗?

您正在onSelectionChanged中创建一个新的模型对象。这违背了模型的目的,模型应该修改,但不能替换。如果您需要创建一个新的模型对象,那么您也必须替换组件使用的模型(再次调用setModel(model)。

我知道这不是一个组件,而是一个组件的实现,但显示了总体思路

public class LocaleDropDownPanel extends Panel
{
private Locale sessionLocale;

public LocaleDropDownPanel(String id, Locale locale) 
{
    super(id);


    ArrayList<Locale> choices = Lists.newArrayList(Locale.getAvailableLocales());

    //didnt know if you need country or language 
    IChoiceRenderer<Locale> choiceRenderer = new ChoiceRenderer<Locale>("language");

    DropDownChoice<Locale> ddc = new DropDownChoice<Locale>("ddc", new PropertyModel<Locale>(this, "sessionLocale"), 
            new Model<ArrayList<Locale>>(choices), choiceRenderer)
    {
        @Override
        protected void onSelectionChanged(Locale newSelection) 
        {
             //if you want to save the selected locale in your session.
             GlobalAccountSession session = GlobalAccountSession.get();
             session.setLocale(newSelection);
        }
    };

    //This Language selected to begin with
    ddc.setDefaultModelObject(locale);

}

public Locale getSessionLocale() {
    return sessionLocale;
}

public void setSessionLocale(Locale sessionLocale) {
    this.sessionLocale = sessionLocale;
}
}
public类LocaleDropDownPanel扩展面板
{
专用语言环境sessionLocale;
公共LocaleDropDownPanel(字符串id、区域设置)
{
超级(id);
ArrayList choices=Lists.newArrayList(Locale.getAvailableLocales());
//我不知道你是否需要国家或语言
ICHOICHERENDER CHOICERENDER=新的CHOICERENDER(“语言”);
DropDownChoice ddc=新的DropDownChoice(“ddc”),新的PropertyModel(即“sessionLocale”),
新型号(可选),ChoiceRender)
{
@凌驾
受保护的无效onSelectionChanged(区域设置NewsSelection)
{
//如果要在会话中保存选定的区域设置。
GlobalAccountSession=GlobalAccountSession.get();
session.setLocale(新闻选举);
}
};
//选择此语言作为开始
setDefaultModelObject(区域设置);
}
公共区域设置getSessionLocale(){
返回sessionLocale;
}
public void setSessionLocale(区域设置sessionLocale){
this.sessionLocale=sessionLocale;
}
}

我真的不知道你为什么要使用这种型号。我会让下拉列表使用区域设置列表,然后在调用onSelectionChanged时,将所选语言添加到会话中。之所以使用该模型,是因为支持的语言是从后端系统加载的,但在这种情况下,您不需要模型。然后添加一个setSessionlanguage()方法,就不必创建自己的模型了。还可以将SessionLanguage设置为区域设置对象,而不是字符串。如果您担心现在呈现对象id的下拉列表,因为SessionLanguage是一个区域设置,请使用ChoiceRender显示正确的信息。由于wantOnSelectionChangedNotifications,因此在更改下拉列表值时会重新加载页面,如果未设置模型,则会出现错误。我得到错误:尝试在组件:header.panel:session.language的空模型上设置模型对象。这就是我添加模型的原因。