Example usage for org.apache.wicket.markup.html.form.validation FormComponentFeedbackBorder add

List of usage examples for org.apache.wicket.markup.html.form.validation FormComponentFeedbackBorder add

Introduction

In this page you can find the example usage for org.apache.wicket.markup.html.form.validation FormComponentFeedbackBorder add.

Prototype

@Override
public Border add(final Component... children) 

Source Link

Document

This is for all components which have been added to the markup like this:
 <span wicket:id="myBorder"> <input wicket:id="text1" .. 

Usage

From source file:org.geogig.geoserver.web.repository.GeoGigDirectoryFormComponent.java

License:Open Source License

/**
 *
 * @param validators any extra validator that should be added to the input field, or
 *                   {@code null}//from   w  w  w .j a  v a2  s .c  om
 */
GeoGigDirectoryFormComponent(final String id, final IModel<String> valueModel) {
    // make the value of the text field the model of this panel, for easy value retrieval
    super(id, valueModel);

    // add the dialog for the file chooser
    add(dialog = new ModalWindow("dialog"));

    // the text field, with a decorator for validations
    directory = new TextField<>("value", valueModel);
    directory.setRequired(true);
    directory.setOutputMarkupId(true);

    IModel<String> labelModel = new ResourceModel("GeoGigDirectoryFormComponent.directory",
            "Parent directory") {

        private static final long serialVersionUID = 1L;

        @Override
        public String getObject() {
            String value = super.getObject();
            return value + " *";
        }
    };

    final Label directoryLabel = new Label("directoryLabel", labelModel.getObject());
    add(directoryLabel);

    directory.setLabel(labelModel);

    FormComponentFeedbackBorder feedback = new FormComponentFeedbackBorder("wrapper");
    feedback.add(directory);
    feedback.add(chooserButton());
    add(feedback);
}

From source file:org.geoserver.inspire.web.InspireAdminPanel.java

License:Open Source License

