/*
Copyright (c) 2009 The Regents of the University of California.
All rights reserved.
Permission is hereby granted, without written agreement and without
license or royalty fees, to use, copy, modify, and distribute this
software and its documentation for any purpose, provided that the above
copyright notice and the following two paragraphs appear in all copies
of this software.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY OLIGOY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A OLIGOICULAR PURPOSE. THE SOFTWARE
PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
ENHANCEMENTS, OR MODIFICATIONS..
*/
/*
* spreaditOligos.java
*
* Created on Aug 4, 2010, 9:03:45 AM
*/
package org.clothocad.tool.spreaditoligos;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.prefs.Preferences;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import org.clothocore.api.core.Collector;
import org.clothocore.api.data.Collection;
import org.clothocore.api.data.NucSeq;
import org.clothocore.api.data.ObjBase;
import org.clothocore.api.data.ObjLink;
import org.clothocore.api.data.ObjType;
import org.clothocore.api.data.Oligo;
import org.clothocore.api.data.Person;
import org.clothocore.api.data.Plasmid;
import org.clothocore.api.data.Vector;
import org.clothocore.api.dnd.ObjBaseObserver;
import org.clothocore.api.dnd.RefreshEvent;
import org.clothocore.api.dnd.RefreshEvent.Condition;
import org.clothocore.api.plugin.ClothoConnection;
import org.clothocore.api.plugin.ClothoConnection.ClothoQuery;
import org.clothocore.util.basic.ImageSource;
import org.clothocore.util.basic.ObjBasePopup;
import org.clothocore.util.buttons.TransparentButton;
import org.jdesktop.swingx.JXTable;
/**
*
* @author J. Christopher Anderson
*/
public class spreaditOligos extends javax.swing.JFrame {
/** Creates new changeFormat spreaditOligos */
public spreaditOligos(Collection coll) {
super("Spreadit Oligos: " + getStringName(coll));
setIconImage(ImageSource.getTinyLogo());
_prefs = Preferences.userNodeForPackage(spreaditOligos.class);
_Collection = coll;
refreshOBO = new refresher();
_Collection.isRepresentedBy(refreshOBO, this);
new ObjBasePopup(getContentPane(), _Collection);
_title = new String[] { "Nickname", "Short Description", "Sequence", "Author", "Keywords"};
initComponents();
//prefs
int wide = _prefs.getInt("spreaditOligosWidth", 600);
int high = _prefs.getInt("spreaditOligosHeight", 650);
setSize(wide,high);
setVisible(true);
ExcelAdapter myAd = new ExcelAdapter(table);
new Thread() {
@Override
public void run() {
parseOligos();
//prefs
setWidths();
}
}.start();
}
private static String getStringName(Collection c) {
if(c!=null) {
return c.getName();
} else {
return "Error";
}
}
//prefs
private void setWidths() {
final List<TableColumn> cols = table.getColumns();
for(int i=0; i<cols.size(); i++) {
final int wide = _prefs.getInt("spreaditOligosColumn" + i, cols.get(i).getWidth());
final TableColumn tc = cols.get(i);
columnWidths[i] = wide;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println("Setting " + tc + " to " + wide);
tc.setPreferredWidth(wide);
}
});
}
}
private class refresher implements ObjBaseObserver {
@Override
public void update(ObjBase obj, RefreshEvent evt) {
if(obj==null) {
dispose();
}
new Thread() {
@Override
public void run() {
parseOligos();
}
}.start();
}
}
private void parseOligos() {
new SwingWorker() {
@Override
protected Object doInBackground() throws Exception {
ArrayList<Oligo> inlist = (ArrayList<Oligo>) _Collection.getAll(ObjType.OLIGO);
allOligos = sortList(inlist);
_data = new String [allOligos.size()][5];
return null;
}
@Override
public void done() {
edtRelay();
}
}.execute();
}
private void edtRelay() {
final DefaultTableModel tableModel = new DefaultTableModel(_data, _title) { };
table.setModel(tableModel);
System.out.println(allOligos.size());
obrlist.clear();
for(int i=0; i<allOligos.size(); i++ ) {
final Oligo currOligo = allOligos.get(i);
if(currOligo==null) {
continue;
}
final int index = i;
ObjBaseObserver obr = new ObjBaseObserver() {
@Override
public void update(ObjBase obj, final RefreshEvent evt) {
if(obj==null) {
return;
}
refreshValues((Oligo) obj, evt);
}
};
obrlist.add(obr);
currOligo.isObservedBy(obr);
obr.update(currOligo, new RefreshEvent(currOligo, Condition.UNKNOWN));
ObjBaseObserver nucobr = new ObjBaseObserver() {
@Override
public void update(ObjBase obj, final RefreshEvent evt) {
if(obj==null) {
return;
}
if(evt.isCondition(Condition.SEQUENCE_CHANGED)) {
table.setValueAt(((NucSeq) obj).toString(), index, 2);
}
}
};
obrlist.add(nucobr);
currOligo.getSeq().isObservedBy(nucobr);
nucobr.update(currOligo.getSeq(), new RefreshEvent(currOligo.getSeq(), Condition.SEQUENCE_CHANGED));
isInitiated = true;
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
table.getModel().addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
Oligo changedOligo = allOligos.get(e.getFirstRow());
processOligoChange(changedOligo, e.getFirstRow(), e.getColumn(), (String) tableModel.getValueAt(e.getFirstRow(), e.getColumn()));
}
});
table.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed( MouseEvent e ) {
if(e.getModifiers()==4) {
if(table.getSelectedRows().length>1) {
return;
}
int index = table.getSelectedRow();
final Oligo aOligo = allOligos.get(index);
ObjBasePopup obp = new ObjBasePopup(table, aOligo, e.getPoint());
obp.addMenuItem("Remove from Collection", new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
_Collection.removeItem(aOligo);
}
});
}
}
});
}
});
}
private void refreshValues(Oligo currOligo, RefreshEvent evt) {
int index = allOligos.indexOf(currOligo);
table.setValueAt(currOligo.getName(), index, 0);
table.setValueAt(currOligo.getDescription(), index, 1);
table.setValueAt(currOligo.getAuthor().getName(), index, 3);
if(evt.isCondition(Condition.UNKNOWN)
|| evt.isCondition(Condition.SEARCHTAG_ADDED)
|| evt.isCondition(Condition.SEARCHTAG_REMOVED)) {
table.setValueAt(writeKeywords(currOligo), index, 4);
}
}
private class headerListener extends MouseAdapter {
@Override
public void mouseClicked(MouseEvent e) {
JTableHeader h = (JTableHeader) e.getSource();
TableColumnModel columnModel = h.getColumnModel();
int viewColumn = h.columnAtPoint(e.getPoint());
int column = columnModel.getColumn(viewColumn).getModelIndex();
if (column != -1) {
sortBy sortmode;
switch(column) {
case 0:
sortmode = sortBy.NAME;
break;
case 1:
sortmode = sortBy.DESCRIPTION;
break;
case 2:
sortmode = sortBy.SEQUENCE;
break;
case 3:
sortmode = sortBy.AUTHOR;
break;
default:
return;
}
if(sortmode.equals(sortByChoice)) {
reverseit = !reverseit;
} else {
reverseit = false;
}
setSortMode(sortmode);
}
}
}
public void setSortMode(sortBy choice) {
sortByChoice = choice;
parseOligos();
}
private ArrayList<Oligo> sortList(ArrayList<Oligo> inlist) {
ArrayList<Oligo> out = new ArrayList<Oligo>();
Comparator comparator = new Comparator() {
@Override
public int compare( Object o1, Object o2 ) {
Oligo oligo1 = (Oligo) o1;
Oligo oligo2 = (Oligo) o2;
switch(sortByChoice) {
case NAME:
String i1 = oligo1.getName();
String i2 = oligo2.getName();
if ( reverseit ) {
return i2.compareTo( i1 );
} else {
return i1.compareTo( i2 );
}
case DESCRIPTION:
String s1 = oligo1.getDescription();
String s2 = oligo2.getDescription();
if ( reverseit ) {
return s2.compareTo( s1 );
} else {
return s1.compareTo( s2 );
}
case SEQUENCE:
String os1 = oligo1.getSeq().getSeq();
String os2 = oligo2.getSeq().getSeq();
if ( reverseit ) {
return os2.compareTo( os1 );
} else {
return os1.compareTo( os2 );
}
case AUTHOR:
String a1 = oligo1.getAuthor().getName();
String a2 = oligo2.getAuthor().getName();
if ( reverseit ) {
return a2.compareTo( a1 );
} else {
return a1.compareTo( a2 );
}
default:
return 1;
}
}
};
java.util.Collections.sort( inlist, comparator );
for ( Oligo p : inlist ) {
out.add( p );
}
return out;
}
private String writeKeywords(Oligo aoligo) {
ArrayList<String> tags = aoligo.getSearchTags();
StringBuffer sb = new StringBuffer();
for(int i=0; i<tags.size(); i++) {
sb.append(tags.get(i));
if(i<tags.size()-1) {
sb.append(", ");
}
}
return sb.toString();
}
private void initComponents() {
scroller = new javax.swing.JScrollPane();
table = new JXTable();
//prefs
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.getTableHeader().addMouseListener(new headerListener());
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
_prefs.putInt("spreaditOligosWidth", getWidth());
_prefs.putInt("spreaditOligosHeight", getHeight());
}
});
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.out.println("windowclosing");
List<TableColumn> cols = table.getColumns();
for(int i=0; i<cols.size(); i++) {
_prefs.putInt("spreaditOligosColumn" + i, columnWidths[i]);
}
}
});
//prefs
table.getColumnModel().addColumnModelListener(new TableColumnModelListener() {
@Override
public void columnAdded(TableColumnModelEvent e) {
}
@Override
public void columnRemoved(TableColumnModelEvent e) {
}
@Override
public void columnMoved(TableColumnModelEvent e) {
}
@Override
public void columnMarginChanged(ChangeEvent e) {
List<TableColumn> cols = table.getColumns();
for(int i=0; i<cols.size(); i++) {
columnWidths[i] = cols.get(i).getWidth();
}
}
@Override
public void columnSelectionChanged(ListSelectionEvent e) {
}
});
getContentPane().setBackground(navyblue);
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
String[][] data = new String [][] {
{"Data loading..."}
};
_data = data;
DefaultTableModel tableModel = new DefaultTableModel(_data, new String[] {""});
table.setModel(tableModel);
table.setSortable(false);
table.getTableHeader().setReorderingAllowed(false);
scroller.setViewportView(table);
putInMenuBar();
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(scroller, javax.swing.GroupLayout.DEFAULT_SIZE, 705, Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(scroller, javax.swing.GroupLayout.DEFAULT_SIZE, 456, Short.MAX_VALUE)
.addContainerGap())
);
pack();
}
private void putInMenuBar() {
JMenuBar menuBar = new JMenuBar();
menuBar.setBackground(navyblue);
JMenu fileMenu = new JMenu();
fileMenu.setText("File");
fileMenu.setForeground(Color.WHITE);
menuBar.add(fileMenu);
JMenuItem newWindow = new JMenuItem();
newWindow.setText("New window");
final javax.swing.JFrame myself = this;
newWindow.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
Collection newcoll = new Collection();
newcoll.changeName("Spreadit oligo collection");
newcoll.changeDescription("Temporary collection of oligos");
new spreaditOligos(newcoll);
}
});
fileMenu.add(newWindow);
JMenuItem addOligo = new JMenuItem();
addOligo.setText("Add Oligo");
addOligo.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, java.awt.event.InputEvent.CTRL_MASK));
addOligo.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
oligoEnterer dialog = new oligoEnterer(myself, true);
Oligo aOligo = dialog.getOligo();
if(aOligo!=null) {
_Collection.addObject(aOligo);
System.out.println("basic Oligo added");
}
}
});
fileMenu.add(addOligo);
JMenuItem changeColl = new JMenuItem();
changeColl.setText("Change Default Collection");
changeColl.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
//Throw up a dialog and get user to select the collection stored as 'chosen'
ArrayList<ObjLink> allColl = Collector.getAllLinksOf(ObjType.COLLECTION);
Object[] allNames = allColl.toArray();
ObjLink link = (ObjLink) JOptionPane.showInputDialog(null, "Choose one", "Collection",
JOptionPane.INFORMATION_MESSAGE, null, allNames, allNames[0]);
if(link!=null) {
Collection chosen = Collector.getCollection(link.uuid);
_prefs.put("launchCollection", chosen.getUUID());
}
}
});
fileMenu.add(changeColl);
JMenuItem changeIcon = new JMenuItem();
changeIcon.setText("Change icon");
changeIcon.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
//DO A FILE CHOOSER AND CHANGE LOGO.PNG TO THE FILE
}
});
fileMenu.add(changeIcon);
JMenuItem closeWindow = new JMenuItem();
closeWindow.setText("Close window");
closeWindow.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_W, java.awt.event.InputEvent.CTRL_MASK));
closeWindow.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
myself.dispose();
}
});
fileMenu.add(closeWindow);
JMenu editMenu = new JMenu();
editMenu.setText("Edit");
editMenu.setForeground(Color.WHITE);
menuBar.add(editMenu);
JMenuItem selectAll = new JMenuItem();
selectAll.setText("Select all");
selectAll.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A, java.awt.event.InputEvent.CTRL_MASK));
selectAll.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
table.selectAll();
}
});
editMenu.add(selectAll);
JMenuItem find = new JMenuItem();
find.setText("Search name/description");
find.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F, java.awt.event.InputEvent.ALT_MASK | java.awt.event.InputEvent.CTRL_MASK));
find.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
String query = JOptionPane.showInputDialog( "What do you want to search for?" );
if(query==null) {
return;
}
searchString(query);
}
});
editMenu.add(find);
JMenuItem findSeq = new JMenuItem();
findSeq.setText("Search sequence");
findSeq.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F, java.awt.event.InputEvent.SHIFT_MASK | java.awt.event.InputEvent.CTRL_MASK));
findSeq.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
String query = JOptionPane.showInputDialog( "What sequence do you want to search for?" );
if(query==null) {
return;
}
searchSeq(query);
}
});
editMenu.add(findSeq);
JMenu selectMenu = new JMenu();
selectMenu.setText("Selection");
selectMenu.setForeground(Color.WHITE);
menuBar.add(selectMenu);
JMenuItem save = new JMenuItem();
save.setText("Save selected");
save.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
save.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
int[] selected = table.getSelectedRows();
for(int i: selected) {
Oligo selectOligo = allOligos.get(i);
selectOligo.saveDefault();
}
}
});
selectMenu.add(save);
setJMenuBar(menuBar);
}
private void searchSeq(String tags) {
try {
//Query the database
ClothoConnection c = Collector.getDefaultConnection();
ClothoQuery mainQuery = c.createQuery( ObjType.OLIGO );
ClothoQuery seqQuery = mainQuery.createAssociationQuery( Oligo.Fields.SEQUENCE );
seqQuery.contains( NucSeq.Fields.SEQUENCE, tags, false );
List<ObjBase> results = mainQuery.getResults();
//Wrap the results in a transient collection and launch a viewer
Collection outcoll = new Collection();
outcoll.changeName("Find sequence results");
outcoll.changeDescription("Find output from Spreadit Oligos for " + tags);
for(ObjBase aOligo : results) {
outcoll.addObject(aOligo);
}
new spreaditOligos(outcoll);
} catch( Exception e) {
System.out.println("Sequence find Encountered an error");
}
}
private void searchString(String tags) {
try {
//Query the database
ClothoConnection c = Collector.getDefaultConnection();
ClothoQuery mainQuery = c.createQuery( ObjType.OLIGO );
mainQuery.contains( Oligo.Fields.DESCRIPTION, tags, false );
List<ObjBase> descresults = mainQuery.getResults();
c = Collector.getDefaultConnection();
mainQuery = c.createQuery( ObjType.OLIGO );
mainQuery.contains( Oligo.Fields.NAME, tags, false );
List<ObjBase> nameresults = mainQuery.getResults();
//Wrap the results in a transient collection and launch a viewer
Collection outcoll = new Collection();
outcoll.changeName("Find sequence results");
outcoll.changeDescription("Find output from Spreadit Oligos for " + tags);
for(ObjBase aOligo : descresults) {
outcoll.addObject(aOligo);
}
for(ObjBase aOligo : nameresults) {
outcoll.addObject(aOligo);
}
new spreaditOligos(outcoll);
} catch( Exception e) {
}
}
private void processOligoChange(Oligo aOligo, int row, int column, String val) {
switch(column) {
case 0:
if(aOligo.getName().equals(val)) {
return;
}
aOligo.changeName(val);
table.setValueAt(aOligo.getName(), row, column);
break;
case 1:
if(aOligo.getDescription().equals(val)) {
return;
}
aOligo.changeDescription(val);
table.setValueAt(aOligo.getDescription(), row, column);
break;
case 2:
if(aOligo.getSeq().toString().equals(val)) {
return;
}
aOligo.changeSequence(val);
table.setValueAt(aOligo.getSeq().toString(), row, column);
break;
case 3:
if(aOligo.getAuthor().getName().equals(val)) {
return;
}
Person aPerson = Person.retrieveByName(val);
aOligo.changeAuthor(aPerson);
table.setValueAt(aOligo.getAuthor().getName(), row, column);
break;
case 4:
if(writeKeywords(aOligo).equals(val)) {
return;
}
ArrayList<String> oldtags = aOligo.getSearchTags();
ArrayList<String> newtags = new ArrayList<String>();
ArrayList<String> addlist = new ArrayList<String>();
ArrayList<String> remlist = new ArrayList<String>();
//Parse out what they typed in
String[] tags = val.split("[\\,.]+");
for(String tag : tags) {
String cleaned = tag.trim();
newtags.add(cleaned);
System.out.println(tags);
}
//Decide what goes and what stays
for(String tag : newtags) {
if(!oldtags.contains(tag)) {
addlist.add(tag);
}
}
for(String tag : oldtags) {
if(!newtags.contains(tag)) {
remlist.add(tag);
}
}
//Make changes to the searchtags
for(String tag : addlist) {
aOligo.addSearchTag(tag);
}
for(String tag : remlist) {
aOligo.removeSearchTag(tag);
}
return;
}
}
/*
anoligo = Oligo.retrieveByName("ca998")
acoll = new Collection()
acoll.addObject(anoligo)
acoll.launchDefaultViewer()
*/
private void launchPopup(MouseEvent e) {
if(table.getSelectedRows().length>1) {
System.out.println("Multiple rows selected");
return;
}
int selection = table.getSelectedRow();
System.out.println("Right click popup on " + selection);
}
/**-----------------
variables
-----------------*/
private javax.swing.JScrollPane scroller;
private JXTable table;
static Color navyblue = new Color(35, 48, 64);
private Object[][] _data;
private String [] _title;
private Collection _Collection;
private ArrayList<Oligo> allOligos;
static Preferences _prefs; //prefs
private int[] columnWidths = new int[5];
List<ObjBaseObserver> obrlist = new ArrayList<ObjBaseObserver>();
refresher refreshOBO;
//Plasmid calculator fields
private Vector chosenVector;
private Oligo chosenOligo;
private Plasmid chosenPlasmid;
private ObjBasePopup popper;
private JTextField vectorOfPlasmidCalc;
private JTextField oligoOfPlasmidCalc;
private TransparentButton plasmidIcon;
private static Font labelText = new java.awt.Font("Arial", Font.ITALIC, 10);
private boolean isInitiated = false;
//Digest calculator fields
private TransparentButton digestIcon;
private JPopupMenu popup;
private String firstEnz;
private String secondEnz;
public enum sortBy {NAME, DESCRIPTION, SEQUENCE, AUTHOR};
private sortBy sortByChoice = sortBy.NAME;
private boolean reverseit = false;
}