Java tutorial
/* * Copyright 2013-2016 Erwin Mller <erwin.mueller@deventm.org> * * This file is part of prefdialog-corefields. * * prefdialog-corefields is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * prefdialog-corefields is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with prefdialog-corefields. If not, see <http://www.gnu.org/licenses/>. */ package com.anrisoftware.prefdialog.fields.fieldbutton; import static org.apache.commons.lang3.StringUtils.isEmpty; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyVetoException; import java.lang.annotation.Annotation; import java.util.Locale; import javax.inject.Inject; import javax.swing.AbstractButton; import javax.swing.Action; import javax.swing.ButtonGroup; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import com.anrisoftware.globalpom.reflection.annotationclass.AnnotationClass; import com.anrisoftware.globalpom.reflection.annotationclass.AnnotationClassFactory; import com.anrisoftware.globalpom.reflection.annotations.AnnotationAccess; import com.anrisoftware.globalpom.reflection.annotations.AnnotationAccessFactory; import com.anrisoftware.prefdialog.annotations.FieldButton; import com.anrisoftware.prefdialog.core.AbstractTitleField; import com.anrisoftware.resources.texts.api.Texts; /** * Abstract button field. * * @see FieldButton * * @author Erwin Mueller, erwin.mueller@deventm.org * @since 3.0 */ @SuppressWarnings("serial") public class AbstractFieldButtonField<ComponentType extends AbstractButton> extends AbstractTitleField<ComponentType> { private static final Class<? extends Annotation> ANNOTATION_TYPE = FieldButton.class; private static final String TEXT_ELEMENT = "text"; private static final String SHOW_TEXT_ELEMENT = "showText"; private static final String ACTION_ELEMENT = "action"; private static final String GROUP_ELEMENT = "group"; private transient ActionListener valueAction; private transient ChangeListener changeListener; private transient AnnotationAccess fieldAnnotation; private transient AnnotationClass<?> annotationClass; private AbstractFieldButtonFieldLogger log; private String textResource; private String text; private boolean showText; private ButtonGroup buttonGroup; /** * Sets the dependencies of the field button. * * @see AbstractTitleField#AbstractTitleField(java.awt.Component, Object, * String) */ protected AbstractFieldButtonField(ComponentType component, Object parentObject, String fieldName) { super(component, parentObject, fieldName); readResolve(); } private Object readResolve() { this.valueAction = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { setValue(getComponent().isSelected()); } catch (PropertyVetoException e1) { } } }; this.changeListener = new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { try { setValue(getComponent().isSelected()); } catch (PropertyVetoException e1) { } } }; return this; } @Inject void setupAbstractFieldButton(AbstractFieldButtonFieldLogger logger, AnnotationAccessFactory annotationAccessFactory, AnnotationClassFactory annotationClassFactory) { this.log = logger; this.fieldAnnotation = annotationAccessFactory.create(ANNOTATION_TYPE, getAccessibleObject()); this.annotationClass = annotationClassFactory.create(getParentObject(), ANNOTATION_TYPE, getAccessibleObject()); setupText(); setupShowText(); setupAction(); setupGroup(); setupButton(); } private void setupText() { String text = getFieldButtonAttr(TEXT_ELEMENT); text = isEmpty(text) ? getFieldName() : text; setText(text); } private void setupShowText() { boolean show = getFieldButtonAttr(SHOW_TEXT_ELEMENT); setShowText(show); } private void setupAction() { ActionListener action = createFieldButtonAttr(ACTION_ELEMENT); if (action == null) { return; } if (action instanceof Action) { setAction((Action) action); } else { addActionListener(action); } } private void setupGroup() { ButtonGroup group = createFieldButtonAttr(GROUP_ELEMENT); if (group != null) { setButtonGroup(group); } } private void setupButton() { getComponent().addActionListener(valueAction); getComponent().addChangeListener(changeListener); } @Override public void setLocale(Locale locale) { super.setLocale(locale); updateTextsResources(); } /** * Sets the text of the check-box. Defaults to the empty string which means * the field name is used as the text. * <p> * The text can also be a resource name that is queried in the supplied * texts resource. * * @param text * the text. */ public void setText(String text) { textResource = text; this.text = text; updateTextResource(); log.textSet(this, text); } /** * Returns the text of the check-box. * * @return the text. */ public String getText() { return text; } @Override public void setTexts(Texts texts) { super.setTexts(texts); updateTextsResources(); } private void updateTextsResources() { updateTextResource(); } private void updateTextResource() { if (haveTextResource(textResource)) { text = getTextResource(textResource, text); } if (showText) { getComponent().setText(text); updateMnemonic(); } else { getComponent().setText(""); } } private void updateMnemonic() { if (!showText) { return; } Integer mnemonic = getMnemonic(); if (mnemonic != null) { getComponent().setMnemonic(mnemonic); } int index = getMnemonicIndex(); if (index != -1) { getComponent().setDisplayedMnemonicIndex(index); } } /** * Sets if the text of the check-box should be visible or not. Defaults to * {@code true} which means that the text should be visible. * * @param show * {@code true} for show the text or {@code false} to not show. */ public void setShowText(boolean show) { this.showText = show; updateTextResource(); log.showTextSet(this, show); } /** * Returns if the text is showing or not. * * @return {@code true} for show the text or {@code false} to not show. */ public boolean getShowText() { return showText; } /** * Adds the action listener to the radio button. * * @param listener * the {@link ActionListener}. * * @throws NullPointerException * if the specified listener is {@code null}. */ public void addActionListener(ActionListener listener) { log.checkActionListener(this, listener); getComponent().addActionListener(listener); log.actionAdded(this, listener); } /** * Removed the action listener to the radio button. * * @param listener * the {@link ActionListener}. * * @throws NullPointerException * if the specified listener is {@code null}. */ public void removeActionListener(ActionListener listener) { log.checkActionListener(this, listener); getComponent().removeActionListener(listener); log.actionRemoved(this, listener); } /** * Sets the action for the radio button. * * @param action * the {@link Action} or {@code null}. */ public void setAction(Action action) { getComponent().setAction(action); log.actionSet(this, action); } /** * Returns the action for the radio button. * * @return the {@link Action} or {@code null}. */ public Action getAction() { return getComponent().getAction(); } /** * Sets the button group for this radio button. The button is added to the * specified group. * * @param group * the {@link ButtonGroup}. * * @throws NullPointerException * if the specified group is {@code null}. */ public void setButtonGroup(ButtonGroup group) { log.checkButtonGroup(this, group); this.buttonGroup = group; group.add(getComponent()); log.buttonGroupSet(this, group); } /** * Returns the button group of this radio button. * * @return the {@link ButtonGroup} or {@code null} if the button does not * belong to any group. */ public ButtonGroup getButtonGroup() { return buttonGroup; } /** * Instantiate the class of the field button annotation attribute. * * @see FieldButton * * @param name * the {@link String} name of the attribute. * * @return the {@link Object} or {@code null}. */ @SuppressWarnings("unchecked") protected final <T> T createFieldButtonAttr(String name) { return (T) annotationClass.forAttribute(name).build(); } /** * Returns the value of the field button annotation attribute. * * @see FieldButton * * @param name * the {@link String} name of the attribute. * * @return the {@link Object} value or {@code null}. */ protected final <T> T getFieldButtonAttr(String name) { return fieldAnnotation.getValue(name); } }