@SuppressWarnings({ "unchecked", "rawtypes" })
public InspireAdminPanel(final String id, final IModel<ServiceInfo> model) {
    super(id, model);

    MetadataMap serviceMetadata = model.getObject().getMetadata();

    String metadataURL = (String) serviceMetadata.get(SERVICE_METADATA_URL.key);
    String mediaType = (String) serviceMetadata.get(SERVICE_METADATA_TYPE.key);
    String language = (String) serviceMetadata.get(LANGUAGE.key);
    boolean isWfs = model.getObject() instanceof WFSInfo;
    UniqueResourceIdentifiers ids = null;
    if (isWfs) {//from  w  w  w  .  j  a v  a 2 s  .  c  o m
        ids = (UniqueResourceIdentifiers) serviceMetadata.get(SPATIAL_DATASET_IDENTIFIER_TYPE.key,
                UniqueResourceIdentifiers.class);
    }
    if (!serviceMetadata.containsKey(CREATE_EXTENDED_CAPABILITIES.key)) {
        if (metadataURL == null || isWfs && (ids == null || ids.isEmpty())) {
            serviceMetadata.put(CREATE_EXTENDED_CAPABILITIES.key, false);
        } else {
            serviceMetadata.put(CREATE_EXTENDED_CAPABILITIES.key, true);
        }
    }

    PropertyModel<MetadataMap> metadata = new PropertyModel<MetadataMap>(model, "metadata");

    final CheckBox createInspireExtendedCapabilities = new CheckBox("createExtendedCapabilities",
            new MetadataMapModel(metadata, CREATE_EXTENDED_CAPABILITIES.key, Boolean.class));
    add(createInspireExtendedCapabilities);

    final WebMarkupContainer container = new WebMarkupContainer("container");
    container.setOutputMarkupId(true);
    add(container);

    final WebMarkupContainer configs = new WebMarkupContainer("configs");
    configs.setOutputMarkupId(true);
    configs.setVisible(createInspireExtendedCapabilities.getModelObject());
    container.add(configs);

    createInspireExtendedCapabilities.add(new OnChangeAjaxBehavior() {
        private static final long serialVersionUID = 1L;

        @Override
        protected void onUpdate(AjaxRequestTarget target) {
            configs.setVisible(createInspireExtendedCapabilities.getModelObject());
            target.addComponent(container);
        }
    });

    if (!model.getObject().getMetadata().containsKey(LANGUAGE.key)) {
        model.getObject().getMetadata().put(LANGUAGE.key, "eng");
    }
    configs.add(new LanguageDropDownChoice("language", new MapModel(metadata, LANGUAGE.key)));

    TextField metadataUrlField = new TextField("metadataURL", new MapModel(metadata, SERVICE_METADATA_URL.key));
    metadataUrlField.setRequired(true);
    FormComponentFeedbackBorder metadataURLBorder = new FormComponentFeedbackBorder("border");
    metadataURLBorder.add(metadataUrlField);
    configs.add(metadataURLBorder);
    metadataUrlField.add(
            new AttributeModifier("title", true, new ResourceModel("InspireAdminPanel.metadataURL.title")));

    final Map<String, String> mdUrlTypes = new HashMap<String, String>();
    mdUrlTypes.put("application/vnd.ogc.csw.GetRecordByIdResponse_xml", "CSW GetRecordById Response");
    mdUrlTypes.put("application/vnd.iso.19139+xml", "ISO 19139 ServiceMetadata record");

    IModel<String> urlTypeModel = new MapModel(metadata, SERVICE_METADATA_TYPE.key);

    IChoiceRenderer<String> urlTypeChoiceRenderer = new IChoiceRenderer<String>() {
        private static final long serialVersionUID = 1L;

        @Override
        public Object getDisplayValue(final String key) {
            final String resourceKey = "InspireAdminPanel.metadataURLType." + key;// as found in
            // GeoServerApplication.properties
            final String defaultValue = key;
            final String displayValue = new ResourceModel(resourceKey, defaultValue).getObject();
            return displayValue;
        }

        @Override
        public String getIdValue(final String key, int index) {
            return key;
        }
    };
    List<String> urlTypeChoices = new ArrayList<String>(mdUrlTypes.keySet());
    DropDownChoice<String> serviceMetadataRecordType = new DropDownChoice<String>("metadataURLType",
            urlTypeModel, urlTypeChoices, urlTypeChoiceRenderer);
    serviceMetadataRecordType.setNullValid(true);

    configs.add(serviceMetadataRecordType);

    // this is WFS specific, will appear only if the service is WFS
    WebMarkupContainer identifiersContainer = new WebMarkupContainer("datasetIdentifiersContainer");
    identifiersContainer.setVisible(isWfs);
    configs.add(identifiersContainer);
    IModel<UniqueResourceIdentifiers> sdiModel = new MetadataMapModel(metadata,
            SPATIAL_DATASET_IDENTIFIER_TYPE.key, UniqueResourceIdentifiers.class);
    UniqueResourceIdentifiersEditor identifiersEditor = new UniqueResourceIdentifiersEditor(
            "spatialDatasetIdentifiers", sdiModel);
    identifiersContainer.add(identifiersEditor);
}

From source file:org.geoserver.inspire.web.UniqueResourceIdentifiersEditor.java

License:Open Source License

/**
 * @param id//w  ww  .  j  a  va2  s.  com
 * @param identifiersModel Must return a {@link ResourceInfo}
 */
