/* * Copyright (c) 2005-2016 Vincent Vandenschrick. All rights reserved. * * This file is part of the Jspresso framework. * * Jspresso 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. * * Jspresso 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Jspresso. If not, see <http://www.gnu.org/licenses/>. */ package org.jspresso.framework.gui.swing.components; import java.awt.Color; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.KeyEvent; import java.util.List; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.KeyStroke; import javax.swing.border.BevelBorder; import org.jspresso.framework.util.lang.ObjectUtils; import org.jspresso.framework.util.swing.SwingUtil; /** * A swing component to represent an actionable field. It should behave like a * button except that the action is parametrized by the field text value. This * component is represented by a text field and a button. Actioning the button * or the text field triggers the action. * * @author Vincent Vandenschrick */ public class JActionField extends JPanel { private static final long serialVersionUID = 5741890319182521808L; private final JPanel buttonPanel; private final boolean showTextField; private final JTextField textField; private List<Action> actions; private String value; private boolean fieldEditable; /** * Constructs a new {@code JActionField} instance. * * @param showTextField * is the text field visible to the user. */ public JActionField(boolean showTextField) { textField = new JTextField(); textField.getDocument().putProperty("filterNewlines", Boolean.FALSE); setLayout(new GridBagLayout()); if (showTextField) { add(textField, new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); super.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { textField.requestFocusInWindow(); } }); SwingUtil.enableSelectionOnFocusGained(textField); } this.showTextField = showTextField; buttonPanel = new JPanel(); buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS)); int buttonPosition; if (showTextField) { buttonPosition = 1; } else { buttonPosition = 0; } add(buttonPanel, new GridBagConstraints(buttonPosition, 0, 1, 1, 0, 1, GridBagConstraints.WEST, GridBagConstraints.VERTICAL, new Insets(0, 0, 0, 0), 0, 0)); fieldEditable = true; } /** * Adds a focus listener to the text field. * * @param l * the listener to add. */ public void addTextFieldFocusListener(FocusListener l) { textField.addFocusListener(l); } /** * Gets the actions. * * @return the actions. */ public List<Action> getActions() { return actions; } /** * Gets the action field text. * * @return the action field text. */ public String getActionText() { return textField.getText(); } /** * Gets the value. * * @return the value. */ public Object getValue() { return value; } /** * Gets the showTextField. * * @return the showTextField. */ public boolean isShowingTextField() { return showTextField; } /** * Gets whether this action field text is synchronized with its underlying * value. * * @return true if this action field text is synchronized with its underlying * value. */ public boolean isSynchronized() { return ObjectUtils.equals(value, textField.getText()); } /** * performs the registered action programmatically. */ public void performAction() { textField.getAction().actionPerformed( new ActionEvent(this, 0, getActionText())); } /** * Removes a focus listener from the text field. * * @param l * the listener to remove. */ public void removeTextFieldFocusListener(FocusListener l) { textField.removeFocusListener(l); } /** * Delegates to textField. */ public void selectAll() { textField.selectAll(); } /** * Sets the action field action. * * @param actions * the action field actions. */ public void setActions(List<Action> actions) { if (!ObjectUtils.equals(this.actions, actions)) { buttonPanel.removeAll(); this.actions = actions; for (Action action : actions) { JButton actionButton = new JButton(); SwingUtil.configureButton(actionButton); actionButton.setBackground(textField.getBackground()); actionButton.setAction(action); actionButton.setActionCommand("*"); actionButton.setText(""); int buttonSquareSize; if (showTextField) { buttonSquareSize = textField.getPreferredSize().height; if (textField.getAction() == null) { textField.setAction(action); } } else { buttonSquareSize = actionButton.getPreferredSize().height; } actionButton.setPreferredSize(new Dimension(buttonSquareSize, buttonSquareSize)); actionButton.setMinimumSize(actionButton.getPreferredSize()); actionButton.setMaximumSize(actionButton.getPreferredSize()); buttonPanel.add(actionButton); } } } /** * Gets the action field text. * * @param actionText * the action field text. */ public void setActionText(String actionText) { textField.setText(actionText); } /** * Decorates the component with a marker. * * @param decorated * if the component should be decorated. */ public void setDecorated(boolean decorated) { if (decorated) { buttonPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED, Color.RED.brighter(), Color.RED.darker())); } else { buttonPanel.setBorder(null); } } /** * Turns the action field to be editable or not. * * @param enabled * true if enabled. */ @Override public void setEnabled(boolean enabled) { if (textField.getAction() != null) { textField.getAction().setEnabled(enabled); } textField.setEditable(enabled && fieldEditable); } /** * Sets the value. * * @param value * the value to set. */ public void setValue(String value) { this.value = value; textField.setText(value); } /** * {@inheritDoc} */ @Override protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) { if (super.processKeyBinding(ks, e, condition, pressed)) { return true; } Object binding = textField.getInputMap(condition).get(ks); if (binding != null && textField.getActionMap().get(binding) != null) { textField.dispatchEvent(e); return true; } return false; } /** * Sets field editable. * * @param fieldEditable the field editable */ public void setFieldEditable(boolean fieldEditable) { this.fieldEditable = fieldEditable; textField.setEditable(isEnabled() && fieldEditable); } /** * Gets the text field in this action field. * * @return the text field */ public JTextField getTextField() { return textField; } }