org.ebayopensource.turmeric.eclipse.repositorysystem.ui.pref.CustomRadioGroupFieldEditor.java Source code

Java tutorial

Introduction

Here is the source code for org.ebayopensource.turmeric.eclipse.repositorysystem.ui.pref.CustomRadioGroupFieldEditor.java

Source

/*******************************************************************************
 * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *******************************************************************************/
package org.ebayopensource.turmeric.eclipse.repositorysystem.ui.pref;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.ebayopensource.turmeric.eclipse.repositorysystem.preferences.core.PreferenceConstants;
import org.ebayopensource.turmeric.eclipse.repositorysystem.ui.RepositorySystemUIActivator;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;

/**
 * A field editor for an enumeration type preference. The choices are presented
 * as a list of radio buttons.
 * 
 * @author yayu
 */
public class CustomRadioGroupFieldEditor extends FieldEditor {

    /** The Constant SUB_VALUE. */
    public static final String SUB_VALUE = "field_editor_sub_value";//$NON-NLS-1$

    private String[][] labelsAndValues;

    /**
     * The first level key is repo ID, the second level key is org ID/Name, then
     * the value is org display name
     */
    private Map<String, Map<String, String>> organizations;

    private int numColumns;

    private int indent = HORIZONTAL_GAP;

    private String value;

    private String subPreferenceName;

    private String subValue;

    private Composite chooseArea;

    private Button[] radioButtons;

    private boolean useGroup;

    private Map<FieldEditor, Composite> subFieldEditors = new ConcurrentHashMap<FieldEditor, Composite>();

    private Map<String, List<Button>> subButtons = new ConcurrentHashMap<String, List<Button>>();

    /**
     * Instantiates a new custom radio group field editor.
     *
     * @param name the name
     * @param labelText the label text
     * @param numColumns the num columns
     * @param labelAndValues the label and values
     * @param organizations the organizations
     * @param parent the parent
     */
    public CustomRadioGroupFieldEditor(String name, String labelText, int numColumns, String[][] labelAndValues,
            Map<String, Map<String, String>> organizations, Composite parent) {
        this(name, labelText, numColumns, labelAndValues, organizations, parent, false);
    }

