/** * Copyright (C) 2015 Valkyrie RCP * * 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 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.valkyriercp.factory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.context.MessageSourceResolvable; import org.springframework.context.NoSuchMessageException; import org.springframework.context.support.MessageSourceAccessor; import org.valkyriercp.binding.format.support.AbstractFormatterFactory; import org.valkyriercp.binding.value.ValueModel; import org.valkyriercp.command.config.CommandButtonLabelInfo; import org.valkyriercp.component.PatchedJFormattedTextField; import org.valkyriercp.core.support.LabelInfo; import org.valkyriercp.image.IconSource; import org.valkyriercp.util.Alignment; import org.valkyriercp.util.GuiStandardUtils; import org.valkyriercp.util.UIConstants; import org.valkyriercp.util.ValkyrieRepository; import javax.swing.*; import javax.swing.table.TableModel; import java.awt.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; /** * Default component factory implementation that delegates to JGoodies component * factory. * * @author Keith Donald */ public class DefaultComponentFactory implements ComponentFactory, MessageSourceAware { private final Log logger = LogFactory.getLog(getClass()); private int textFieldColumns = 25; private MessageSource messageSource; public TableFactory getTableFactory() { return ValkyrieRepository.getInstance().getApplicationConfig().tableFactory(); } public MessageSource getMessageSource() { if(messageSource == null) return ValkyrieRepository.getInstance().getApplicationConfig().messageSource(); return messageSource; } /** * {@inheritDoc} */ public JLabel createLabel(String labelKey) { JLabel label = createNewLabel(); getLabelInfo(getRequiredMessage(labelKey)).configureLabel(label); return label; } /** * {@inheritDoc} */ public JLabel createLabel(String[] labelKeys) { JLabel label = createNewLabel(); getLabelInfo(getRequiredMessage(labelKeys)).configureLabel(label); return label; } /** * {@inheritDoc} */ public JLabel createLabel(String labelKey, Object[] arguments) { JLabel label = createNewLabel(); getLabelInfo(getRequiredMessage(labelKey, arguments)).configureLabel(label); return label; } /** * Parse the given label to create a {@link LabelInfo}. * * @param label The label to parse. * @return a {@link LabelInfo} representing the label. * @see LabelInfo#valueOf(String) */ protected LabelInfo getLabelInfo(String label) { return LabelInfo.valueOf(label); } /** * Get the message for the given key. Don't throw an exception if it's not * found but return a default value. * * @param messageKey Key to lookup the message. * @return the message found in the resources or a default message. */ protected String getRequiredMessage(String messageKey) { return getRequiredMessage(messageKey, null); } /** * Get the message for the given key. Don't throw an exception if it's not * found but return a default value. * * @param messageKeys The keys to use when looking for the message. * @return the message found in the resources or a default message. */ protected String getRequiredMessage(final String[] messageKeys) { MessageSourceResolvable resolvable = new MessageSourceResolvable() { public String[] getCodes() { return messageKeys; } public Object[] getArguments() { return null; } public String getDefaultMessage() { if (messageKeys.length > 0) { return messageKeys[0]; } return ""; } }; return getMessages().getMessage(resolvable); } /** * Returns the messageSourceAccessor. */ private MessageSourceAccessor getMessages() { return ValkyrieRepository.getInstance().getApplicationConfig().messageSourceAccessor(); } /** * {@inheritDoc} */ public JLabel createLabel(String labelKey, ValueModel[] argumentValueHolders) { return new LabelTextRefresher(labelKey, argumentValueHolders).getLabel(); } @Override public void setMessageSource(MessageSource messageSource) { this.messageSource = messageSource; } private class LabelTextRefresher implements PropertyChangeListener { private String labelKey; private JLabel label; private ValueModel[] argumentHolders; public LabelTextRefresher(String labelKey, ValueModel[] argumentHolders) { this.labelKey = labelKey; this.argumentHolders = argumentHolders; this.label = createNewLabel(); subscribe(); updateLabel(); } private void subscribe() { for (int i = 0; i < argumentHolders.length; i++) { ValueModel argHolder = argumentHolders[i]; argHolder.addValueChangeListener(this); } } public JLabel getLabel() { return label; } public void propertyChange(PropertyChangeEvent evt) { updateLabel(); } private void updateLabel() { Object[] argValues = new Object[argumentHolders.length]; for (int i = 0; i < argumentHolders.length; i++) { ValueModel argHolder = argumentHolders[i]; argValues[i] = argHolder.getValue(); } getLabelInfo(getRequiredMessage(labelKey, argValues)).configureLabel(label); } } private String getRequiredMessage(String messageKey, Object[] args) { try { String message = getMessages().getMessage(messageKey, args); return message; } catch (NoSuchMessageException e) { return messageKey; } } public JLabel createTitleLabel(String labelKey) { return com.jgoodies.forms.factories.DefaultComponentFactory.getInstance().createTitle( getRequiredMessage(labelKey)); } public JComponent createTitledBorderFor(String labelKey, JComponent component) { component.setBorder(BorderFactory.createCompoundBorder(BorderFactory .createTitledBorder(getRequiredMessage(labelKey)), GuiStandardUtils .createEvenlySpacedBorder(UIConstants.ONE_SPACE))); return component; } public JLabel createLabelFor(String labelKey, JComponent component) { JLabel label = createNewLabel(); getLabelInfo(getRequiredMessage(labelKey)).configureLabelFor(label, component); return label; } public JLabel createLabelFor(String[] labelKeys, JComponent component) { JLabel label = createNewLabel(); getLabelInfo(getRequiredMessage(labelKeys)).configureLabelFor(label, component); return label; } protected JLabel createNewLabel() { return new JLabel(); } public JButton createButton(String labelKey) { return (JButton) getButtonLabelInfo(getRequiredMessage(labelKey)).configure(getButtonFactory().createButton()); } protected CommandButtonLabelInfo getButtonLabelInfo(String label) { return CommandButtonLabelInfo.valueOf(label); } protected ButtonFactory getButtonFactory() { return ValkyrieRepository.getInstance().getApplicationConfig().buttonFactory(); } public JComponent createLabeledSeparator(String labelKey) { return createLabeledSeparator(labelKey, Alignment.LEFT); } public JCheckBox createCheckBox(String labelKey) { return (JCheckBox) getButtonLabelInfo(getRequiredMessage(labelKey)).configure(createNewCheckBox()); } public JCheckBox createCheckBox(String[] labelKeys) { return (JCheckBox) getButtonLabelInfo(getRequiredMessage(labelKeys)).configure(createNewCheckBox()); } protected JCheckBox createNewCheckBox() { return new JCheckBox(); } public JToggleButton createToggleButton(String labelKey) { return (JToggleButton) getButtonLabelInfo(getRequiredMessage(labelKey)).configure(createNewToggleButton()); } public JToggleButton createToggleButton(String[] labelKeys) { return (JToggleButton) getButtonLabelInfo(getRequiredMessage(labelKeys)).configure(createNewToggleButton()); } protected AbstractButton createNewToggleButton() { return new JToggleButton(); } /* * (non-Javadoc) * @see org.springframework.richclient.factory.ComponentFactory#createRadioButton(java.lang.String) */ public JRadioButton createRadioButton(String labelKey) { return (JRadioButton) getButtonLabelInfo(getRequiredMessage(labelKey)).configure(createNewRadioButton()); } protected JRadioButton createNewRadioButton() { return new JRadioButton(); } public JRadioButton createRadioButton(String[] labelKeys) { return (JRadioButton) getButtonLabelInfo(getRequiredMessage(labelKeys)).configure(createNewRadioButton()); } public JMenuItem createMenuItem(String labelKey) { return (JMenuItem) getButtonLabelInfo(getRequiredMessage(labelKey)) .configure(getMenuFactory().createMenuItem()); } protected MenuFactory getMenuFactory() { return ValkyrieRepository.getInstance().getApplicationConfig().menuFactory(); } public JComponent createLabeledSeparator(String labelKey, Alignment alignment) { return com.jgoodies.forms.factories.DefaultComponentFactory.getInstance().createSeparator( getRequiredMessage(labelKey), ((Number) alignment.getCode()).intValue()); } public JList createList() { return new JList(); } public JComboBox createComboBox() { return new JComboBox(); } public JComboBox createListValueModelComboBox(ValueModel selectedItemValueModel, ValueModel selectableItemsListHolder, String renderedPropertyPath) { return null; } /** * Returns the default column count for new text fields (including formatted * text and password fields) * * @return the default column count. Must not be lower than 0 * @see JTextField */ public int getTextFieldColumns() { return textFieldColumns; } /** * Defines the default column count for new text fields (including formatted * text and password fields) * * @param columns the default column count. Must not be lower than 0 * @see JTextField */ public void setTextFieldColumns(int columns) { if (columns < 0) throw new IllegalArgumentException("text field columns must not be lower than 0. Value was: " + columns); this.textFieldColumns = columns; } public JFormattedTextField createFormattedTextField(AbstractFormatterFactory formatterFactory) { PatchedJFormattedTextField patchedJFormattedTextField = new PatchedJFormattedTextField(formatterFactory); configureTextField(patchedJFormattedTextField); return patchedJFormattedTextField; } public JTextField createTextField() { JTextField textField = new JTextField(); configureTextField(textField); return textField; } /** * Configures the text field. * * @param textField the field to configure. Must not be null */ protected void configureTextField(JTextField textField) { textField.setColumns(getTextFieldColumns()); } public JPasswordField createPasswordField() { JPasswordField passwordField = new JPasswordField(); configureTextField(passwordField); return passwordField; } public JTextArea createTextArea() { return new JTextArea(); } public JTextArea createTextArea(int rows, int columns) { JTextArea textArea = createTextArea(); textArea.setRows(rows); textArea.setColumns(columns); return textArea; } public JTextArea createTextAreaAsLabel() { return GuiStandardUtils.textAreaAsLabel(createTextArea()); } public JTabbedPane createTabbedPane() { return new JTabbedPane(); } public void addConfiguredTab(JTabbedPane tabbedPane, String labelKey, JComponent tabComponent) { LabelInfo info = getLabelInfo(getRequiredMessage(labelKey)); tabbedPane.addTab(info.getText(), tabComponent); int tabIndex = tabbedPane.getTabCount() - 1; tabbedPane.setMnemonicAt(tabIndex, info.getMnemonic()); tabbedPane.setDisplayedMnemonicIndexAt(tabIndex, info.getMnemonicIndex()); tabbedPane.setIconAt(tabIndex, getIcon(labelKey)); tabbedPane.setToolTipTextAt(tabIndex, getCaption(labelKey)); } public JScrollPane createScrollPane() { return new JScrollPane(); } public JScrollPane createScrollPane(Component view) { return new JScrollPane(view); } public JScrollPane createScrollPane(Component view, int vsbPolicy, int hsbPolicy) { return new JScrollPane(view, vsbPolicy, hsbPolicy); } public JPanel createPanel() { return new JPanel(); } public JPanel createPanel(LayoutManager layoutManager) { return new JPanel(layoutManager); } private String getCaption(String labelKey) { return getOptionalMessage(labelKey + ".caption"); } protected String getOptionalMessage(String messageKey) { return getMessages().getMessage(messageKey, (String) null); } private Icon getIcon(String labelKey) { return getIconSource().getIcon(labelKey); } /** * Returns the icon source. */ private IconSource getIconSource() { return ValkyrieRepository.getInstance().getApplicationConfig().iconSource(); } /** * Construct a JTable with a default model It will delegate the creation to * a TableFactory if it exists. * * @return The new table. */ public JTable createTable() { return (getTableFactory() != null) ? getTableFactory().createTable() : new JTable(); } /** * Construct a JTable with the specified table model. It will delegate the * creation to a TableFactory if it exists. * * @param model the table model * @return The new table. */ public JTable createTable(TableModel model) { return (getTableFactory() != null) ? getTableFactory().createTable(model) : new JTable(model); } /** * {@inheritDoc} */ public JComponent createToolBar() { JToolBar toolBar = new JToolBar(); toolBar.setFloatable(false); toolBar.setRollover(true); return toolBar; } }