public UniqueResourceIdentifiersEditor(String id, final IModel<UniqueResourceIdentifiers> identifiersModel) {
    super(id, identifiersModel);

    if (identifiersModel.getObject() == null) {
        identifiersModel.setObject(new UniqueResourceIdentifiers());
    }

    // container for ajax updates
    final WebMarkupContainer container = new WebMarkupContainer("container");
    container.setOutputMarkupId(true);
    add(container);

    // the link list
    identifiers = new GeoServerTablePanel<UniqueResourceIdentifier>("identifiers",
            new UniqueResourceIdentifiersProvider(identifiersModel), false) {

        @Override
        protected Component getComponentForProperty(String id, final IModel itemModel,
                Property<UniqueResourceIdentifier> property) {
            String name = property.getName();
            if ("code".equals(name)) {
                Fragment codeFragment = new Fragment(id, "txtFragment", UniqueResourceIdentifiersEditor.this);
                FormComponentFeedbackBorder codeBorder = new FormComponentFeedbackBorder("border");
                codeFragment.add(codeBorder);
                TextField<String> code = new TextField<String>("txt",
                        new PropertyModel<String>(itemModel, "code"));
                code.setLabel(new ParamResourceModel("th.code", UniqueResourceIdentifiersEditor.this));
                code.setRequired(true);
                codeBorder.add(code);
                return codeFragment;
            } else if ("namespace".equals(name)) {
                Fragment nsFragment = new Fragment(id, "txtFragment", UniqueResourceIdentifiersEditor.this);
                FormComponentFeedbackBorder namespaceBorder = new FormComponentFeedbackBorder("border");
                nsFragment.add(namespaceBorder);
                TextField<String> namespace = new TextField<String>("txt",
                        new PropertyModel<String>(itemModel, "namespace"));
                namespace
                        .setLabel(new ParamResourceModel("th.namespace", UniqueResourceIdentifiersEditor.this));
                namespace.add(new URIValidator());
                namespaceBorder.add(namespace);
                return nsFragment;
            } else if ("metadataURL".equals(name)) {
                Fragment urlFragment = new Fragment(id, "txtFragment", UniqueResourceIdentifiersEditor.this);
                FormComponentFeedbackBorder namespaceBorder = new FormComponentFeedbackBorder("border");
                urlFragment.add(namespaceBorder);
                TextField<String> url = new TextField<String>("txt",
                        new PropertyModel<String>(itemModel, "metadataURL"));
                url.add(new URIValidator());
                namespaceBorder.add(url);
                return urlFragment;
            } else if ("remove".equals(name)) {
                Fragment removeFragment = new Fragment(id, "removeFragment",
                        UniqueResourceIdentifiersEditor.this);
                GeoServerAjaxFormLink removeLink = new GeoServerAjaxFormLink("remove") {

                    @Override
                    protected void onClick(AjaxRequestTarget target, Form form) {
                        UniqueResourceIdentifiers identifiers = identifiersModel.getObject();
                        UniqueResourceIdentifier sdi = (UniqueResourceIdentifier) itemModel.getObject();
                        identifiers.remove(sdi);
                        target.addComponent(container);
                    }
                };
                removeFragment.add(removeLink);
                return removeFragment;
            }
            return null;
        }
    };
    identifiers.setItemReuseStrategy(ReuseIfModelsEqualStrategy.getInstance());
    identifiers.setPageable(false);
    identifiers.setSortable(false);
    identifiers.setFilterable(false);
    container.add(identifiers);

    // add new link button
    button = new AjaxButton("addIdentifier") {

        @Override
        protected void onSubmit(AjaxRequestTarget target, Form form) {
            UniqueResourceIdentifiers identifiers = identifiersModel.getObject();
            identifiers.add(new UniqueResourceIdentifier());

            target.addComponent(container);
        }

        @Override
        protected void onError(AjaxRequestTarget target, Form<?> form) {
            // the form validator triggered, but we don't want the msg to display
            Session.get().cleanupFeedbackMessages();
            Session.get().dirty();
            onSubmit(target, form);
        }

    };
    add(button);

    // grab a seat... the way I'm adding this validator in onBeforeRender will be hard
    // to stomach... however, could not find other way to add a validation to an editabl table, grrr
    add(new IValidator<UniqueResourceIdentifiers>() {

        @Override
        public void validate(IValidatable<UniqueResourceIdentifiers> validatable) {
            UniqueResourceIdentifiers identifiers = identifiersModel.getObject();
            if (identifiers.size() == 0) {
                ValidationError error = new ValidationError();
                String message = new ParamResourceModel("noSpatialDatasetIdentifiers",
                        UniqueResourceIdentifiersEditor.this).getString();
                error.setMessage(message);
                validatable.error(error);
            }

        }

    });
}

From source file:org.geoserver.web.data.resource.DataLinkEditor.java

License:Open Source License

/**
 * @param id//w ww .ja va2s .  com
 * @param resourceModel Must return a {@link ResourceInfo}
 */