    /**
     * Instantiates a new custom radio group field editor.
     *
     * @param name the name
     * @param labelText the label text
     * @param numColumns the num columns
     * @param labelAndValues the label and values
     * @param organizations the organizations
     * @param parent the parent
     * @param useGroup the use group
     */
    public CustomRadioGroupFieldEditor(String name, String labelText, int numColumns, String[][] labelAndValues,
            Map<String, Map<String, String>> organizations, Composite parent, boolean useGroup) {

        setPreferenceStore(RepositorySystemUIActivator.getDefault().getPreferenceStore());
        init(name, labelText);
        Assert.isTrue(validateKeyValuePair(labelAndValues));
        Assert.isNotNull(organizations);
        this.subPreferenceName = PreferenceConstants.PREF_ORGANIZATION;
        this.labelsAndValues = labelAndValues;
        this.organizations = organizations;
        this.numColumns = numColumns;
        this.useGroup = useGroup;
        createControl(parent);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void doLoad() {
        String value = getPreferenceStore().getString(getPreferenceName());
        updateValue(value);
        setSubButtonsEnabled(value);
        updateSubValue(value, getPreferenceStore().getString(getSubPreferenceName()));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void doLoadDefault() {
        String value = getPreferenceStore().getDefaultString(getPreferenceName());
        updateValue(value);
        updateSubValue(value, getPreferenceStore().getDefaultString(getSubPreferenceName()));
    }

    /**
     * Gets the sub preference name.
     *
     * @return the sub preference name
     */
    public String getSubPreferenceName() {
        return subPreferenceName;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void doStore() {
        if (value == null) {
            getPreferenceStore().setToDefault(getPreferenceName());
            return;
        }

        getPreferenceStore().setValue(getPreferenceName(), value);

        if (subValue == null) {
            getPreferenceStore().setToDefault(getSubPreferenceName());
            return;
        }

        getPreferenceStore().setValue(getSubPreferenceName(), subValue);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int getNumberOfControls() {
        return 1;
    }

    private void createChooseArea(Composite parent) {
        Font font = parent.getFont();

        if (useGroup) {
            Group group = new Group(parent, SWT.NONE);
            group.setFont(font);
            String text = getLabelText();
            if (text != null) {
                group.setText(text);
            }
            chooseArea = group;
            GridLayout layout = new GridLayout();
            layout.horizontalSpacing = HORIZONTAL_GAP;
            layout.numColumns = numColumns;
            chooseArea.setLayout(layout);
        } else {
            chooseArea = new Composite(parent, SWT.NONE);
            GridLayout layout = new GridLayout();
            layout.marginWidth = 0;
            layout.marginHeight = 0;
            layout.horizontalSpacing = HORIZONTAL_GAP;
            layout.numColumns = numColumns;
            chooseArea.setLayout(layout);
            chooseArea.setFont(font);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void adjustForNumColumns(int numColumns) {
        Control control = getLabelControl();
        if (control != null) {
            ((GridData) control.getLayoutData()).horizontalSpan = numColumns;
        }
        ((GridData) chooseArea.getLayoutData()).horizontalSpan = numColumns;
    }

    private boolean validateKeyValuePair(String[][] keyValuePair) {
        if (keyValuePair == null) {
            return false;
        }
        for (int i = 0; i < keyValuePair.length; i++) {
            String[] array = keyValuePair[i];
            if (array == null || array.length != 2) {
                return false;
            }
        }
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void doFillIntoGrid(Composite parent, int numColumns) {
        if (useGroup == true) {
            Control control = getRadioBoxControl(parent);
            GridData data = new GridData(GridData.FILL_HORIZONTAL);
            control.setLayoutData(data);
        } else {
            Control control = getLabelControl(parent);
            GridData data = new GridData();
            data.horizontalSpan = numColumns;
            control.setLayoutData(data);
            control = getRadioBoxControl(parent);
            data = new GridData();
            data.horizontalSpan = numColumns;
            data.horizontalIndent = indent;
            control.setLayoutData(data);
        }

    }

    /**
     * Gets the radio box control.
     *
     * @param parent the parent
     * @return the radio box control
     */
    public Composite getRadioBoxControl(Composite parent) {
        if (chooseArea != null) {
            checkParent(chooseArea, parent);
            return chooseArea;
        }
        createChooseArea(parent);
        Font font = parent.getFont();
        radioButtons = new Button[labelsAndValues.length];
        for (int i = 0; i < labelsAndValues.length; i++) {
            final Button radio = new Button(chooseArea, SWT.RADIO | SWT.LEFT);
            radioButtons[i] = radio;
            String[] labelAndValue = labelsAndValues[i];
            radio.setText(labelAndValue[0]);
            radio.setData(labelAndValue[1]);
            radio.setFont(font);
            radio.setEnabled(organizations.size() > 1);
            radio.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent event) {
                    CustomRadioGroupFieldEditor.this.clearErrorMessage();
                    String oldValue = value;
                    value = (String) event.widget.getData();
                    setPresentsDefaultValue(false);
                    setSubButtonsEnabled(value);
                    fireValueChanged(VALUE, oldValue, value);
                }
            });

            final Composite composite = new Composite(chooseArea, SWT.NONE);
            final GridLayout layout = new GridLayout(1, true);
            composite.setLayout(layout);
            List<Button> buttons = new ArrayList<Button>();
            subButtons.put(labelAndValue[1], buttons);
            for (String orgId : organizations.get(labelAndValue[1]).keySet()) {
                final Button radio1 = new Button(composite, SWT.RADIO | SWT.LEFT);
                GridData data = new GridData();
                data.horizontalIndent = 30;
                radio1.setLayoutData(data);
                radio1.setText(organizations.get(labelAndValue[1]).get(orgId));
                radio1.setData(orgId);
                radio1.setFont(font);
                radio1.setEnabled(organizations.get(labelAndValue[1]).size() > 1);
                radio1.addSelectionListener(new SelectionAdapter() {
                    @Override
                    public void widgetSelected(SelectionEvent event) {
                        CustomRadioGroupFieldEditor.this.clearErrorMessage();
                        String oldValue = subValue;
                        subValue = (String) event.widget.getData();
                        setPresentsDefaultValue(false);
                        fireValueChanged(SUB_VALUE, oldValue, subValue);
                    }
                });
                buttons.add(radio1);
            }

            final Composite panel = new Composite(chooseArea, SWT.NONE);
            GridData data = new GridData(GridData.FILL_HORIZONTAL);
            data.horizontalSpan = numColumns;
            panel.setLayoutData(data);
            panel.setLayout(new GridLayout(2, false));
            final FieldEditor fieldEditor = createChoiceSubFieldEditor(panel, radio);
            if (fieldEditor != null) {
                Label label = fieldEditor.getLabelControl(panel);
                data = new GridData();
                data.horizontalIndent = 15;
                label.setLayoutData(data);
                subFieldEditors.put(fieldEditor, panel);
                fieldEditor.setEnabled(radio.getText().equals(getPreferenceStore().getString(getPreferenceName())),
                        panel);
                radio.addSelectionListener(new SelectionAdapter() {

                    @Override
                    public void widgetDefaultSelected(SelectionEvent e) {
                        widgetSelected(e);
                    }

                    @Override
                    public void widgetSelected(SelectionEvent e) {
                        setSubFieldEditorEnabled(false);
                        fieldEditor.setEnabled(radio.getSelection(), panel);
                        fieldEditor.setFocus();
                    }

                });
            }
        }
        chooseArea.addDisposeListener(new DisposeListener() {
            @Override
            public void widgetDisposed(DisposeEvent event) {
                chooseArea = null;
                radioButtons = null;
            }
        });

        return chooseArea;
    }

    private void setSubButtonsEnabled(String id) {
        for (String key : subButtons.keySet()) {
            for (Button btn : subButtons.get(key)) {
                btn.setEnabled(id.equals(key));
                btn.setSelection(false);
            }
        }
        updateSubValue(id, "");
    }

    /**
     * Creates the choice sub field editor.
     *
     * @param parent the parent
     * @param radioBtn the radio btn
     * @return the field editor
     */
    protected FieldEditor createChoiceSubFieldEditor(final Composite parent, final Button radioBtn) {

        return null;
    }

    private void setSubFieldEditorEnabled(boolean enabled) {
        for (FieldEditor fieldEditor : this.subFieldEditors.keySet()) {
            fieldEditor.setEnabled(enabled, this.subFieldEditors.get(fieldEditor));
        }
    }

    /**
     * Sets the indent used for the first column of the radion button matrix.
     * 
     * @param indent
     *            the indent (in pixels)
     */
    public void setIndent(int indent) {
        if (indent < 0) {
            this.indent = 0;
        } else {
            this.indent = indent;
        }
    }

    private void updateValue(String newValue) {
        this.value = newValue;
        if (radioButtons == null) {
            return;
        }

        if (this.value != null) {
            boolean found = false;
            for (int i = 0; i < radioButtons.length; i++) {
                Button radio = radioButtons[i];
                boolean selection = false;
                if (((String) radio.getData()).equals(this.value)) {
                    selection = true;
                    found = true;
                }
                radio.setSelection(selection);
            }
            if (found) {
                return;
            }
        }

        // if valie is not found, the first radio button will be selected.
        if (radioButtons.length > 0) {
            radioButtons[0].setSelection(true);
            this.value = (String) radioButtons[0].getData();
        }
        return;
    }

    private void updateSubValue(String firstValue, String selectedValue) {
        this.subValue = selectedValue;
        if (subButtons == null) {
            return;
        }

        if (this.subValue != null) {
            boolean found = false;
            for (Button radio : subButtons.get(this.value)) {
                boolean selection = false;
                if (((String) radio.getData()).equals(this.subValue)) {
                    selection = true;
                    found = true;
                }
                radio.setSelection(selection);
                radio.setEnabled(this.organizations.get(this.value).size() > 1);
            }
            if (found) {
                return;
            }
        }

        // if value is not found, the first radio button will be selected.
        if (subButtons.get(firstValue).isEmpty() == false) {
            subButtons.get(firstValue).get(0).setSelection(true);
            this.subValue = (String) subButtons.get(firstValue).get(0).getData();
        }
        return;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setEnabled(boolean enabled, Composite parent) {
        if (useGroup == false) {
            super.setEnabled(enabled, parent);
        }
        for (int i = 0; i < radioButtons.length; i++) {
            radioButtons[i].setEnabled(enabled);
        }

    }
}