/*
Copyright (C) 2006 EBI
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 itmplied 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
*/
package org.biomart.builder.view.gui.dialogs;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.biomart.builder.model.Relation.CompoundRelationDefinition;
import org.biomart.common.resources.Resources;
/**
* A dialog which allows the user to specify how many times a relation will be
* followed by the transformation process.
*
* @author Richard Holland <holland@ebi.ac.uk>
* @version $Revision: 1.14 $, $Date: 2007-08-21 15:19:54 $, modified by
* $Author: rh4 $
* @since 0.6
*/
public class CompoundRelationDialog extends JDialog {
private static final long serialVersionUID = 1;
private SpinnerNumberModel arity;
private JCheckBox parallel;
/**
* Pop up a dialog to define the arity of a relation.
*
* @param startvalue
* the initial preselected arity.
* @param title
* the title to give the dialog.
* @param label
* the title to give the arity selector.
* @param forceParallel
* <tt>true</tt> if parallelism is not optional.
* @param partitionOptions
* a list (possibly empty) of options available for attaching a
* partition table to this compound relation. Each option is a
* fully qualified partition column name.
*/
public CompoundRelationDialog(final CompoundRelationDefinition startvalue,
final String title, final String label,
final boolean forceParallel, final Collection partitionOptions) {
// Create the base dialog.
super();
this.setTitle(title);
this.setModal(true);
// Create the layout manager for this panel.
final JPanel content = new JPanel();
content.setLayout(new GridBagLayout());
this.setContentPane(content);
// Create constraints for fields that are not in the last row.
final GridBagConstraints fieldConstraints = new GridBagConstraints();
fieldConstraints.gridwidth = GridBagConstraints.REMAINDER;
fieldConstraints.fill = GridBagConstraints.NONE;
fieldConstraints.anchor = GridBagConstraints.LINE_START;
fieldConstraints.insets = new Insets(0, 2, 0, 0);
// Create constraints for fields that are in the last row.
final GridBagConstraints fieldLastRowConstraints = (GridBagConstraints) fieldConstraints
.clone();
fieldLastRowConstraints.gridheight = GridBagConstraints.REMAINDER;
// Set up the arity spinner field.
this.arity = new SpinnerNumberModel(startvalue.getN(), 1,
Integer.MAX_VALUE, 1);
final JSpinner spinner = new JSpinner(this.arity);
this.parallel = new JCheckBox(Resources.get("parallelLabel"));
// Set up the check box to turn it on and off.
final JCheckBox checkbox = new JCheckBox();
if (startvalue.getN() > 1)
checkbox.setSelected(true);
this.parallel.setSelected(startvalue.isParallel());
this.parallel.setEnabled(!forceParallel && startvalue.getN() > 1);
// The close and execute buttons.
final JButton close = new JButton(Resources.get("closeButton"));
final JButton execute = new JButton(Resources.get("updateButton"));
// Input fields.
JPanel field = new JPanel();
field.add(checkbox);
field.add(new JLabel(label));
field.add(spinner);
field.add(new JLabel(Resources.get("compoundRelationSpinnerLabel")));
content.add(field, fieldConstraints);
// Parallel button.
field = new JPanel();
field.add(this.parallel);
content.add(field, fieldConstraints);
// Close/Execute buttons at the bottom.
field = new JPanel();
field.add(close);
field.add(execute);
content.add(field, fieldLastRowConstraints);
// Intercept the spinner.
spinner.addChangeListener(new ChangeListener() {
public void stateChanged(final ChangeEvent e) {
if (CompoundRelationDialog.this.getArity() <= 1) {
checkbox.setSelected(false);
CompoundRelationDialog.this.parallel.setSelected(false);
CompoundRelationDialog.this.parallel.setEnabled(false);
} else {
checkbox.setSelected(true);
if (forceParallel)
CompoundRelationDialog.this.parallel.setSelected(true);
CompoundRelationDialog.this.parallel
.setEnabled(!forceParallel);
}
}
});
// Intercept the checkbox.
checkbox.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
if (!checkbox.isSelected())
CompoundRelationDialog.this.arity.setValue(new Integer(1));
}
});
// Intercept the close button, which closes the dialog
// without taking any action.
close.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
// Reset to default value.
CompoundRelationDialog.this.arity.setValue(new Integer(
startvalue.getN()));
CompoundRelationDialog.this.setVisible(false);
}
});
// Intercept the execute button, which validates the fields
// then closes the dialog.
execute.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
if (CompoundRelationDialog.this.validateFields())
CompoundRelationDialog.this.setVisible(false);
}
});
// Make execute the default button.
this.getRootPane().setDefaultButton(execute);
// Set size of window.
this.pack();
// Move ourselves.
this.setLocationRelativeTo(null);
}
/**
* Get the arity the user selected.
*
* @return the selected arity.
*/
public int getArity() {
return this.arity.getNumber().intValue();
}
/**
* If the user ticked the parallel relation box, indicating that this
* relation should be treated as a fork point, this will return
* <tt>true</tt>.
*
* @return <tt>true</tt> if the user ticked the parallel box.
*/
public boolean getParallel() {
return this.parallel.isSelected();
}
private boolean validateFields() {
// List of messages to display, if any are necessary.
final List messages = new ArrayList();
// Must enter something in the arity box.
if (this.arity.getNumber() == null)
messages.add(Resources.get("fieldIsEmpty", Resources.get("arity")));
// Any messages to display? Show them.
if (!messages.isEmpty())
JOptionPane.showMessageDialog(null,
messages.toArray(new String[0]), Resources
.get("validationTitle"),
JOptionPane.INFORMATION_MESSAGE);
// Validation succeeds if there are no messages.
return messages.isEmpty();
}
}