public DataLinkEditor(String id, final IModel<ResourceInfo> resourceModel) {
    super(id, resourceModel);

    // container for ajax updates
    final WebMarkupContainer container = new WebMarkupContainer("container");
    container.setOutputMarkupId(true);
    add(container);

    // the link list
    table = new WebMarkupContainer("table");
    table.setOutputMarkupId(true);
    container.add(table);
    links = new ListView<DataLinkInfo>("links",
            new PropertyModel<List<DataLinkInfo>>(resourceModel, "dataLinks")) {

        @Override
        protected void populateItem(ListItem<DataLinkInfo> item) {

            // odd/even style
            item.add(new SimpleAttributeModifier("class", item.getIndex() % 2 == 0 ? "even" : "odd"));

            // link info
            FormComponentFeedbackBorder urlBorder = new FormComponentFeedbackBorder("urlBorder");
            item.add(urlBorder);
            TextField<String> format = new TextField<>("format",
                    new PropertyModel<String>(item.getModel(), "type"));
            format.setRequired(true);
            item.add(format);
            TextField<String> url = new TextField<>("dataLinkURL",
                    new PropertyModel<String>(item.getModel(), "content"));
            url.add(new UrlValidator());
            url.setRequired(true);
            urlBorder.add(url);

            // remove link
            AjaxLink<DataLinkInfo> link = new AjaxLink<DataLinkInfo>("removeLink", item.getModel()) {

                @Override
                public void onClick(AjaxRequestTarget target) {
                    ResourceInfo ri = (ResourceInfo) resourceModel.getObject();
                    ri.getDataLinks().remove(getModelObject());
                    updateLinksVisibility();
                    target.addComponent(container);
                }

            };
            item.add(link);
        }
    };
    // this is necessary to avoid loosing item contents on edit/validation checks
    links.setReuseItems(true);
    table.add(links);

    // the no data links label
    noData = new Label("noLinks", new ResourceModel("noDataLinksSoFar"));
    container.add(noData);
    updateLinksVisibility();

    // add new link button
    AjaxButton button = new AjaxButton("addlink") {

        @Override
        protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
            ResourceInfo ri = (ResourceInfo) resourceModel.getObject();
            DataLinkInfo link = ri.getCatalog().getFactory().createDataLink();
            ;
            link.setType("text/plain");
            ri.getDataLinks().add(link);
            updateLinksVisibility();

            target.addComponent(container);
        }

    };
    add(button);
}

From source file:org.geoserver.web.data.resource.MetadataLinkEditor.java

License:Open Source License

/**
 * @param id/* w w w .jav  a 2 s  .c  o m*/
 * @param model Must return a {@link ResourceInfo}
 */
public MetadataLinkEditor(String id, final IModel<ResourceInfo> resourceModel) {
    super(id, resourceModel);

    // container for ajax updates
    final WebMarkupContainer container = new WebMarkupContainer("container");
    container.setOutputMarkupId(true);
    add(container);

    // the link list
    table = new WebMarkupContainer("table");
    table.setOutputMarkupId(true);
    container.add(table);
    links = new ListView<MetadataLinkInfo>("links",
            new PropertyModel<List<MetadataLinkInfo>>(resourceModel, "metadataLinks")) {

        @Override
        protected void populateItem(ListItem<MetadataLinkInfo> item) {

            // odd/even style
            item.add(new SimpleAttributeModifier("class", item.getIndex() % 2 == 0 ? "even" : "odd"));

            // link info
            DropDownChoice<String> dropDownChoice = new DropDownChoice<>("type",
                    new PropertyModel<String>(item.getModel(), "metadataType"), LINK_TYPES);
            dropDownChoice.setRequired(true);
            item.add(dropDownChoice);
            FormComponentFeedbackBorder urlBorder = new FormComponentFeedbackBorder("urlBorder");
            item.add(urlBorder);
            TextField<String> format = new TextField<>("format",
                    new PropertyModel<String>(item.getModel(), "type"));
            format.setRequired(true);
            item.add(format);
            TextField<String> url = new TextField<>("metadataLinkURL",
                    new PropertyModel<String>(item.getModel(), "content"));
            url.add(new UrlValidator());
            url.setRequired(true);
            urlBorder.add(url);

            // remove link
            AjaxLink<MetadataLinkInfo> link = new AjaxLink<MetadataLinkInfo>("removeLink", item.getModel()) {

                @Override
                public void onClick(AjaxRequestTarget target) {
                    ResourceInfo ri = (ResourceInfo) resourceModel.getObject();
                    ri.getMetadataLinks().remove(getModelObject());
                    updateLinksVisibility();
                    target.addComponent(container);
                }

            };
            item.add(link);
        }
    };
    // this is necessary to avoid loosing item contents on edit/validation checks
    links.setReuseItems(true);
    table.add(links);

    // the no metadata links label
    noMetadata = new Label("noLinks", new ResourceModel("noMetadataLinksSoFar"));
    container.add(noMetadata);
    updateLinksVisibility();

    // add new link button
    AjaxButton button = new AjaxButton("addlink") {

        @Override
        protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
            ResourceInfo ri = (ResourceInfo) resourceModel.getObject();
            MetadataLinkInfo link = ri.getCatalog().getFactory().createMetadataLink();
            ;
            link.setMetadataType(LINK_TYPES.get(0));
            link.setType("text/plain");
            ri.getMetadataLinks().add(link);
            updateLinksVisibility();

            target.addComponent(container);
        }

    };
    add(button);
}

From source file:org.geoserver.web.data.store.arcsde.RasterTableSelectionPanel.java

License:Open Source License

public RasterTableSelectionPanel(final String id, final IModel paramsModel, final Form storeEditForm,
        FormComponent server, FormComponent port, FormComponent instance, FormComponent user,
        FormComponent password) {/*  w w  w.j a  va 2 s .co m*/

    super(id);
    this.serverComponent = server;
    this.portComponent = port;
    this.instanceComponent = instance;
    this.userComponent = user;
    this.passwordComponent = password;

    final MapModel tableNameModel = new MapModel(paramsModel, TABLE_NAME);

    List<String> choices = new ArrayList<String>();
    if (tableNameModel.getObject() != null) {
        Object currentTableName = tableNameModel.getObject();
        choices.add(String.valueOf(currentTableName));
    }

    choice = new DropDownChoice("rasterTable", tableNameModel, choices);

    /*
     * Make table name match the option id
     */
    choice.setChoiceRenderer(new IChoiceRenderer() {
        private static final long serialVersionUID = 1L;

        public String getIdValue(Object tableName, int index) {
            return tableName.toString();
        }

        public Object getDisplayValue(Object tableName) {
            return tableName;
        }
    });
    choice.setOutputMarkupId(true);
    choice.setNullValid(false);
    choice.setRequired(true);

    final FormComponentFeedbackBorder feedback = new FormComponentFeedbackBorder("border");
    feedback.add(choice);
    add(feedback);
    {
        final String titleKey = RESOURCE_KEY_PREFIX + ".tableNameChoice.title";
        ResourceModel titleModel = new ResourceModel(titleKey);
        String title = String.valueOf(titleModel.getObject());
        choice.add(new SimpleAttributeModifier("title", title));
    }

    final AjaxSubmitLink refreshTablesLink = new AjaxSubmitLink("refresh", storeEditForm) {
        private static final long serialVersionUID = 1L;

        /**
         * We're not doing any validation here, just want to perform the same attempt to get to
         * the list of connection parameters than at {@link #onSumbit}
         */
        @Override
        protected void onError(AjaxRequestTarget target, Form form) {
            onSubmit(target, form);
        }

        @Override
        protected void onSubmit(final AjaxRequestTarget target, final Form form) {

            final String server = serverComponent.getValue();
            final String port = portComponent.getValue();
            final String instance = instanceComponent.getValue();
            final String user = userComponent.getValue();
            final String password = passwordComponent.getValue();

            final ISessionPoolFactory sessionFac = getSessionFactory();

            List<String> rasterColumns;
            try {
                rasterColumns = getRasterColumns(server, port, instance, user, password, sessionFac);
            } catch (IllegalArgumentException e) {
                rasterColumns = Collections.emptyList();
                String message = "Refreshing raster tables list: " + e.getMessage();
                storeEditForm.error(message);
                target.addComponent(storeEditForm);// refresh
            }

            choice.setChoices(rasterColumns);
            target.addComponent(choice);
            // do nothing else, so we return to the same page...
        }
    };
    add(refreshTablesLink);
    {
        final String titleKey = RESOURCE_KEY_PREFIX + ".refresh.title";
        ResourceModel titleModel = new ResourceModel(titleKey);
        String title = String.valueOf(titleModel.getObject());
        refreshTablesLink.add(new SimpleAttributeModifier("title", title));
    }
}

From source file:org.geoserver.web.data.store.panel.CharsetPanel.java

License:Open Source License

public CharsetPanel(final String id, final IModel charsetModel, final IModel paramLabelModel,
        final boolean required) {
    // make the value of the combo field the model of this panel, for easy
    // value retriaval
    super(id, charsetModel);

    // the label/*from  www  .  ja v  a  2 s.  c o  m*/
    String requiredMark = required ? " *" : "";
    Label label = new Label("paramName", paramLabelModel.getObject() + requiredMark);
    add(label);

    // the drop down field, with a decorator for validations
    final ArrayList charsets = new ArrayList(Charset.availableCharsets().keySet());
    choice = new DropDownChoice("paramValue", charsetModel, charsets);
    choice.setRequired(required);
    // set the label to be the paramLabelModel otherwise a validation error would look like
    // "Parameter 'paramValue' is required"
    choice.setLabel(paramLabelModel);

    FormComponentFeedbackBorder feedback = new FormComponentFeedbackBorder("border");
    feedback.add(choice);
    add(feedback);
}

