//===================================================================== // File: BinDialog.java // Class: BinDialog // Package: AFLPgui // // Author: James J. Benham // Date: August 11, 1998 // Contact: james_benham@hmc.edu // // Genographer v1.0 - Computer assisted scoring of gels. // Copyright (C) 1998 Montana State University // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; version 2 // of the License. // // This program 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // The GNU General Public License is distributed in the file GPL //===================================================================== package AFLPgui; import java.awt.Button; import java.awt.Checkbox; import java.awt.Choice; import java.awt.Dialog; import java.awt.Frame; import java.awt.Label; import java.awt.List; import java.awt.TextField; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import AFLPcore.Bin; import AFLPcore.DataList; import AFLPcore.FeatureList; import AFLPcore.Option; import AFLPcore.ProgOptions; import AFLPcore.ScoreFunction; import AFLPcore.ScoreManager; /** * This is a dialog box that shows a list of bins. It will allow the * user to add new bins, delete a bin, delete all of the bins, and change * the parameters of a bin: the location, range, and scoring method. * The user can change the scoring method for all of the bins at once. * Changes are stored in a seperate list, and are saved only when the "Ok" * button is clicked. Most errors are caught and then sent to a dialog * box to be displayed. The name of the bin displayed in the list depends * on whether or not the bin has a name defined. If it does, that name will * be used. Otherwise, the displayed name is simply the location of the bin. * Methods are provided to both load a bin into the display portion of the * dialog box and to save the display to a bin. * * @author James J. Benham * @version 1.0.0 * @date August 11, 1998 */ public class BinDialog extends Dialog implements ActionListener, ItemListener, KeyListener, WindowListener { private static final String HELP_FILE = "binhelp.html"; private static int WIDTH = 444; private static int HEIGHT = 240; // List box parameters private static int LIST_H_INSET = 10; private static int LIST_V_INSET = 30; private static int LIST_WIDTH = 90; private static int LIST_HEIGHT = 200; // Field parameters private static int V_SPACE = 10; private static int H_SPACE = 4; private static int COMP_HEIGHT = 25; private static int COMP_H_INSET = 110; private static int LABEL_WIDTH = 80; private static int FIELD_WIDTH = 80; private static int CHOICE_WIDTH = 150; // Button parameters private static int BUTTON_WIDTH = 80; private static int ENTER_WIDTH = 120; private static int SCORE_WIDTH = 110; private static int BUTTON_H_INSET = 354; // Check Box parameter private static int CHECK_INSET = 5; private static int CHECK_WIDTH = 200; private Button okButton; private Button cancelButton; private Button newButton; private Button deleteButton; private Button delAllButton; private Button helpButton; private Button enterButton; private Button scoreOptionButton; private Checkbox scoreAllCheck; private List binList; private Choice scoreChoice; private TextField nameField; private TextField locationField; private TextField rangeField; private DataList bins; private DataList savedBins; private Bin currentBin; private int index; private boolean allMode; private String scoreNames[]; private ScoreFunction scoreFn; private Frame parent; /** * Create a new Bin Dialog with the specified parameters. * * @param parent the owner of this dialog box * @param title the title of the dialog box * @param modal if true, dialog blocks input to the parent window * when shown */ public BinDialog(Frame parent, String title, boolean modal) { super(parent, title, modal); this.parent = parent; bins = new DataList(); currentBin = null; index = -1; addWindowListener(this); componentLayout(); loadSelection(index); } /** * The bins to display. Each bin will be given a display name. This * will be the name of the bin itself if it is defined, or it will * simply be the bin's location. * * @param bins the list of bins to dispaly in the dialog box. */ public void setBins(DataList bins) { savedBins = bins; this.bins = bins.completeClone(); // Add the bins to the list Bin temp; binList.removeAll(); for(int i=0; i < this.bins.size(); i++) { temp = (Bin) this.bins.dataAt(i); if(temp.getName().equals("")) binList.add("" + temp.getLocation()); else binList.add(temp.getName()); } } /** * Handles all of the action event, which come mostly from the * buttons in the dialog box. To see how each button is handled, * please see the source. */ public void actionPerformed(ActionEvent e) { try{ if(e.getSource() == okButton) { bins.copyList(savedBins); // store the changes dispose(); setVisible(false); } else if(e.getSource() == enterButton) { storeInfo(index); } else if(e.getSource() == cancelButton) { bins = savedBins; // dispose of changes dispose(); setVisible(false); } else if(e.getSource() == newButton) { index = -1; binList.select(index); loadSelection(index); } else if(e.getSource() == deleteButton) { if(index != -1) { binList.remove(index); bins.removeElementAt(index); index = -1; loadSelection(index); } } else if(e.getSource() == delAllButton) { bins = new DataList(); binList.removeAll(); index = -1; loadSelection(index); } else if(e.getSource() == helpButton) { ProgOptions.showHelp(HELP_FILE); } else if(e.getSource() == scoreOptionButton) { OptionDialog optDialog = new OptionDialog(scoreFn.getOptions(), (Frame) getParent(), scoreFn.getName() + " Parameters"); optDialog.setVisible(true); if(!optDialog.isCanceled()) { Option[] opts = optDialog.getOptions(); scoreFn.setOptions(opts); } } } catch(Throwable error) { ErrorDialog eD = new ErrorDialog((Frame) getParent()); eD.showError(error); } } /** * This handles events generated when the list is manipulated or when * the check box is changed. It also handles the event when the * scoring method is changed. */ public void itemStateChanged(ItemEvent e) { if(e.getSource() == binList) { // get the selected item index = binList.getSelectedIndex(); loadSelection(index); } else if(e.getSource() == scoreAllCheck) { allMode = scoreAllCheck.getState(); if(allMode) { nameField.setText("----------------"); nameField.setEditable(false); locationField.setText("----------------"); locationField.setEditable(false); rangeField.setText("----------------"); rangeField.setEditable(false); binList.setMultipleMode(true); binList.setVisible(false); for(int i=0; i < bins.size(); i++) binList.select(i); binList.setVisible(true); binList.setEnabled(false); } else { nameField.setEditable(true); locationField.setEditable(true); rangeField.setEditable(true); binList.setMultipleMode(false); binList.setEnabled(true); binList.select(index); loadSelection(index); } } else if(e.getSource() == scoreChoice) { String value = scoreChoice.getSelectedItem(); scoreFn = (ScoreFunction) FeatureList.getScoreMgr().get(value); scoreFn = (ScoreFunction) scoreFn.clone(); } } /** * This is used to cause the dialog box to store changes made when * the Enter key is pushed in one of the fields. */ public void keyReleased(KeyEvent e) { // Assume that a release of the enter key constitutes the typing // of the enter key. It is very unlikely that it got pushed down // somewhere else and released here. // There are only three listeners, so enter the values if the enter // key is pushed if (e.getKeyCode() == KeyEvent.VK_ENTER) storeInfo(index); } /** * Allows the window to close and has the same affect as pressing the * cancel button. None of the changes are saved. */ public void windowClosing(WindowEvent e) { bins = savedBins; // dispose of changes dispose(); setVisible(false); } /** * Displays the specified bin in the dialog box. If the index * is -1, then a blank display is created. * * @param index the index of the bin in the list of bins. * * @see BinDialog#setBins */ private void loadSelection(int index) { if(index != -1) { // retrieve the bin currentBin = (Bin) bins.dataAt(index); // update the displays nameField.setText(currentBin.getName()); locationField.setText("" + currentBin.getLocation()); rangeField.setText("" + currentBin.getRange()); scoreFn = currentBin.getScoreMethod(); scoreChoice.select(scoreFn.getName()); } else { currentBin = null; nameField.setText(""); locationField.setText(""); rangeField.setText(""); scoreFn = (ScoreFunction) FeatureList.getScoreMgr().getDefault(); scoreChoice.select(FeatureList.getScoreMgr().getDefaultName()); } } /** * This will read in the values from the display and store them * appropriatly. If the index is -1, then a new bin will * be created and added to the list. Otherwise, the values will be read * in and stored in the currently selected bin. If the check box for * changing all of the scoring methods is selected, then only the * score method will be stored, but it will be stored in all of the bins. * * @param index the index of the bin in the bin list, -1 for a new bin * * @exception NumberFormatException occurs if this method cannot read in * a number from one of the text boxes. */ public void storeInfo(int index) throws NumberFormatException { String scoreName; ScoreManager mgr = FeatureList.getScoreMgr(); if(!allMode) { // Read the values from the fields String name = nameField.getText(); double location = 0; double range = 0; try{ location = (new Double(locationField.getText())).doubleValue(); range = (new Double(rangeField.getText())).doubleValue(); } catch(NumberFormatException e) { throw new NumberFormatException("Location and Range must be" + " numbers."); } // Check to see if we should display the name or the size. String displayName; if(name.equals("")) displayName = "" + location; else displayName = name; if(index != -1) { // simply modifiy the current bin and update the name in the list currentBin.setName(name); currentBin.setLocation(location); currentBin.setRange(range); scoreName = scoreChoice.getSelectedItem(); currentBin.setScoreMethod(scoreFn); binList.replaceItem(displayName, index); binList.select(index); } else { // We have a new bin, so it must be created and then added to the // list. Find the location of the bin and insert it there in the // screen list currentBin = new Bin(location, range); currentBin.setName(name); currentBin.setScoreMethod((ScoreFunction) mgr.getDefault()); bins.include(currentBin); index = (bins.find(location)).location; binList.add(displayName, index); binList.select(index); } } else { // change the scoring method for all of the bins. for(int i=0; i < bins.size(); i++) { scoreFn = (ScoreFunction) scoreFn.clone(); ((Bin) bins.dataAt(i)).setScoreMethod(scoreFn); } } } /** * Controls wether or not the dialog box is visible. It it is * true, then a new blank selection will be loaded. * * @param b the visibility state of the dialog box. */ public void setVisible(boolean b) { super.setVisible(b); if(b) { // show blank fields and no selection index = -1; loadSelection(index); } } /** * Adds all of the components to the dialog box and adds the * appropriate listeners as well. */ private void componentLayout() { int startY = 0; setLayout(null); setSize(WIDTH, HEIGHT); setResizable(false); //====================Add the list================== binList = new List(); add(binList); binList.setBounds(LIST_H_INSET, LIST_V_INSET, LIST_WIDTH, LIST_HEIGHT); binList.addItemListener(this); //====================Add name stuff================= Label nameL = new Label("Name:", Label.LEFT); nameField = new TextField(); add(nameL); add(nameField); nameL.setBounds(COMP_H_INSET, LIST_V_INSET, LABEL_WIDTH, COMP_HEIGHT); nameField.setBounds(COMP_H_INSET + H_SPACE + LABEL_WIDTH, LIST_V_INSET, FIELD_WIDTH, COMP_HEIGHT); nameField.addKeyListener(this); startY += LIST_V_INSET + V_SPACE + COMP_HEIGHT; //===================Add location stuff================== Label locationL = new Label("Location:", Label.LEFT); locationField = new TextField(); add(locationL); add(locationField); locationL.setBounds(COMP_H_INSET, startY, LABEL_WIDTH, COMP_HEIGHT); locationField.setBounds(COMP_H_INSET + H_SPACE + LABEL_WIDTH, startY, FIELD_WIDTH, COMP_HEIGHT); locationField.addKeyListener(this); startY += V_SPACE + COMP_HEIGHT; //===================Add range stuff================== Label rangeL = new Label("Range:", Label.LEFT); rangeField = new TextField(); add(rangeL); add(rangeField); rangeL.setBounds(COMP_H_INSET, startY, LABEL_WIDTH, COMP_HEIGHT); rangeField.setBounds(COMP_H_INSET + H_SPACE + LABEL_WIDTH, startY, FIELD_WIDTH, COMP_HEIGHT); rangeField.addKeyListener(this); startY += V_SPACE + COMP_HEIGHT; //===================Add score stuff================== Label scoreL = new Label("Score Using:", Label.LEFT); scoreChoice = new Choice(); add(scoreL); add(scoreChoice); scoreL.setBounds(COMP_H_INSET, startY, LABEL_WIDTH, COMP_HEIGHT); scoreChoice.setBounds(COMP_H_INSET + H_SPACE + LABEL_WIDTH, startY, CHOICE_WIDTH, COMP_HEIGHT); // add the choices scoreNames = FeatureList.getScoreMgr().getNames(); for(int i=0; i < scoreNames.length; i++) scoreChoice.add(scoreNames[i]); scoreChoice.select(FeatureList.getScoreMgr().getDefaultName()); scoreChoice.addItemListener(this); startY += V_SPACE + COMP_HEIGHT; //====================Add Score Check Box====================== scoreAllCheck = new Checkbox("Score all using this method", false); add(scoreAllCheck); scoreAllCheck.setBounds(COMP_H_INSET + CHECK_INSET, startY, CHECK_WIDTH, COMP_HEIGHT); scoreAllCheck.addItemListener(this); startY += V_SPACE + COMP_HEIGHT; //====================Add buttons====================== enterButton = new Button("Enter Changes"); add(enterButton); enterButton.setBounds(COMP_H_INSET, startY, ENTER_WIDTH, COMP_HEIGHT); enterButton.addActionListener(this); scoreOptionButton = new Button("Scoring Options"); add(scoreOptionButton); scoreOptionButton.setBounds(COMP_H_INSET + H_SPACE + ENTER_WIDTH, startY, SCORE_WIDTH, COMP_HEIGHT); scoreOptionButton.addActionListener(this); startY += V_SPACE + COMP_HEIGHT; startY = LIST_V_INSET; okButton = new Button("Ok"); add(okButton); okButton.setBounds(BUTTON_H_INSET, startY, BUTTON_WIDTH, COMP_HEIGHT); okButton.addActionListener(this); startY += V_SPACE + COMP_HEIGHT; cancelButton = new Button("Cancel"); add(cancelButton); cancelButton.setBounds(BUTTON_H_INSET, startY, BUTTON_WIDTH, COMP_HEIGHT); cancelButton.addActionListener(this); startY += V_SPACE + COMP_HEIGHT; newButton = new Button("New"); add(newButton); newButton.setBounds(BUTTON_H_INSET, startY, BUTTON_WIDTH, COMP_HEIGHT); newButton.addActionListener(this); startY += V_SPACE + COMP_HEIGHT; deleteButton = new Button("Delete"); add(deleteButton); deleteButton.setBounds(BUTTON_H_INSET, startY, BUTTON_WIDTH, COMP_HEIGHT); deleteButton.addActionListener(this); startY += V_SPACE + COMP_HEIGHT; delAllButton = new Button("Delete All"); add(delAllButton); delAllButton.setBounds(BUTTON_H_INSET, startY, BUTTON_WIDTH, COMP_HEIGHT); delAllButton.addActionListener(this); startY += V_SPACE + COMP_HEIGHT; helpButton = new Button("Help"); add(helpButton); helpButton.setBounds(BUTTON_H_INSET, startY, BUTTON_WIDTH, COMP_HEIGHT); helpButton.addActionListener(this); startY += V_SPACE + COMP_HEIGHT; } // ==================Unused methods required by interfaces================= /**Unused*/ public void keyPressed(KeyEvent e) {} /**Unused*/ public void keyTyped(KeyEvent e) {} /**Unused*/ public void windowOpened(WindowEvent e) {} /**Unused*/ public void windowClosed(WindowEvent e) {} /**Unused*/ public void windowIconified(WindowEvent e) {} /**Unused*/ public void windowDeiconified(WindowEvent e) {} /**Unused*/ public void windowActivated(WindowEvent e) {} /**Unused*/ public void windowDeactivated(WindowEvent e) {} }