/* * RadioChooserDialog.java * Copyright James Dempsey, 2013 * * This library 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 2.1 of the License, or (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Created on 03/06/2013 * * $Id$ */ package pcgen.gui2.dialog; import java.awt.BorderLayout; import java.awt.Container; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.WindowConstants; import javax.swing.border.TitledBorder; import pcgen.facade.core.ChooserFacade; import pcgen.facade.core.InfoFacade; import pcgen.facade.util.ListFacade; import pcgen.gui2.tools.Utility; import pcgen.gui2.util.FontManipulation; import pcgen.system.LanguageBundle; /** * The Class {@code RadioChooserDialog} provides a dialog with a variable * number of radio buttons to allow the user to make a single choice from a * list. A ChooserFacade instance must be supplied, this defines the choices * available, the text to be displayed on screen and the actions to be taken * when the user confirms their choices. The chooser is generally displayed * via a call to UIDelgate.showGeneralChooser. * * <br> * @author James Dempsey <jdempsey@users.sourceforge.net> */ @SuppressWarnings("serial") public class RadioChooserDialog extends JDialog implements ActionListener { private final ChooserFacade chooser; private boolean committed; private ButtonGroup avaGroup = null; private JRadioButton[] avaRadioButton = null; private JPanel buttonPanel; private JRadioButton selectedButton; /** * Create a new instance of RadioChooserDialog for selecting from the data * supplied in the chooserFacade. * @param frame The window we are opening relative to. * @param chooser The definition of what should be displayed. */ public RadioChooserDialog(Frame frame, ChooserFacade chooser) { super(frame, true); this.chooser = chooser; initComponents(); pack(); } private void initComponents() { setTitle(LanguageBundle.getString("in_chooserSelectOne")); //$NON-NLS-1$ setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); Container pane = getContentPane(); pane.setLayout(new BorderLayout()); JLabel titleLabel = new JLabel(chooser.getName()); FontManipulation.title(titleLabel); titleLabel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10)); pane.add(titleLabel, BorderLayout.NORTH); buildButtonPanel(); pane.add(buttonPanel, BorderLayout.CENTER); JPanel bottomPane = new JPanel(new FlowLayout()); JButton button = new JButton(LanguageBundle.getString("in_ok")); //$NON-NLS-1$ button.setMnemonic(LanguageBundle.getMnemonic("in_mn_ok")); //$NON-NLS-1$ button.setActionCommand("OK"); button.addActionListener(this); bottomPane.add(button); button = new JButton(LanguageBundle.getString("in_cancel")); //$NON-NLS-1$ button.setMnemonic(LanguageBundle.getMnemonic("in_mn_cancel")); //$NON-NLS-1$ button.setActionCommand("CANCEL"); button.addActionListener(this); bottomPane.add(button); pane.add(bottomPane, BorderLayout.SOUTH); } /** * Create the panel of radio buttons. */ private void buildButtonPanel() { ListFacade<InfoFacade> availableList = chooser.getAvailableList(); int row = 0; avaRadioButton = new JRadioButton[availableList.getSize()]; avaGroup = new ButtonGroup(); // Create the buttons for (InfoFacade infoFacade : availableList) { avaRadioButton[row] = new JRadioButton(infoFacade.toString(), false); avaGroup.add(avaRadioButton[row]); avaRadioButton[row].addActionListener(this); ++row; } int numRows = row; if (numRows > 0) { avaRadioButton[0].setSelected(true); selectedButton = avaRadioButton[0]; } // Layout the buttons GridBagLayout gridbag = new GridBagLayout(); buttonPanel = new JPanel(); TitledBorder title = BorderFactory.createTitledBorder(null, ""); buttonPanel.setBorder(title); buttonPanel.setLayout(gridbag); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.HORIZONTAL; if (numRows > 11) { buildTwoColLayout(numRows, c, gridbag); } else { for (int i = 0; i < numRows; ++i) { int cr = i; c.anchor = GridBagConstraints.WEST; Utility.buildConstraints(c, 0, cr, 2, 1, 1, 0); gridbag.setConstraints(avaRadioButton[i], c); buttonPanel.add(avaRadioButton[i]); } } } /** * Build up tow columns of buttons arranged in column order e.g. 1-6 then 7-12 * @param numButtons The number of buttons to be placed. * @param c The GridBagConstraints for the panel. * @param gridbag The layout of the panel. */ private void buildTwoColLayout(int numButtons, GridBagConstraints c, GridBagLayout gridbag) { int numRows = numButtons - numButtons / 2; for (int i = 0; i < numRows; ++i) { int cr = i; c.anchor = GridBagConstraints.WEST; Utility.buildConstraints(c, 0, cr, 2, 1, 1, 0); gridbag.setConstraints(avaRadioButton[i], c); buttonPanel.add(avaRadioButton[i]); if (i + numRows < numButtons) { c.anchor = GridBagConstraints.EAST; Utility.buildConstraints(c, 3, cr, 2, 1, 1, 0); gridbag.setConstraints(avaRadioButton[i + numRows], c); buttonPanel.add(avaRadioButton[i + numRows]); } } } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof JRadioButton) { // A new radio button was selected - remember it selectedButton = (JRadioButton) e.getSource(); return; } if (e.getActionCommand().equals("OK")) { for (int i = 0; i < avaRadioButton.length; i++) { if (selectedButton == avaRadioButton[i]) { chooser.addSelected(chooser.getAvailableList() .getElementAt(i)); break; } } if (chooser.isRequireCompleteSelection() && chooser.getRemainingSelections().get() > 0) { JOptionPane.showMessageDialog(this, LanguageBundle .getFormattedString("in_chooserRequireComplete", //$NON-NLS-1$ chooser.getRemainingSelections().get()), chooser.getName(), JOptionPane.INFORMATION_MESSAGE); return; } else { chooser.commit(); } } else { chooser.rollback(); } committed = e.getActionCommand().equals("OK"); dispose(); } /** * Returns the means by which the dialog was closed. * @return the committed status, false for cancelled, true for OKed. */ public boolean isCommitted() { return committed; } }