From source file:org.geoserver.web.data.store.panel.ColorPickerPanel.java

License:Open Source License

/**
 * /* www .  j av a2s.  c o  m*/
 * @param id
 * @param paramsMap
 * @param paramName
 * @param paramLabel
 * @param required
 * @param validators
 *            any extra validator that should be added to the input field,
 *            or {@code null}
 */
public ColorPickerPanel(final String id, final IModel paramVale, final IModel paramLabelModel,
        final boolean required, IValidator... validators) {
    // make the value of the text field the model of this panel, for easy
    // value retriaval
    super(id, paramVale);

    // the label
    String requiredMark = required ? " *" : "";
    Label label = new Label("paramName", paramLabelModel.getObject() + requiredMark);
    add(label);

    // the color picker. Notice that we need to convert between RRGGBB and
    // #RRGGBB,
    // passing in a Color.class param is just a trick to force the component
    // to use
    // the converter both ways
    ColorPickerField textField = new ColorPickerField("paramValue", paramVale, Color.class) {
        @Override
        public IConverter getConverter(Class type) {
            return new IConverter() {

                public String convertToString(Object value, Locale locale) {
                    String input = (String) value;
                    if (input.startsWith("#"))
                        return input.substring(1);
                    else
                        return input;
                }

                public Object convertToObject(String value, Locale locale) {
                    if (value.equals(""))
                        return value;
                    return "#" + value;
                }
            };
        }
    };
    textField.setRequired(required);
    // set the label to be the paramLabelModel otherwise a validation error
    // would look like
    // "Parameter 'paramValue' is required"
    textField.setLabel(paramLabelModel);

    if (validators != null) {
        for (IValidator validator : validators) {
            textField.add(validator);
        }
    }
    FormComponentFeedbackBorder feedback = new FormComponentFeedbackBorder("border");
    feedback.add(textField);
    add(feedback);
}

From source file:org.geoserver.web.data.store.panel.DropDownChoiceParamPanel.java

License:Open Source License

/**
 * @param id//from   www .  ja  va  2  s.c  o  m
 *            panel id
 * @param paramValue
 *            model for the component's value
 * @param paramLabelModel
 *            model for the parameter name label
 * @param options
 *            drop down choices
 * @param required
 *            true if a value is required, false otherwise
 */
public DropDownChoiceParamPanel(final String id, final IModel<Serializable> paramValue,
        final IModel<String> paramLabelModel, final List<? extends Serializable> options,
        final boolean required) {

    super(id);

    String requiredMark = required ? " *" : "";
    Label label = new Label("paramName", paramLabelModel.getObject() + requiredMark);
    add(label);

    choice = new DropDownChoice<Serializable>("paramValue", paramValue, options);
    choice.setRequired(required);

    FormComponentFeedbackBorder feedback = new FormComponentFeedbackBorder("border");
    feedback.add(choice);
    add(feedback);
}

From source file:org.geoserver.web.data.store.panel.FileParamPanel.java

License:Open Source License

/**
 * /*  w  ww  .  jav a  2  s .  c o m*/
 * @param id
 * @param paramsMap
 * @param paramName
 * @param paramLabelModel
 * @param required
 * @param validators
 *            any extra validator that should be added to the input field, or {@code null}
 */
public FileParamPanel(final String id, final IModel paramValue, final IModel paramLabelModel,
        final boolean required, IValidator... validators) {
    // make the value of the text field the model of this panel, for easy value retrieval
    super(id, paramValue);

    // add the dialog for the file chooser
    add(dialog = new ModalWindow("dialog"));

    // the label
    String requiredMark = required ? " *" : "";
    Label label = new Label("paramName", paramLabelModel.getObject() + requiredMark);
    add(label);

    // the text field, with a decorator for validations
    textField = new TextField("paramValue", new FileModel(paramValue));
    textField.setRequired(required);
    textField.setOutputMarkupId(true);
    // set the label to be the paramLabelModel otherwise a validation error would look like
    // "Parameter 'paramValue' is required"
    textField.setLabel(paramLabelModel);

    if (validators != null) {
        for (IValidator validator : validators) {
            textField.add(validator);
        }
    }

    FormComponentFeedbackBorder feedback = new FormComponentFeedbackBorder("border");
    feedback.add(textField);
    feedback.add(chooserButton((String) paramLabelModel.getObject()));
    add(feedback);
}