/* * Copyright 2008-2011 the original author or authors. * * 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.jdal.swing.form; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Font; import java.awt.Image; import java.awt.Toolkit; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Vector; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.ComboBoxModel; import javax.swing.DefaultComboBoxModel; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JOptionPane; import javax.swing.UIManager; import javax.swing.border.Border; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jdal.beans.StaticMessageSource; import org.jdal.swing.SimpleDialog; import org.springframework.beans.BeanWrapper; import org.springframework.beans.PropertyAccessorFactory; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; /** * Static utility library for use in Swing Forms * * @author Jose Luis Martin - (jlm@joseluismartin.info) */ @SuppressWarnings("unchecked") public abstract class FormUtils { public static final Icon CANCEL_ICON = getIcon("images/16x16/dialog-cancel.png"); public static final Icon OK_ICON = getIcon("/images/16x16/dialog-ok.png"); private static final Log log = LogFactory.getLog(FormUtils.class); public static void link(final JComboBox<?> primary, final JComboBox<?> dependent, final String propertyName) { link(primary, dependent, propertyName, false); } /** * Add a link on primary and dependent JComboBoxes by property name. * When selection changes on primary use propertyName to get a Collection and fill dependent JComboBox with it * @param primary JComboBox when selection changes * @param dependent JComboBox that are filled with collection * @param propertyName the property name for get the collection from primary selected item * @param addNull if true, add a null as first combobox item */ @SuppressWarnings("rawtypes") public static void link(final JComboBox primary, final JComboBox dependent, final String propertyName, final boolean addNull) { primary.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Object selected = primary.getSelectedItem(); if (selected != null) { BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(selected); if (wrapper.isWritableProperty(propertyName)) { Collection collection = (Collection) wrapper.getPropertyValue(propertyName); Vector<Object> vector = new Vector<Object>(collection); if (addNull) vector.add(0, null); DefaultComboBoxModel model = new DefaultComboBoxModel(vector); dependent.setModel(model); } else { log.error("Can't write on propety '" + propertyName + "' of class: '" + selected.getClass() + "'"); } } } }); } /** * Return a List of Objects from a ComboBoxModel * @param model ComboBoxModel * @return a list of Objects with ComboBoxModel items */ public static List<Object> getComboModelList(ComboBoxModel<?> model) { ArrayList<Object> list = new ArrayList<Object>(); for (int i = 0; i < model.getSize(); i++) { list.add(model.getElementAt(i)); } return list; } public static <T> JComboBox<T> newCombo(Class<T> clazz, int chars) { return (JComboBox<T>) newCombo(chars); } public static JComboBox<?> newCombo(int chars) { StringBuilder sb = new StringBuilder(chars); while (chars-- > 0) sb.append("X"); JComboBox<String> combo = new JComboBox<String>(); combo.setPrototypeDisplayValue(sb.toString()); return combo; } /** * Make font of JLabel bold * @param label JLabel to make bold */ public static void setBold(JLabel label) { label.setFont(label.getFont().deriveFont(Font.BOLD)); } /** * Create Titled Border * @param name the title * @return Border */ public static Border createTitledBorder(String name) { Border margin = BorderFactory.createEmptyBorder(10, 10, 10, 10); Border title = BorderFactory.createTitledBorder(name); return BorderFactory.createCompoundBorder(title, margin); } /** * Get Default OK Button from LookAndFeel (like JOptionPane) */ public static JButton newOKButton() { String text = StaticMessageSource.getMessage("Accept"); int mnemonic = getMnemonic("OptionPane.okButtonMnemonic"); JButton b = new JButton(text, OK_ICON); b.setMnemonic(mnemonic); b.setAlignmentX(Container.CENTER_ALIGNMENT); b.setAlignmentY(Container.CENTER_ALIGNMENT); return b; } /** * Get Default Cancel Button from LookAndFeel (like JOptionPane) */ public static JButton newCancelButton() { String text = StaticMessageSource.getMessage("Cancel"); int mnemonic = getMnemonic("OptionPane.cancelButtonMnemonic"); JButton b = new JButton(text, CANCEL_ICON); b.setMnemonic(mnemonic); b.setAlignmentX(Container.CENTER_ALIGNMENT); b.setAlignmentY(Container.CENTER_ALIGNMENT); return b; } private static int getMnemonic(String key) { String value = (String) UIManager.get(key); if (value == null) { return 0; } try { return Integer.parseInt(value); } catch (NumberFormatException nfe) { } return 0; } /** * Load Icon from url * @param url * @return Icon, null on faliure */ public static Icon getIcon(String url) { Resource resource = new ClassPathResource(url); Icon icon = null; try { Image image = Toolkit.getDefaultToolkit().getImage(resource.getURL()); icon = new ImageIcon(image); } catch (IOException e) { log.error(e); } return icon; } /** * Load icon if icon = null, else return icon. * @param icon icon to load * @param url String with url * @return icon */ public static Icon getIcon(Icon icon, String url) { return icon != null ? icon : getIcon(url); } /** * Make a JMenu from an Action List * @param actions the Action List * @return JMenu */ public static JMenu toMenu(List<Action> actions) { JMenu menu = new JMenu(); for (Action a : actions) menu.add(a); return menu; } /** * @param message * @return JLabel */ public static JLabel newLabelForBox(String message) { JLabel label = new JLabel(message); label.setMaximumSize(new Dimension(Short.MAX_VALUE, label.getFont().getSize() + 10)); label.setAlignmentX(Container.CENTER_ALIGNMENT); return label; } /** * Show error message * @param message message to show */ public static void showError(String message) { showError(null, message); } /** * Show error message * @param parent component parent * @param message message to show */ public static void showError(Component parent, String message) { JOptionPane.showMessageDialog(parent, message, "Error", JOptionPane.ERROR_MESSAGE); } /** * Creates a new JDialog with default accept/cancel buttons * @param component to show in * @return new created dialog */ public static JDialog newDialog(Component component) { return newDialog(null, component); } /** * Creates a new JDialog with default accept/cancel buttons * @param owner owner window * @param component component to show in * @return new crated dialog */ public static JDialog newDialog(Window owner, Component component) { return new SimpleDialog(owner, component); } /** * Creates empty border * @param size border size * @return empty border */ public static Border createEmptyBorder(int size) { return BorderFactory.createEmptyBorder(size, size, size, size); } /** * Create a box with an aligned component using Component constants for right, center and left. * @param c component * @param alignment aligment. * @return Box with compoenent */ public static Component newBoxForComponent(Component c, float alignment) { Box box = Box.createHorizontalBox(); if (Component.RIGHT_ALIGNMENT == alignment) { box.add(Box.createHorizontalGlue()); box.add(c); } else if (Component.CENTER_ALIGNMENT == alignment) { box.add(Box.createHorizontalGlue()); box.add(c); box.add(Box.createHorizontalGlue()); } else { // default to left box.add(c); box.add(Box.createHorizontalGlue()); } return box; } /** * Create a box with a coponent aligned to left. * @param c component * @return Box with the compoenent */ public static Component newBoxForComponent(Component c) { return newBoxForComponent(c, Component.LEFT_ALIGNMENT); } }