com.jidesoft.dialog.ButtonPanel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jide-oss Show documentation
Show all versions of jide-oss Show documentation
JIDE Common Layer (Professional Swing Components)
/*
* @(#)ButtonPanel.java
*
* Copyright 2002 - 2003 JIDE Software. All rights reserved.
*/
package com.jidesoft.dialog;
import com.jidesoft.plaf.LookAndFeelFactory;
import com.jidesoft.plaf.UIDefaultsLookup;
import com.jidesoft.swing.ArrowKeyNavigationSupport;
import javax.swing.*;
import java.awt.*;
/**
* ButtonPanel
can help to layout buttons easily in any dialogs.
*
* For more detail, please refer to JIDE Dialogs Developer Guide.
*/
public class ButtonPanel extends JPanel implements ButtonListener, ButtonNames {
private static final long serialVersionUID = -7840551457656712357L;
/**
* This option will make all buttons have the same size. If all buttons have the same size, the GUI will certainly
* look better.
*/
public static final int SAME_SIZE = 0;
/**
* This option will make all buttons no less than a certain size. The size is different on different platforms. We
* need this option because sometimes one button has a very long text. If all buttons have the same size, it will
* make the button panel extremely long. Even though they have the same size but will look out of balance. This
* option is not available if the buttons are arranged vertically.
*/
public static final int NO_LESS_THAN = 1;
/**
* Client property key. If this client property is set to Boolean.TRUE, the button panel will always use the
* component's preferred width instead of using minButtonWidth.
*/
public static final String KEEP_PREFERRED_WIDTH = "keepPreferredWidth";
/**
* The button will produce an affirmative action. Typical affirmative buttons are OK, Save, Print, Replace etc. It
* doesn't have to be positive either. For example, both Yes and No are affirmative action. This constant is used as
* constraint parameter in {@link #addButton(javax.swing.AbstractButton, Object)} method.
*/
public static final String AFFIRMATIVE_BUTTON = "AFFIRMATIVE";
/**
* The button will produce a cancel action. Typical cancel button is Cancel. This constant is used as constraint
* parameter in {@link #addButton(javax.swing.AbstractButton, Object)} method.
*/
public static final String CANCEL_BUTTON = "CANCEL";
/**
* The button will open some help windows. This constant is used as constraint parameter in {@link
* #addButton(javax.swing.AbstractButton, Object)} method.
*/
public static final String HELP_BUTTON = "HELP";
/**
* The button will produce an alternative action different neither an affirmative or cancel action. Typical
* alternative button is Don't Save comparing with Save as affirmative action and Cancel as cancel action. This
* constant is used as constraint parameter in {@link #addButton(javax.swing.AbstractButton, Object)} method.
*/
public static final String OTHER_BUTTON = "ALTERNATIVE";
private String _defaultOrder = UIDefaultsLookup.getString("ButtonPanel.order");
private String _defaultOppositeOrder = UIDefaultsLookup.getString("ButtonPanel.oppositeOrder");
private int _defaultButtonGap = UIDefaultsLookup.getInt("ButtonPanel.buttonGap");
private int _defaultGroupGap = UIDefaultsLookup.getInt("ButtonPanel.groupGap");
private int _defaultButtonWidth = UIDefaultsLookup.getInt("ButtonPanel.minButtonWidth");
private int _alignment;
private ButtonPanelLayout _layout;
/**
* Constructs a new ButtonPanel
with right alignment.
*/
public ButtonPanel() {
this(SwingConstants.TRAILING);
}
/**
* Constructs a new ButtonPanel
with the specified alignment.
*
* @param alignment the alignment. The supported alignment are {@link SwingConstants#RIGHT}, {@link
* SwingConstants#LEFT}, {@link SwingConstants#CENTER}, {@link SwingConstants#TOP} or {@link
* SwingConstants#BOTTOM}.
*/
public ButtonPanel(int alignment) {
this(alignment, SAME_SIZE);
}
/**
* Constructs a new ButtonPanel
with default horizontal spacing and the given alignment.
*
* @param alignment the alignment of the buttons. It can be one of SwingConstants.LEFT
or
* SwingConstants.RIGHT
or SwingConstants.TOP
or
* SwingConstants.BOTTOM
or SwingConstants.CENTER
.
* @param sizeConstrains size constraint of the button. It can be either SAME_SIZE
or
* NO_LESS_THAN
*/
public ButtonPanel(int alignment, int sizeConstrains) {
_alignment = alignment;
if (alignment != SwingConstants.LEFT && alignment != SwingConstants.RIGHT && alignment != SwingConstants.LEADING && alignment != SwingConstants.TRAILING
&& alignment != SwingConstants.TOP && alignment != SwingConstants.BOTTOM && alignment != SwingConstants.CENTER) {
throw new IllegalArgumentException("Invalid alignment");
}
int axis = (_alignment == SwingConstants.CENTER || _alignment == SwingConstants.LEFT || _alignment == SwingConstants.RIGHT || _alignment == SwingConstants.TRAILING || _alignment == SwingConstants.LEADING)
? ButtonPanelLayout.X_AXIS : ButtonPanelLayout.Y_AXIS;
_layout = new ButtonPanelLayout(this, axis, _alignment, sizeConstrains, _defaultOrder, _defaultOppositeOrder, _defaultButtonGap, _defaultGroupGap);
setLayout(_layout);
new ArrowKeyNavigationSupport(new Class[]{AbstractButton.class}).install(this);
}
@Override
public void updateUI() {
if (UIDefaultsLookup.get("ButtonPanel.buttonGap") == null
&& UIDefaultsLookup.get("ButtonPanel.order") == null
&& UIDefaultsLookup.get("ButtonPanel.groupGap") == null) {
LookAndFeelFactory.installJideExtension();
}
super.updateUI();
reinstallDefaults();
}
protected void reinstallDefaults() {
if (_layout != null) {
if (_defaultButtonGap == _layout.getButtonGap()) {
_defaultButtonGap = UIDefaultsLookup.getInt("ButtonPanel.buttonGap");
_layout.setButtonGap(_defaultButtonGap);
}
if (_defaultGroupGap == _layout.getGroupGap()) {
_defaultGroupGap = UIDefaultsLookup.getInt("ButtonPanel.groupGap");
_layout.setGroupGap(_defaultGroupGap);
}
if (_defaultOrder.equals(_layout.getButtonOrder())) {
_defaultOrder = UIDefaultsLookup.getString("ButtonPanel.order");
_layout.setButtonOrder(_defaultOrder);
}
if (_defaultOppositeOrder.equals(_layout.getOppositeButtonOrder())) {
_defaultOppositeOrder = UIDefaultsLookup.getString("ButtonPanel.oppositeOrder");
_layout.setOppositeButtonOrder(_defaultOppositeOrder);
}
if (_defaultButtonWidth == _layout.getMinButtonWidth()) {
_defaultButtonWidth = UIDefaultsLookup.getInt("ButtonPanel.minButtonWidth");
_layout.setMinButtonWidth(_defaultButtonWidth);
}
}
}
/**
* Sets the alignment. If the alignment is one of SwingConstants.CENTER, SwingConstants.LEFT, SwingConstants.RIGHT,
* SwingConstants.LEADING or SwingConstants.TRAILING, the buttons will be laid out horizontally. If the alignment is
* SwingConstants.TOP or SwingConstants.BOTTOM, the buttons will be laid out vertically.
*
* @param alignment the alignment. The supported alignment are {@link SwingConstants#RIGHT}, {@link
* SwingConstants#LEFT}, {@link SwingConstants#CENTER}, {@link SwingConstants#TOP} or {@link
* SwingConstants#BOTTOM}.
*/
public void setAlignment(int alignment) {
_alignment = alignment;
int axis = (_alignment == SwingConstants.CENTER || _alignment == SwingConstants.LEFT || _alignment == SwingConstants.RIGHT || _alignment == SwingConstants.LEADING || _alignment == SwingConstants.TRAILING)
? ButtonPanelLayout.X_AXIS : ButtonPanelLayout.Y_AXIS;
_layout.setAlignment(_alignment);
_layout.setAxis(axis);
_layout.layoutContainer(this);
}
/**
* Gets the alignment of the ButtonPanel.
*
* @return the alignment of the ButtonPanel.
*/
public int getAlignment() {
return _alignment;
}
/**
* Adds button to ButtonPanel as AFFIRMATIVE_BUTTON.
*
* @param button a button
*/
public void addButton(AbstractButton button) {
addButton(button, AFFIRMATIVE_BUTTON);
}
/**
* Adds button to ButtonPanel with specified type.
*
* @param button a button.
* @param index the position in the button panel's list at which to insert the component; -1 means insert at the
* end component
*/
public void addButton(AbstractButton button, int index) {
addButton(button, AFFIRMATIVE_BUTTON, index);
}
/**
* Adds button to ButtonPanel with specified constraint. The valid constraints are {@link #AFFIRMATIVE_BUTTON},
* {@link #CANCEL_BUTTON},{@link #OTHER_BUTTON} and {@link #HELP_BUTTON}. The main purpose of the constraints is to
* determine how the buttons are laid out on different platforms according to the OS convention. For example, on
* Windows, AFFIRMATIVE_BUTTON appears on the right hand side of CANCEL_BUTTON. On Mac OS X, AFFIRMATIVE_BUTTON will
* appear on the left hand side of CANCEL_BUTTON.
*
* @param button a button.
* @param constraint one of constraints.
*/
public void addButton(AbstractButton button, Object constraint) {
addButton(button, constraint, -1);
}
/**
* Adds button to ButtonPanel with specified type.
*
* @param button a button.
* @param constraint String of one of types.
* @param index the position in the button panel's list at which to insert the component; -1 means insert at
* the end component
*/
public void addButton(AbstractButton button, Object constraint, int index) {
add(button, constraint, index);
}
@Override
protected void addImpl(Component comp, Object constraints, int index) {
// TODO: if index is not 0, it could be a problem
if (constraints == null) {
constraints = AFFIRMATIVE_BUTTON;
}
super.addImpl(comp, constraints, index);
}
/**
* Removes the button. It's the same as {@link #remove(java.awt.Component)}.
*
* @param button a button
*/
public void removeButton(AbstractButton button) {
remove(button);
}
/**
* Gets the button order.
*
* @return the button order.
*/
public String getButtonOrder() {
return _layout.getButtonOrder();
}
/**
* Sets the button order.
*
* @param buttonOrder the new button order.
*/
public void setButtonOrder(String buttonOrder) {
_layout.setButtonOrder(buttonOrder);
}
/**
* Gets the opposite button order.
*
* @return the opposite button order.
*/
public String getOppositeButtonOrder() {
return _layout.getOppositeButtonOrder();
}
/**
* Sets the opposite button order.
*
* @param oppositeButtonOrder the new opposite button order.
*/
public void setOppositeButtonOrder(String oppositeButtonOrder) {
_layout.setOppositeButtonOrder(oppositeButtonOrder);
}
/**
* Gets the size constraint.
*
* @return the size constraint.
*/
public int getSizeConstraint() {
return _layout.getSizeConstraint();
}
/**
* Sets the size constraint. Valid values are {@link #NO_LESS_THAN} and {@link #SAME_SIZE}. The size constraint will
* apply to all components except if the component client property {@link ButtonPanel#KEEP_PREFERRED_WIDTH} is set
* to Boolean.TRUE.
*
* @param sizeConstrains the size constraint.
*/
public void setSizeConstraint(int sizeConstrains) {
_layout.setSizeConstraint(sizeConstrains);
}
/**
* Gets the gap between two button groups.
*
* @return the gap between two button groups.
*/
public int getGroupGap() {
return _layout.getGroupGap();
}
/**
* Sets the gap between two button groups.
*
* @param groupGap the gap between button groups.
*/
public void setGroupGap(int groupGap) {
_layout.setGroupGap(groupGap);
}
/**
* Gets the gap between two buttons in the same group.
*
* @return the gap between two buttons in the same group.
*/
public int getButtonGap() {
return _layout.getButtonGap();
}
/**
* Sets the gap between two buttons in the same group.
*
* @param buttonGap the gap between buttons.
*/
public void setButtonGap(int buttonGap) {
_layout.setButtonGap(buttonGap);
}
/**
* Gets the minimum button width.
*
* @return the minimum button width.
*/
public int getMinButtonWidth() {
return _layout.getMinButtonWidth();
}
/**
* Sets the minimum button width.
*
* @param minButtonWidth the minimum button width.
*/
public void setMinButtonWidth(int minButtonWidth) {
_layout.setMinButtonWidth(minButtonWidth);
}
public void buttonEventFired(ButtonEvent e) {
if (e.getID() == ButtonEvent.CLEAR_DEFAULT_BUTTON) {
JRootPane rootPane = getRootPane();
if (rootPane != null && rootPane.getDefaultButton() != null) {
rootPane.setDefaultButton(null);
}
}
else {
for (int i = 0; i < getComponentCount(); i++) {
final Component component = getComponent(i);
if (e.getButtonName().equals(component.getName())) {
switch (e.getID()) {
case ButtonEvent.ENABLE_BUTTON:
component.setVisible(true);
if (component instanceof JButton && ((JButton) component).getAction() != null) {
((JButton) component).getAction().setEnabled(true);
}
component.setEnabled(true);
break;
case ButtonEvent.DISABLE_BUTTON:
component.setEnabled(false);
if (component instanceof JButton && ((JButton) component).getAction() != null) {
((JButton) component).getAction().setEnabled(false);
}
component.setVisible(true);
break;
case ButtonEvent.SHOW_BUTTON:
component.setVisible(true);
break;
case ButtonEvent.HIDE_BUTTON:
component.setVisible(false);
JRootPane rootPane = getRootPane();
if (rootPane != null && rootPane.getDefaultButton() == component) {
rootPane.setDefaultButton(null);
}
// to clear the initialDefaultButton in root pane
if (rootPane != null && rootPane.getClientProperty("initialDefaultButton") == component) {
rootPane.putClientProperty("initialDefaultButton", null);
}
break;
case ButtonEvent.CHANGE_BUTTON_TEXT:
if (component instanceof AbstractButton) {
((AbstractButton) component).setText(e.getUserObject());
}
break;
case ButtonEvent.CHANGE_BUTTON_MNEMONIC:
if (component instanceof AbstractButton) {
((AbstractButton) component).setMnemonic(e.getUserObject().charAt(0));
}
break;
case ButtonEvent.CHANGE_BUTTON_TOOLTIP:
if (component instanceof AbstractButton) {
((AbstractButton) component).setToolTipText(e.getUserObject());
}
break;
case ButtonEvent.CHANGE_BUTTON_FOCUS:
Runnable runnable = new Runnable() {
public void run() {
component.requestFocus();
}
};
SwingUtilities.invokeLater(runnable);
break;
case ButtonEvent.SET_DEFAULT_BUTTON:
if (component instanceof JButton) {
if (getRootPane() != null) {
getRootPane().setDefaultButton(((JButton) component));
}
else {
_defaultButton = (JButton) component;
_addNotify = true;
}
}
break;
}
break;
}
}
}
}
private boolean _addNotify = false;
private JButton _defaultButton;
@Override
public void addNotify() {
super.addNotify();
if (_addNotify) {
JRootPane pane = getRootPane();
if (_defaultButton != null && pane != null) {
pane.setDefaultButton(_defaultButton);
_addNotify = false;
_defaultButton = null;
}
}
}
/**
* Gets the button with the name. In order to use this method, you have to set a name to the button using {@link
* AbstractButton#setName(String)} method. Please note, the name is not the same as the constraint in the second
* parameter of {@link #add(java.awt.Component, Object)}.
*
* @param name the button name.
* @return the button which has the name. null if there is no button with that name.
*
* @throws IllegalArgumentException if the name is null or empty.
*/
public Component getButtonByName(String name) {
if (name == null || name.trim().length() == 0) {
throw new IllegalArgumentException("name cannot be null or empty");
}
for (int i = 0; i < getComponentCount(); i++) {
Component component = getComponent(i);
if (name.equals(component.getName())) {
return component;
}
}
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy