Adding jobs and statistics...

This commit is contained in:
Marcel Kronfeld 2011-05-04 14:38:06 +00:00
parent 882474ad12
commit 6c13d1bb9b
16 changed files with 1606 additions and 81 deletions

View File

@ -3,6 +3,7 @@ package eva2.gui;
import java.awt.Component;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyEditor;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
@ -19,7 +20,7 @@ import javax.swing.tree.TreePath;
*
*/
public class EvATreeSelectionListener implements TreeSelectionListener, PropertyChangeListener {
private GenericObjectEditor goe=null;
private PropertyEditor goe=null;
private EvATreeNode root = null;
private JTree jtree = null;
public static final boolean TRACE = true;
@ -32,7 +33,7 @@ public class EvATreeSelectionListener implements TreeSelectionListener, Property
* @param goEditor the editor containing the parameter panel
* @param jt the GUI view of the tree
*/
public EvATreeSelectionListener(EvATreeNode rootNode, GenericObjectEditor goEditor, JTree jt) {
public EvATreeSelectionListener(EvATreeNode rootNode, PropertyEditor goEditor, JTree jt) {
goe = goEditor;
root = rootNode;
jtree = jt;

View File

@ -22,32 +22,38 @@ import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyEditor;
import java.lang.reflect.Array;
import java.util.LinkedList;
import java.util.List;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.SwingConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import eva2.tools.EVAHELP;
import eva2.tools.SelectedTag;
import eva2.tools.SerializedObject;
/*==========================================================================*
* CLASS DECLARATION
@ -70,10 +76,22 @@ implements PropertyEditor {
private PropertySelectableList selectableList = null;
/** Click this to delete the selected array values */
private JButton m_DeleteBut = new JButton("Delete");
/** Click to add the current object configuration to the array */
/** list of additional buttons above the list */
private List<JButton> m_AdditionalUpperButtonList = new LinkedList<JButton>();
/** list of additional buttons below the list */
private List<JButton> m_AdditionalLowerButtonList = new LinkedList<JButton>();
private JPanel additionalCenterPane = null;
private List<JMenuItem> m_popupItemList = new LinkedList<JMenuItem>();
private JButton m_AddBut = new JButton("Add");
private JButton m_SetBut = new JButton("Set");
private JButton m_SetAllBut = new JButton("Set all");
private boolean withAddButton = true;
private boolean withSetButton = true;
private boolean withDeleteButton = true;
private Component m_View = null;
/** Listens to buttons being pressed and taking the appropriate action */
private ActionListener m_InnerActionListener =
@ -100,7 +118,7 @@ implements PropertyEditor {
m_ElementList.setModel(m_ListModel);
}
if (selectableList!=null) selectableList.setObjects(modelToArray(m_ListModel));
if (selectableList!=null) selectableList.setObjects(modelToArray(selectableList.getObjects(), m_ListModel));
m_Support.firePropertyChange("", null, null);
}
if (m_ElementList.getSelectedIndex() == -1) {
@ -121,7 +139,7 @@ implements PropertyEditor {
m_ListModel.addElement(addObj);
}
m_ElementList.setModel(m_ListModel);
if (selectableList!=null) selectableList.setObjects(modelToArray(m_ListModel));
if (selectableList!=null) selectableList.setObjects(modelToArray(selectableList.getObjects(), m_ListModel));
m_Support.firePropertyChange("", null, null);
} catch (Exception ex) {
JOptionPane.showMessageDialog(GenericArrayEditor.this,"Could not create an object copy",null,JOptionPane.ERROR_MESSAGE);
@ -151,8 +169,15 @@ implements PropertyEditor {
}
};
private Object[] modelToArray(DefaultListModel listModel) {
Object[] os= new Object[listModel.size()];
public void setAdditionalCenterPane(JPanel panel) {
this.additionalCenterPane = panel;
}
private Object[] modelToArray(Object[] origArray, DefaultListModel listModel) {
Class objClass = origArray.getClass().getComponentType();
Object[] os = (Object[]) java.lang.reflect.Array.newInstance(objClass, listModel.size());
// Object[] os= new Object[listModel.size()];
for (int i=0; i<listModel.size(); i++) {
os[i]=listModel.get(i);
}
@ -176,7 +201,6 @@ implements PropertyEditor {
}
};
/**
* Sets up the array editor.
*/
@ -190,8 +214,63 @@ implements PropertyEditor {
m_ElementList.addListSelectionListener(m_InnerSelectionListener);
m_AddBut.setToolTipText("Add the current item to the list");
m_DeleteBut.setToolTipText("Delete the selected list item");
m_ElementList.addMouseListener(new ActionJList(m_ElementList, this));
}
public int[] getSelectedIndices() {
return m_ElementList.getSelectedIndices();
}
private class ActionJList extends MouseAdapter {
protected JList list;
GenericArrayEditor gae=null;
// PropertyPanel propPanel=null;
public ActionJList(JList l, GenericArrayEditor genAE){
list = l;
gae=genAE;
// if (pPan instanceof PropertyPanel ) propPanel = (PropertyPanel) pPan;
// else {
// System.err.println("Error, invalid property panel in " + this.getClass());
// }
}
public void mouseClicked(MouseEvent e){
if(e.getClickCount() == 2){
int index = list.locationToIndex(e.getPoint());
// Check if the index is valid and if the indexed cell really contains the clicked point
if (index>=0 && (list.getCellBounds(index, index).contains(e.getPoint()))) {
PropertyPanel propPanel=null;
Component comp = gae.m_View;
if (comp instanceof PropertyPanel ) propPanel = (PropertyPanel) comp;
else System.err.println("Error, invalid property panel in " + this.getClass());
ListModel dlm = list.getModel();
Object item = dlm.getElementAt(index);
list.ensureIndexIsVisible(index);
// System.out.println(e);
// System.out.println("Double clicked on " + item);
propPanel.getEditor().setValue(item);
propPanel.showDialog(e.getXOnScreen(), e.getYOnScreen());
propPanel=null;
// int x = getLocationOnScreen().x;
// int y = getLocationOnScreen().y;
// if (m_PropertyDialog == null)
// m_PropertyDialog = new PropertyDialog(gae.m_ElementEditor, EVAHELP.cutClassName(gae.m_ElementEditor.getClass().getName()) , x, y);
// else {
// m_PropertyDialog.updateFrameTitle(gae.m_ElementEditor);
// m_PropertyDialog.set
// m_PropertyDialog.setVisible(false);
// m_PropertyDialog.setExtendedState(JFrame.NORMAL);
// m_PropertyDialog.setVisible(true);
// m_PropertyDialog.requestFocus();
// }
}
}
}
}
/* This class handles the creation of list cell renderers from the
* property editors.
*/
@ -232,7 +311,7 @@ implements PropertyEditor {
((GenericObjectEditor) e).setClassType(m_ValueClass);
}
e.setValue(value);
return new JPanel() {
JPanel cellPanel = new JPanel() {
// return new JCheckBox("", isSelected) {
// public void paintComponent(Graphics g) {
// String name = (String)BeanInspector.callIfAvailable(value, "getName", new Object[]{});
@ -258,6 +337,7 @@ implements PropertyEditor {
return newPref;
}
};
return cellPanel;
} catch (Exception ex) {
return null;
}
@ -273,7 +353,9 @@ implements PropertyEditor {
private void updateEditorType(Object obj) {
// Determine if the current object is an array
m_ElementEditor = null; m_ListModel = null;
m_ElementEditor = null;
m_ListModel = null;
m_View = null;
removeAll();
if ((obj != null) && (obj.getClass().isArray() || (obj instanceof PropertySelectableList))) {
@ -341,19 +423,40 @@ implements PropertyEditor {
// panel.add(view, BorderLayout.CENTER);
// panel.add(m_AddBut, BorderLayout.EAST);
// JPanel buttonPanel=new JPanel(new FlowLayout());
JPanel combinedPanel = new JPanel(new GridLayout(1,3));
combinedPanel.add(m_View );
combinedPanel.add(m_AddBut);
combinedPanel.add(m_SetBut);
combinedPanel.add(m_SetAllBut);
add(combinedPanel, BorderLayout.NORTH);
add(new JScrollPane(m_ElementList), BorderLayout.CENTER);
add(m_DeleteBut, BorderLayout.SOUTH);
if (withAddButton && !(m_AdditionalUpperButtonList.contains(m_AddBut))) m_AdditionalUpperButtonList.add(m_AddBut);
if (withSetButton && !(m_AdditionalUpperButtonList.contains(m_SetBut))) m_AdditionalUpperButtonList.add(m_SetBut);
if (withSetButton && !(m_AdditionalUpperButtonList.contains(m_SetAllBut))) m_AdditionalUpperButtonList.add(m_SetAllBut);
JPanel combiUpperPanel = new JPanel(getButtonLayout(1, m_AdditionalUpperButtonList));
combiUpperPanel.add(m_View );
for (JButton but : m_AdditionalUpperButtonList) {
combiUpperPanel.add(but);
}
add(combiUpperPanel, BorderLayout.NORTH);
if (additionalCenterPane==null) add(new JScrollPane(m_ElementList), BorderLayout.CENTER);
else {
JPanel centerPane=new JPanel();
centerPane.setLayout(new GridLayout(2, 1));
centerPane.add(new JScrollPane(m_ElementList));
centerPane.add(additionalCenterPane);
add(centerPane, BorderLayout.CENTER);
}
if (withDeleteButton && !m_AdditionalLowerButtonList.contains(m_DeleteBut)) m_AdditionalLowerButtonList.add(m_DeleteBut);
JPanel combiLowerPanel = new JPanel(getButtonLayout(0, m_AdditionalLowerButtonList));
for (JButton but : m_AdditionalLowerButtonList) {
combiLowerPanel.add(but);
}
add(combiLowerPanel, BorderLayout.SOUTH);
m_ElementEditor.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
repaint();
}
});
addPopupMenu();
} catch (Exception ex) {
System.err.println(ex.getMessage());
ex.printStackTrace();
@ -367,6 +470,71 @@ implements PropertyEditor {
m_Support.firePropertyChange("", null, null);
validate();
}
/**
* Make a fitting grid layout for a list of buttons. An additional offset may be given
* if further components should be added besides the buttons.
*
* @param additionalOffset
* @param bList
* @return
*/
private LayoutManager getButtonLayout(int additionalOffset, List<JButton> bList) {
int lines = 1+((bList.size()+additionalOffset-1)/3);
int cols = 3;
return new GridLayout(lines, cols);
}
public void removeUpperActionButton(String text) {
removeActionButton(m_AdditionalUpperButtonList, text);
}
public void removeLowerActionButton(String text) {
removeActionButton(m_AdditionalLowerButtonList, text);
}
protected void removeActionButton(List<JButton> bList, String text) {
JButton but = null;
for (JButton jb : bList) {
if (text.equals(jb.getText())) {
but = jb;
break;
}
}
if (but!=null) bList.remove(but);
}
public void addUpperActionButton(String text, ActionListener al) {
addActionButton(m_AdditionalUpperButtonList, text, al);
}
/**
* Wrap an action listener such that the selection state will always be up to date
* in the selectableList (if it exists).
* @param al
* @return
*/
private ActionListener makeSelectionKnownAL(final ActionListener al) {
return new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (selectableList!=null) {
selectableList.setSelectionByIndices(m_ElementList.getSelectedIndices());
}
al.actionPerformed(e);
}
};
}
public void addLowerActionButton(String text, ActionListener al) {
addActionButton(m_AdditionalLowerButtonList, text, al);
}
public void addActionButton(List<JButton> bList, String text, ActionListener al) {
JButton but = new JButton(text);
but.addActionListener(makeSelectionKnownAL(al));
bList.add(but);
}
/**
* Sets the current object array.
*
@ -377,6 +545,21 @@ implements PropertyEditor {
updateEditorType(o);
}
/**
* Select all items. If all are selected, then deselect all items.
*/
public void selectDeselectAll() {
if (areAllSelected()) m_ElementList.getSelectionModel().clearSelection();
else m_ElementList.setSelectionInterval(0, m_ElementList.getModel().getSize()-1);
}
public boolean areAllSelected() {
for (int i=0; i<m_ElementList.getModel().getSize(); i++) {
if (!m_ElementList.isSelectedIndex(i)) return false;
}
return true;
}
/**
* Gets the current object array.
*
@ -399,6 +582,49 @@ implements PropertyEditor {
}
}
public void addPopupItem(String text, ActionListener al) {
JMenuItem item = createMenuItem(text, true, makeSelectionKnownAL(al));
m_popupItemList.add(item);
}
public void addPopupMenu() {
if (m_popupItemList.size()>0) {
m_ElementList.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (selectableList!=null) {
selectableList.setSelectionByIndices(m_ElementList.getSelectedIndices());
}
if ((e.getModifiers() & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) {
// do nothing
} else { // right click released, so show popup
JPopupMenu popupMenu = new JPopupMenu();
for (JMenuItem item : m_popupItemList) popupMenu.add(item);
popupMenu.show(GenericArrayEditor.this, e.getX(), e.getY());
}
}
});
}
}
/**
* Create a menu item with given title and listener, add it to the menu and
* return it. It may be enabled or disabled.
*
* @param menu
* @param title
* @param aListener
* @param enabled
* @return
*/
private JMenuItem createMenuItem(String title, boolean enabled,
ActionListener aListener) {
JMenuItem item = new JMenuItem(title);
// if (bgColor!=null) item.setForeground(bgColor);
item.addActionListener(aListener);
item.setEnabled(enabled);
return item;
}
/**
* Supposedly returns an initialization string to create a classifier
* identical to the current one, including it's state, but this doesn't
@ -486,30 +712,53 @@ implements PropertyEditor {
/**
*
*/
public static void main(String [] args) {
try {
java.beans.PropertyEditorManager.registerEditor(SelectedTag.class,TagEditor.class);
java.beans.PropertyEditorManager.registerEditor(int [].class,GenericArrayEditor.class);
java.beans.PropertyEditorManager.registerEditor(double [].class,GenericArrayEditor.class);
GenericArrayEditor editor = new GenericArrayEditor();
int[] initial = { 3,45, 7};
editor.setValue(initial);
PropertyDialog pd = new PropertyDialog(editor,EVAHELP.cutClassName(editor.getClass().getName())
, 100, 100);
// pd.setSize(200,200);
pd.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
editor.setValue(initial);
//ce.validate();
} catch (Exception ex) {
ex.printStackTrace();
System.err.println(ex.getMessage());
}
// public static void main(String [] args) {
// try {
// java.beans.PropertyEditorManager.registerEditor(SelectedTag.class,TagEditor.class);
// java.beans.PropertyEditorManager.registerEditor(int [].class,GenericArrayEditor.class);
// java.beans.PropertyEditorManager.registerEditor(double [].class,GenericArrayEditor.class);
// GenericArrayEditor editor = new GenericArrayEditor();
//
//
// int[] initial = { 3,45, 7};
// editor.setValue(initial);
// PropertyDialog pd = new PropertyDialog(editor,EVAHELP.cutClassName(editor.getClass().getName())
// , 100, 100);
//// pd.setSize(200,200);
// pd.addWindowListener(new WindowAdapter() {
// public void windowClosing(WindowEvent e) {
// System.exit(0);
// }
// });
// editor.setValue(initial);
// //ce.validate();
// } catch (Exception ex) {
// ex.printStackTrace();
// System.err.println(ex.getMessage());
// }
// }
public boolean isWithAddButton() {
return withAddButton;
}
public void setWithAddButton(boolean withAddButton) {
this.withAddButton = withAddButton;
}
public boolean isWithSetButton() {
return withSetButton;
}
public void setWithSetButton(boolean withSetButton) {
this.withSetButton = withSetButton;
}
public boolean isWithDeleteButton() {
return withDeleteButton;
}
public void setWithDeleteButton(boolean wB) {
this.withDeleteButton = wB;
}
public void removeNotify() {
super.removeNotify();
}
}

View File

@ -15,6 +15,7 @@ import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import java.beans.PropertyEditor;
import java.beans.PropertyEditorManager;
import java.io.Serializable;
@ -23,13 +24,15 @@ import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JPanel;
import eva2.server.stat.EvAJobList;
public class JParaPanel implements Serializable, PanelMaker {
public static boolean TRACE = false;
protected String m_Name = "undefined";
protected Object m_LocalParameter;
protected Object m_ProxyParameter;
protected GenericObjectEditor m_Editor;
protected PropertyEditor m_Editor;
private JPanel m_Panel;
public JParaPanel() {
@ -49,11 +52,14 @@ public class JParaPanel implements Serializable, PanelMaker {
//m_Panel.setPreferredSize(new Dimension(200, 200)); // MK: this was evil, killing all the auto-layout mechanisms
PropertyEditorProvider.installEditors();
m_Editor = new GenericObjectEditor();
((GenericObjectEditor) (m_Editor)).setClassType(m_LocalParameter.
getClass());
((GenericObjectEditor) (m_Editor)).setValue(m_LocalParameter);
((GenericObjectEditor) (m_Editor)).disableOKCancel();
if (m_LocalParameter instanceof EvAJobList) {
m_Editor = EvAJobList.makeEditor(m_Panel, (EvAJobList)m_LocalParameter);
} else {
m_Editor = new GenericObjectEditor();
((GenericObjectEditor) (m_Editor)).setClassType(m_LocalParameter.getClass());
((GenericObjectEditor) (m_Editor)).setValue(m_LocalParameter);
((GenericObjectEditor) (m_Editor)).disableOKCancel();
}
m_Panel.setLayout(new BorderLayout());
m_Panel.add(m_Editor.getCustomEditor(), BorderLayout.CENTER);
@ -71,7 +77,7 @@ public class JParaPanel implements Serializable, PanelMaker {
return m_Name;
}
public GenericObjectEditor getEditor() {
public PropertyEditor getEditor() {
return m_Editor;
}

View File

@ -45,39 +45,52 @@ public class PropertyPanel extends JPanel {
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
if (m_PropertyEditor.getValue() != null) {
if (m_PropertyDialog == null) {
int x = getLocationOnScreen().x;
int y = getLocationOnScreen().y;
m_PropertyDialog = new PropertyDialog(m_PropertyEditor, EVAHELP.cutClassName(m_PropertyEditor.getClass().getName()) , x, y);
}
else {
m_PropertyDialog.updateFrameTitle(m_PropertyEditor);
// System.out.println("" + BeanInspector.toString(m_PropertyDialog));
m_PropertyDialog.setVisible(false);
m_PropertyDialog.setExtendedState(JFrame.NORMAL);
m_PropertyDialog.setVisible(true);
m_PropertyDialog.requestFocus();
// System.out.println("" + BeanInspector.toString(m_PropertyDialog));
// System.out.println("Aft: " + m_PropertyDialog.isShowing() + " " + m_PropertyDialog.isVisible() + " " + m_PropertyDialog.isActive() + " " + m_PropertyDialog.isFocused());
}
showDialog(getLocationOnScreen().x, getLocationOnScreen().y);
}
}
});
Dimension newPref = getPreferredSize();
newPref.height = getFontMetrics(getFont()).getHeight() * 6 / 4; //6 / 4;
newPref.width = newPref.height * 6; //5
setPreferredSize(newPref);
}
public void showDialog(int initX, int initY) {
if (m_PropertyDialog == null) {
// int x = getLocationOnScreen().x;
// int y = getLocationOnScreen().y;
m_PropertyDialog = new PropertyDialog(m_PropertyEditor, EVAHELP.cutClassName(m_PropertyEditor.getClass().getName()) , initX, initY);
m_PropertyDialog.setPreferredSize(new Dimension(500,300));
}
else {
m_PropertyDialog.updateFrameTitle(m_PropertyEditor);
// System.out.println("" + BeanInspector.toString(m_PropertyDialog));
m_PropertyDialog.setVisible(false);
m_PropertyDialog.setExtendedState(JFrame.NORMAL);
m_PropertyDialog.setVisible(true);
m_PropertyDialog.requestFocus();
// System.out.println("" + BeanInspector.toString(m_PropertyDialog));
// System.out.println("Aft: " + m_PropertyDialog.isShowing() + " " + m_PropertyDialog.isVisible() + " " + m_PropertyDialog.isActive() + " " + m_PropertyDialog.isFocused());
}
}
/**
*
*/
public void removeNotify() {
if (m_PropertyDialog != null) {
//System.out.println(" m_PropertyDialog.dispose();");
m_PropertyDialog.dispose();
// System.out.println(" m_PropertyDialog.dispose();");
// System.out.println(m_PropertyDialog.isActive());
// System.out.println(m_PropertyDialog.isVisible());
// System.out.println(m_PropertyDialog.isValid());
// System.out.println(m_PropertyDialog.isDisplayable());
// if (m_PropertyDialog.isDisplayable()) m_PropertyDialog.dispose(); // this caused a deadlock!
// m_PropertyDialog.dispose(); // this also caused a deadlock!
m_PropertyDialog = null;
}
}
/**
*
*/

View File

@ -12,9 +12,9 @@ import java.beans.PropertyChangeSupport;
*/
public class PropertySelectableList<T> implements java.io.Serializable {
private T[] m_Objects;
private boolean[] m_Selection;
private PropertyChangeSupport m_Support = new PropertyChangeSupport(this);
protected T[] m_Objects;
protected boolean[] m_Selection;
private transient PropertyChangeSupport m_Support = new PropertyChangeSupport(this);
// public PropertySelectableList() {
// }
@ -44,10 +44,42 @@ public class PropertySelectableList<T> implements java.io.Serializable {
m_Support.firePropertyChange("PropertySelectableList", null, this);
}
public void setObjects(T[] o, boolean[] selection) {
this.m_Objects = o;
this.m_Selection = selection;
if (o.length != selection.length) throw new RuntimeException("Error, mismatching length of arrays in " + this.getClass());
m_Support.firePropertyChange("PropertySelectableList", null, this);
}
public T[] getObjects() {
return this.m_Objects;
}
/**
* Returns the elements represented by this list where only the selected elements are non-null.
* @return
*/
public T[] getSelectedObjects() {
T[] selObjects = getObjects().clone();
for (int i=0; i<selObjects.length; i++) {
if (!m_Selection[i]) selObjects[i]=null;
}
return selObjects;
}
/**
* Set the selection by giving a list of selected indices.
*
* @param selection
*/
public void setSelectionByIndices(int[] selection) {
m_Selection = new boolean[getObjects().length];
for (int i=0; i<selection.length; i++) {
m_Selection[selection[i]]=true;
}
m_Support.firePropertyChange("PropertySelectableList", null, this);
}
public void setSelection(boolean[] selection) {
this.m_Selection = selection;
m_Support.firePropertyChange("PropertySelectableList", null, this);

View File

@ -17,7 +17,9 @@ import java.util.ArrayList;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import eva2.gui.BeanInspector;
import eva2.tools.BasicResourceLoader;
import eva2.tools.StringTools;
/**
@ -203,4 +205,64 @@ public class FileTools {
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
return fc;
}
public static boolean saveObjectToFolder(Object object, File folder, boolean forceOverwrite, Component parentComponent) {
String predefName = null;
try {
predefName = (String)BeanInspector.callIfAvailable(object, "getName", null);
predefName=StringTools.simplifySymbols(predefName)+".ser";
} catch(Exception e){
predefName=object.getClass().getName();
predefName=StringTools.simplifySymbols(predefName)+".ser";
}
if (!folder.exists()) {
System.err.println("Error, folder " + folder + " does not exist, aborting saveObjectToFolder.");
return false;
} else {
File outFile = new File(folder,predefName);
if (outFile.exists() && !forceOverwrite) {
int opt = JOptionPane.showConfirmDialog(parentComponent, "File " + outFile.getName() + " exists! Overwrite?", "Confirm to overwrite file", JOptionPane.YES_NO_CANCEL_OPTION);
if (opt!=JOptionPane.OK_OPTION) return false;
}
// we may save the file
String msg;
if ((msg = saveObject(object, outFile))!=null) {
JOptionPane.showMessageDialog(parentComponent,
"Couldn't save object: "
+ object
+ "\n" + msg,
"Save object to folder",
JOptionPane.ERROR_MESSAGE);
return false;
} else return true;
}
}
/**
* Store the given object directly without any testing. Returns null on success,
* otherwise the error message of an exception that occurred.
*
* @param object
* @param target
* @return
*/
public static String saveObject(Object object, File target) {
try {
if (object instanceof String) {
PrintWriter Out = new PrintWriter(new FileOutputStream(target));
Out.println((String)object);
Out.flush();
Out.close();
} else {
ObjectOutputStream oo = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(target)));
oo.writeObject(object);
oo.close();
}
return null;
} catch (Exception ex) {
System.err.println("Unable to write to file " + target.getAbsolutePath());
return ex.getMessage();
}
}
}

View File

@ -50,6 +50,20 @@ public abstract class AbstractGOParameters implements InterfaceGOParameters, Ser
opt.SetProblem(prob);
}
/**
* Apply the given GO parameter settings to this instance. This maintains the listeners etc.
*
* @param src
*/
public void setSameParams(AbstractGOParameters src) {
setOptimizer(src.m_Optimizer);
setProblem(src.m_Problem);
setTerminator(src.m_Terminator);
this.m_Optimizer.SetProblem(this.m_Problem);
setSeed(src.m_Seed);
setPostProcessParams(src.m_PostProc);
}
/**
* Add a listener to the current optimizer.
*

View File

@ -10,6 +10,8 @@ import eva2.gui.GenericObjectEditor;
import eva2.gui.JParaPanel;
import eva2.server.go.InterfaceGOParameters;
import eva2.server.stat.AbstractStatistics;
import eva2.server.stat.EvAJob;
import eva2.server.stat.EvAJobList;
import eva2.server.stat.InterfaceStatisticsParameter;
import eva2.server.stat.StatisticsStandalone;
import eva2.server.stat.StatisticsWithGUI;
@ -19,7 +21,9 @@ import eva2.tools.jproxy.RMIProxyLocal;
public class GenericModuleAdapter extends AbstractModuleAdapter implements Serializable {
private AbstractStatistics m_StatisticsModul;
private EvAJobList jobList = null;
public String helperFilename;
JParaPanel jobPanel=null, paramPanel=null;
/**
* Constructor of the ModuleAdapter
@ -93,19 +97,41 @@ public class GenericModuleAdapter extends AbstractModuleAdapter implements Seria
EvAModuleButtonPanelMaker ButtonPanel = new EvAModuleButtonPanelMaker(m_RemoteThis,((Processor)m_Processor).isOptRunning());
ButtonPanel.setHelperFilename(helperFilename);
frmMkr.addPanelMaker(ButtonPanel);
InterfaceGOParameters Para = ((Processor)m_Processor).getGOParams();
if (TRACE) System.out.println("parameters are of type "+Para.getClass());
InterfaceGOParameters goParams = ((Processor)m_Processor).getGOParams();
if (TRACE) System.out.println("parameters are of type "+goParams.getClass());
// TODO do we really need proxies here?
if (m_RMI && !Proxy.isProxyClass(Para.getClass())) frmMkr.addPanelMaker(new JParaPanel( RMIProxyLocal.newInstance(Para), Para.getName()));
else frmMkr.addPanelMaker(new JParaPanel(Para, Para.getName()));
if (m_RMI && !Proxy.isProxyClass(goParams.getClass())) frmMkr.addPanelMaker(paramPanel = new JParaPanel( RMIProxyLocal.newInstance(goParams), goParams.getName()));
else frmMkr.addPanelMaker(paramPanel = new JParaPanel(goParams, goParams.getName()));
if (m_RMI && !Proxy.isProxyClass(Stat.getClass())) frmMkr.addPanelMaker(new JParaPanel( RMIProxyLocal.newInstance(Stat), Stat.getName()));
else frmMkr.addPanelMaker(new JParaPanel(Stat, Stat.getName()));
jobList = new EvAJobList(new EvAJob[]{});
jobList.setModule(this);
jobList.addTextListener((AbstractStatistics) ((Processor)m_Processor).getStatistics());
// if (m_RMI && !Proxy.isProxyClass(Stat.getClass())) frmMkr.addPanelMaker(new JParaPanel( RMIProxyLocal.newInstance(jobList), jobList.getName()));
// else frmMkr.addPanelMaker(new JParaPanel(jobList, jobList.getName()));
if (m_RMI && !Proxy.isProxyClass(Stat.getClass())) jobPanel = new JParaPanel( RMIProxyLocal.newInstance(jobList), jobList.getName());
else jobPanel = new JParaPanel(jobList, jobList.getName());
frmMkr.addPanelMaker(jobPanel);
((Processor)m_Processor).getGOParams().addInformableInstance(frmMkr);
return frmMkr;
}
public static String getName() {
@Override
public void performedStart(String infoString) {
super.performedStart(infoString);
EvAJob job = scheduleJob();
((AbstractStatistics)(((Processor)m_Processor).getStatistics())).addDataListener(job);
}
@Override
public void performedStop() {
super.performedStop();
}
public static String getName() {
return null;
}
@ -116,4 +142,16 @@ public class GenericModuleAdapter extends AbstractModuleAdapter implements Seria
public AbstractStatistics getStatistics() {
return m_StatisticsModul;
}
public EvAJob scheduleJob() {
EvAJob job = jobList.addJob(((Processor)m_Processor).getGOParams(), (AbstractStatistics)(((Processor)m_Processor).getStatistics()));
jobPanel.getEditor().setValue(jobList);
return job;
}
@Override
public void setGOParameters(InterfaceGOParameters goParams) {
super.setGOParameters(goParams);
paramPanel.getEditor().setValue(goParams);
}
}

View File

@ -3,6 +3,7 @@ package eva2.server.stat;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
@ -50,7 +51,7 @@ import eva2.tools.math.Mathematics;
*
*/
public abstract class AbstractStatistics implements InterfaceTextListener, InterfaceStatistics {
private PrintWriter resultOut;
private transient PrintWriter resultOut;
public final static boolean TRACE = false;
protected InterfaceStatisticsParameter m_StatsParams;
@ -141,6 +142,17 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
}
}
private void fireDataListenersFinalize() {
if (dataListeners!=null) {
LinkedList<InterfaceStatisticsListener> toRemove = new LinkedList<InterfaceStatisticsListener>();
for (InterfaceStatisticsListener l : dataListeners) {
boolean rm = l.notifyMultiRunFinished(currentStatHeader, finalObjectData);
if (rm) toRemove.add(l);
}
for (InterfaceStatisticsListener l : toRemove) dataListeners.remove(l);
}
}
/**
* Notify listeners on the start and stop of a run.
*
@ -155,10 +167,10 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
currentStatHeader, currentStatMetaInfo);
} else {
l.notifyRunStopped(optRunsPerformed, normal);
if (optRunsPerformed > 1) {
// if (optRunsPerformed > 1) {
l.finalMultiRunResults(currentStatHeader,
finalObjectData);
}
// }
}
}
}
@ -369,6 +381,7 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
}
if (optRunsPerformed >= m_StatsParams.getMultiRuns()) {
finalizeOutput();
fireDataListenersFinalize();
}
}

View File

@ -0,0 +1,243 @@
package eva2.server.stat;
import java.io.Serializable;
import java.util.List;
import eva2.gui.BeanInspector;
import eva2.server.go.InterfaceGOParameters;
import eva2.tools.StringSelection;
/**
* An EvAJob is a set of optimization parameters and potential results from the statistics class.
* Each job has a unique ID and may have been completely finished or not. Once finished, the
* framework should guarantee that the job is removed as a statistics listener.
*
* A job contains data fields of a multi-run experiment and header strings describing the data.
*
* @author mkron
*
*/
public class EvAJob implements Serializable, InterfaceStatisticsListener {
private static final boolean TRACE = false;
private InterfaceGOParameters params = null;
private String[] fieldHeaders = null;
private List<Object[]> multiRunFinalObjectData = null;
private int jobID=0;
private static int jobIDCounter=0;
private int numRuns = 0;
private boolean lastRunIncompl = false;
// private boolean jobFinished = false;
private StateEnum state = StateEnum.idle;
private enum StateEnum { running, idle, complete, incomplete};
public EvAJob() {
jobID=jobIDCounter;
jobIDCounter++;
}
public EvAJob(InterfaceGOParameters params, InterfaceStatistics sts) {
this();
this.params = params;
sts.addDataListener(this);
}
/**
* Clear the job by resetting its state and clearing all data (which will be lost!).
* The parameters of course remain.
*/
public void resetJob() {
numRuns = 0;
state=StateEnum.idle;
lastRunIncompl=false;
// jobFinished=false;
fieldHeaders=null;
multiRunFinalObjectData=null;
}
public InterfaceGOParameters getParams() {
return params;
}
/**
* Set the GO parameters for this instance.
*
* @param params
*/
public void setParams(InterfaceGOParameters params) {
// how should this be treated? In case the run is already finished, changing
// the parameters will be evil, so avoid that case.
if (state==StateEnum.complete) {
System.err.println("Warning, ignoring changed parameters for finished job!");
} else this.params = params;
}
public String getName() {
if (params==null) return "Invalid Job ("+jobID+")";
else {
String name=getStateTag();
name = name+" Job ("+jobID+"), "; // +params.getName();
name=name+params.getOptimizer().getName()+"/"+params.getProblem().getName();
// name=name+( (onlineData==null) ? ", empty" : (onlineData.size()+" records"));
name=name+(", " + numRuns + " runs");
if (fieldHeaders!=null) name=name+(", " + fieldHeaders.length + " fields");
// if (jobFinished) name=name+", finished";
// if (lastRunIncompl) name=name+", incomplete";
return name;
}
}
private String getStateTag() {
String tag = null;
switch(state) {
case complete: tag="*"; break;
case incomplete: tag="?"; break;
case idle: tag="."; break;
case running: tag="!"; break;
}
tag = tag+numRuns+" ";
return tag;
// if (isFinishedAndComplete()) return "*";
// else if (jobFinished && !lastRunIncompl) return "?";
// else if (!jobFinished && lastRunIncompl) return "-";
// else if (!jobFinished && !lastRunIncompl) return "O";
// else {
// System.err.println("Invalid state of job " + this.toString());
// return "?";
// }
}
public String globalInfo() {
return "Job: " + BeanInspector.niceToString(params);
}
public boolean isFinishedAndComplete() {
// return (jobFinished && !lastRunIncompl);
return (state==StateEnum.complete) && !lastRunIncompl;
}
public String[] getFieldHeaders() {
return fieldHeaders;
}
public List<Object[]> getJobData() {
return multiRunFinalObjectData;
}
public InterfaceGOParameters getGOParams() {
return params;
}
public void finalMultiRunResults(String[] header,
List<Object[]> multiRunFinalObjDat) {
fieldHeaders=header;
multiRunFinalObjectData = multiRunFinalObjDat;
}
public void notifyGenerationPerformed(String[] header,
Object[] statObjects, Double[] statDoubles) {
fieldHeaders=header;
if (state!=StateEnum.running) throw new RuntimeException("Sent data to job with invalid state!");
// if (onlineData==null) onlineData = new ArrayList<Object[]>(10);
// onlineData.add(statObjects);
}
public void notifyRunStarted(int runNumber, int plannedMultiRuns,
String[] header, String[] metaInfo) {
state=StateEnum.running;
// onlineData = null;
// multiRunFinalObjectData = null;
}
public void notifyRunStopped(int runsPerformed, boolean completedLastRun) {
numRuns=runsPerformed;
lastRunIncompl = !completedLastRun;
if (TRACE) System.out.println("EvAJob.notifyRunStopped, " + runsPerformed + " " + completedLastRun);
}
public boolean notifyMultiRunFinished(String[] header, List<Object[]> multiRunFinalObjDat) {
fieldHeaders=header;
multiRunFinalObjectData = multiRunFinalObjDat;
if (lastRunIncompl) state=StateEnum.incomplete;
else state=StateEnum.complete;
// jobFinished=true;
if (TRACE) System.out.println("multi run finished!");
return true;
}
/**
* Retrieve the index of a data field within the data lines.
* Returns -1 if the field has not been found.
*
* @param field
* @return
*/
public int getFieldIndex(String field) {
if (fieldHeaders!=null) {
for (int i=0; i<fieldHeaders.length; i++) {
if (fieldHeaders[i].equals(field)) return i;
}
}
return -1;
}
public int getNumRuns() {
if (multiRunFinalObjectData!=null) return multiRunFinalObjectData.size();
else return -1;
}
/**
* Retrieve a single column of double data indicated by a field name. If the field is unknown
* or there is no double data, null is returned.
*
* @param field
* @return
*/
public double[] getDoubleDataColumn(String field) {
int index = getFieldIndex(field);
if (index>=0) {
double[] data = new double[getNumRuns()];
for (int i=0; i<getNumRuns(); i++) {
Object o = multiRunFinalObjectData.get(i)[index];
try {
if ((o instanceof Double)) {
data[i]=(Double)o;
} else data[i]=Double.parseDouble(o+"");
} catch(Exception e) {
return null;
}
}
return data;
} else return null;
}
/**
* Retrieve a single column of data indicated by a field name. If the field is unknown
* or there is no data, null is returned.
*
* @param field
* @return
*/
public Object[] getDataColumn(String field) {
int index = getFieldIndex(field);
if (index>=0) {
Object[] data = new Object[getNumRuns()];
for (int i=0; i<getNumRuns(); i++) {
data[i]=multiRunFinalObjectData.get(i)[index];
}
return data;
} else return null;
}
public StringSelection getFieldSelection(StringSelection curSelection) {
StringSelection newSel = (StringSelection) curSelection.clone();
curSelection.setAllSelectionStates(false);
for (String field : fieldHeaders) {
curSelection.setSelected(field, true);
}
return newSel;
}
}

View File

@ -0,0 +1,301 @@
package eva2.server.stat;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyEditor;
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import eva2.gui.BeanInspector;
import eva2.gui.GenericArrayEditor;
import eva2.gui.JEFrame;
import eva2.gui.JParaPanel;
import eva2.gui.PropertySelectableList;
import eva2.server.go.InterfaceGOParameters;
import eva2.server.go.tools.FileTools;
import eva2.server.modules.AbstractGOParameters;
import eva2.server.modules.AbstractModuleAdapter;
import eva2.server.modules.GenericModuleAdapter;
import eva2.server.modules.ModuleAdapter;
import eva2.tools.Serializer;
/**
* A selectable list of EvAJobs. Each job contains a GOParameters instance and potentially statistical data.
*
* @author mkron
*
*/
public class EvAJobList extends PropertySelectableList<EvAJob> implements Serializable, InterfaceTextListener {
List<InterfaceTextListener> listeners = null;
private ModuleAdapter module = null;
// private static transient LogPanel logPanel = null;
// private static transient JFrame statsFrame = null;
public EvAJobList(EvAJob[] initial) {
super(initial);
}
public String getName() {
return "Job Set";
}
public String globalInfo() {
return "Display a set of jobs consisting of a multi-run experiment.";
}
/**
* This adds a new job to the list.
*
* @param params
* @param stats
*/
public EvAJob addJob(InterfaceGOParameters params, AbstractStatistics stats) {
EvAJob job = new EvAJob((InterfaceGOParameters)Serializer.deepClone(params), stats);
stats.addDataListener(job);
addJob(job, true);
return job;
}
private void addJob(EvAJob j, boolean selected) {
EvAJob[] curArr = getObjects();
EvAJob[] newArr = null;
boolean[] newSelection = null;
if (curArr!=null && curArr.length>0) {
newArr = new EvAJob[curArr.length + 1];
newSelection = new boolean[newArr.length];
System.arraycopy(curArr, 0, newArr, 0, curArr.length);
System.arraycopy(m_Selection, 0, newSelection, 0, curArr.length);
} else {
newArr = new EvAJob[1];
newSelection = new boolean[1];
}
newSelection[newArr.length-1]=selected;
newArr[newArr.length-1] = j;
setObjects(newArr, newSelection);
}
/**
* Return the last job in the list, which is also the last one added.
*
* @return
*/
public EvAJob lastJob() {
EvAJob[] curArr = getObjects();
if (curArr!=null && curArr.length>0) return curArr[curArr.length-1];
else return null;
}
/**
* Return a list of the currently selected jobs.
*
* @return
*/
public ArrayList<EvAJob> getSelectedJobs() {
EvAJob[] selected = getSelectedObjects();
ArrayList<EvAJob> l = new ArrayList<EvAJob>();
for (EvAJob j : selected) {
if (j!=null) l.add(j);
}
return l;
}
public boolean saveSelectedJobs(Component parentComponent) {
EvAJob[] selected = getSelectedObjects();
if (selected!=null && (selected.length>0)) {
JFileChooser fc = new JFileChooser();
fc.setName("Select a directory to save jobs to...");
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int returnVal = fc.showSaveDialog(parentComponent);
if (returnVal==JFileChooser.APPROVE_OPTION) {
File sFile = fc.getSelectedFile();
if (sFile.exists()) {
for (EvAJob job : selected) {
if (!FileTools.saveObjectToFolder(job, sFile, false, parentComponent)) {
System.err.println("Error on saving jobs...");
return false;
}
}
} else return false; // invalid folder chosen
} else return false; // user break
}
return true;
}
/**
* Search for a job in the list which has the given parameter structure assigned.
* This is tested by reference, so the exact same instance of InterfaceGOParameters
* must be known. If no matching job is found, null is returned.
* @param params
* @return
*/
public EvAJob getJobOf(InterfaceGOParameters params) {
for (EvAJob job : getObjects()) {
if (job.getGOParams()==params) return job;
}
return null;
}
// private static List<JButton> getActionButtons(final EvAJobList jobList, final GenericArrayEditor edi) {
// LinkedList<JButton> buts = new LinkedList<JButton>();
// buts.add(getRunButton(jobList, edi));
// return buts;
// }
// private static JButton getRunButton(final EvAJobList jobList, final GenericArrayEditor edi) {
// JButton runBut = new JButton("Exec");
// runBut.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent e) {
// System.out.println("PING!");
// System.out.println(BeanInspector.toString(edi.getSelectedIndices()));
// EvAStatisticalEvaluation.evaluate((InterfaceTextListener)jobList, jobList.getObjects(), edi.getSelectedIndices());
// System.out.println(BeanInspector.toString(EvAStatisticalEvaluation.statsParams.getPairedStats().getSelected()));
// }
// });
// return runBut;
// }
/**
* Create a customized editor for the job list based on an array editor.
*
* @param jobList
* @return
*/
public static PropertyEditor makeEditor(final Component parent, final EvAJobList jobList) {
final GenericArrayEditor edi = new GenericArrayEditor();
edi.setWithAddButton(false);
edi.setWithSetButton(false);
ActionListener al=new ActionListener() {
public void actionPerformed(ActionEvent e) {
// System.out.println("PING!");
// System.out.println(BeanInspector.toString(edi.getSelectedIndices()));
EvAStatisticalEvaluation.evaluate((InterfaceTextListener)jobList, jobList.getObjects(), edi.getSelectedIndices(),
(StatsOnSingleDataSetEnum[])EvAStatisticalEvaluation.statsParams.getOneSampledStats().getSelectedEnum(StatsOnSingleDataSetEnum.values()),
(StatsOnTwoSampledDataEnum[])EvAStatisticalEvaluation.statsParams.getTwoSampledStats().getSelectedEnum(StatsOnTwoSampledDataEnum.values()));
// System.out.println(BeanInspector.toString(EvAStatisticalEvaluation.statsParams.getPairedStats().getSelected()));
}
// public void actionPerformed(ActionEvent e) {
// if (statsFrame ==null) {
// statsFrame = new JEFrame("EvA2 Statistics Evaluation", true);
// JPanel tmpPan = createStatsPanel(jobList, edi);
// statsFrame.getContentPane().add(tmpPan);
// }
// if (!statsFrame.isVisible()) {
// statsFrame.pack();
// statsFrame.validate();
// statsFrame.setVisible(true);
// } else statsFrame.requestFocus();
// }
};
ActionListener sl=new ActionListener() {
public void actionPerformed(ActionEvent e) {
edi.selectDeselectAll();
}
};
ActionListener sal=new ActionListener() {
public void actionPerformed(ActionEvent e) {
jobList.saveSelectedJobs(edi);
}
};
edi.addUpperActionButton("(De-)Sel. all", sl);
edi.addUpperActionButton("Test Stats", al);
edi.addLowerActionButton("Save selected", sal);
// edi.addPopupItem("Reset selected", getClearSelectedActionListener(parent, jobList)); // this option does not make much sense - instead of deleting data, taking over the settings for a new run is more plausible
edi.addPopupItem("Reuse as current settings", getReuseActionListener(parent, jobList));
edi.setAdditionalCenterPane(createStatsPanel(jobList, edi));
edi.setValue(jobList);
return edi;
}
private static JPanel createStatsPanel(final EvAJobList jobList, final GenericArrayEditor edi) {
// if (logPanel != null) System.err.println("Error: logPanel should be null!!!");
// logPanel = new LogPanel();
// EvAStatisticalEvaluation.statsParams.setGenericAdditionalButtons(getActionButtons(lPan, jobList, edi));
JParaPanel pan = new JParaPanel(EvAStatisticalEvaluation.statsParams, "Statistics");
// GOEPanel pan = new GOEPanel(EvAStatisticalEvaluation.selectedSingleStats, jobList, null, new GenericObjectEditor());
JComponent paraPan = pan.makePanel();
JPanel tmpPan = new JPanel();
// tmpPan.setPreferredSize(new Dimension(1200,1200));
tmpPan.add(paraPan);
// tmpPan.add(logPanel);
return tmpPan;
}
// public static void main(String[] args) {
// JEFrame frm = new JEFrame("Test", true);
// EvAJobList jl = new EvAJobList(new EvAJob[]{});
// frm.add((GenericArrayEditor)makeEditor(null, jl));
// frm.pack();
// frm.setVisible(true);
// }
private static ActionListener getReuseActionListener(final Component parent, final EvAJobList jobList) {
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent e) {
List<EvAJob> jobs = jobList.getSelectedJobs();
if (jobs.size()==1) {
EvAJob job = jobs.get(0);
AbstractGOParameters curParams = (AbstractGOParameters)((AbstractModuleAdapter)jobList.module).getGOParameters();
curParams.setSameParams((AbstractGOParameters) job.getGOParams());
((GenericModuleAdapter)jobList.module).setGOParameters(curParams);
((GenericModuleAdapter)jobList.module).getStatistics().getStatisticsParameter().setMultiRuns(job.getNumRuns());
((GenericModuleAdapter)jobList.module).getStatistics().getStatisticsParameter().setFieldSelection(job.getFieldSelection(((GenericModuleAdapter)jobList.module).getStatistics().getStatisticsParameter().getFieldSelection()));
} else JOptionPane.showMessageDialog(parent, "Select exactly one job to reuse!", "Error", JOptionPane.ERROR_MESSAGE);
}
};
return al;
}
private static ActionListener getClearSelectedActionListener(final Component parent, final EvAJobList jobList) {
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent e) {
List<EvAJob> jobs = jobList.getSelectedJobs();
for (EvAJob j : jobs) j.resetJob();
}
};
return al;
}
/**
* Link a processor to the job list for re-scheduling jobs.
* @param processor
*/
public void setModule(ModuleAdapter mod) {
module = mod;
}
public void addTextListener(InterfaceTextListener tListener) {
if (listeners==null) listeners = new LinkedList<InterfaceTextListener>();
if (!listeners.contains(tListener)) listeners.add(tListener);
}
public boolean removeTextListener(InterfaceTextListener tListener) {
if (listeners!=null) {
return listeners.remove(tListener);
} else return false;
}
@Override
public void print(String str) {
if (listeners!=null) for (InterfaceTextListener lst : listeners) {
lst.print(str);
}
}
@Override
public void println(String str) {
if (listeners!=null) for (InterfaceTextListener lst : listeners) {
lst.println(str);
}
}
}

View File

@ -0,0 +1,326 @@
package eva2.server.stat;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import eva2.gui.BeanInspector;
import eva2.tools.ReflectPackage;
import eva2.tools.math.Mathematics;
/**
* Do some statistical tests on a set of job results. Note that the plausibility (comparability of the
* jobs) is not tested here.
*
* @author mkron
*
*/
public class EvAStatisticalEvaluation {
public static final boolean TRACE=false;
// public static final String[] order = {"Mean" , "Median", "Variance", "Std. Deviation"};
public static EvAStatisticalEvaluationParams statsParams = new EvAStatisticalEvaluationParams();
// public static void evaluate(EvAJob[] jobList, int[] selectedIndices) {
// if (TRACE) System.out.println("Job list: " + BeanInspector.toString(jobList));
// JTextoutputFrame textout = new JTextoutputFrame("Statistics");
// textout.setShow(true);
// ArrayList<EvAJob> jobsToWorkWith = new ArrayList<EvAJob>();
// for (int i=0; i<jobList.length; i++) {
// // remove jobs which are not finished or not selected
// if (jobList[i]!=null && (Mathematics.contains(selectedIndices, i)) && (jobList[i].isFinishedAndComplete())) jobsToWorkWith.add(jobList[i]);
// }
// List<String> commonFields = getCommonFields(jobsToWorkWith);
// if (commonFields!=null && !commonFields.isEmpty()) for (String field : commonFields) {
// textout.println("Checking field " + field);
//
// for (int i=0; i<jobsToWorkWith.size(); i++) {
// textout.print(jobsToWorkWith.get(i).getParams().getOptimizer().getName() + "\t");
// for (int j=0; j<jobsToWorkWith.size(); j++) {
//// System.out.println("Comparing " + i + " with " + j);
// textout.print("\t" + compare(field, jobsToWorkWith.get(i), jobsToWorkWith.get(j)));
// }
// textout.println("");
// }
// }
// }
public static void evaluate(InterfaceTextListener textout, EvAJob[] jobList, int[] selectedIndices,
StatsOnSingleDataSetEnum[] singleStats,
StatsOnTwoSampledDataEnum[] twoSampledStats ) {
if (TRACE) System.out.println("Job list: " + BeanInspector.toString(jobList));
// JTextoutputFrame textout = new JTextoutputFrame("Statistics");
// textout.setShow(true);
ArrayList<EvAJob> jobsToWorkWith = new ArrayList<EvAJob>();
for (int i=0; i<jobList.length; i++) {
// remove jobs which are not finished or not selected
if (jobList[i]!=null && (Mathematics.contains(selectedIndices, i)) && (jobList[i].isFinishedAndComplete())) jobsToWorkWith.add(jobList[i]);
}
List<String> commonFields = getCommonFields(jobsToWorkWith);
if (commonFields!=null && !commonFields.isEmpty()) for (String field : commonFields) {
textout.println("###\t"+ field + " statistical evaluation");
if(singleStats.length > 0){
textout.println("one-sampled statistics");
for (int j=-1; j<singleStats.length; j++) {
if(j<0){
textout.print("method");
}else{
textout.print("\t" + singleStats[j]);
}
}
textout.println("");
for(int i=0; i<jobsToWorkWith.size(); i++){
textout.print(jobsToWorkWith.get(i).getParams().getOptimizer().getName());
for(int j=0; j<singleStats.length; j++){
switch(singleStats[j]){
case mean: textout.print("\t" + calculateMean(field, jobsToWorkWith.get(i))); break;
case median: textout.print("\t" + calculateMedian(field, jobsToWorkWith.get(i))); break;
case variance: textout.print("\t" + calculateVariance(field, jobsToWorkWith.get(i))); break;
case stdDev: textout.print("\t" + calculateStdDev(field, jobsToWorkWith.get(i))); break;
default: textout.println("");
}
}
textout.println("");
}
}
if(twoSampledStats.length > 0){
textout.println("two-sampled stats:");
for(int i=0; i<twoSampledStats.length; i++){
switch(twoSampledStats[i]){
case tTestEqLenEqVar: textout.println(StatsOnTwoSampledDataEnum.getInfoStrings()[twoSampledStats[i].ordinal()]);
writeTwoSampleFirstLine(textout, jobsToWorkWith);
writeTTestEqSizeEqVar(textout, jobsToWorkWith, field);
break;
case tTestUneqLenEqVar: textout.println(StatsOnTwoSampledDataEnum.getInfoStrings()[twoSampledStats[i].ordinal()]);
writeTwoSampleFirstLine(textout, jobsToWorkWith);
writeUnEqSizeEqVar(textout, jobsToWorkWith, field);
break;
case tTestUneqLenUneqVar: textout.println(StatsOnTwoSampledDataEnum.getInfoStrings()[twoSampledStats[i].ordinal()]);
writeTwoSampleFirstLine(textout, jobsToWorkWith);
writeTTestUnEqSizeUnEqVar(textout, jobsToWorkWith, field);
break;
case mannWhitney: textout.println(StatsOnTwoSampledDataEnum.getInfoStrings()[twoSampledStats[i].ordinal()]);
writeTwoSampleFirstLine(textout, jobsToWorkWith);
writeMannWhitney(textout, jobsToWorkWith, field);
default: textout.println("");
break;
}
textout.println("");
}
}
}
}
/**
* @param textout
* @param jobsToWorkWith
* @param field
*/
private static void writeTTestUnEqSizeUnEqVar(
InterfaceTextListener textout, ArrayList<EvAJob> jobsToWorkWith,
String field) {
for (int i=0; i<jobsToWorkWith.size(); i++) {
textout.print(jobsToWorkWith.get(i).getParams().getOptimizer().getName());
for (int j=0; j<jobsToWorkWith.size(); j++) {
textout.print("\t" + calculateTTestUnEqSizeUnEqVar(field, jobsToWorkWith.get(i), jobsToWorkWith.get(j)));
}
textout.println("");
}
}
/**
* @param textout
* @param jobsToWorkWith
* @param field
*/
private static void writeUnEqSizeEqVar(InterfaceTextListener textout,
ArrayList<EvAJob> jobsToWorkWith, String field) {
for (int i=0; i<jobsToWorkWith.size(); i++) {
textout.print(jobsToWorkWith.get(i).getParams().getOptimizer().getName());
for (int j=0; j<jobsToWorkWith.size(); j++) {
textout.print("\t" + calculateTTestUnEqSizeEqVar(field, jobsToWorkWith.get(i), jobsToWorkWith.get(j)));
}
textout.println("");
}
}
/**
* @param textout
* @param jobsToWorkWith
* @param field
*/
private static void writeTTestEqSizeEqVar(InterfaceTextListener textout,
ArrayList<EvAJob> jobsToWorkWith, String field) {
for (int i=0; i<jobsToWorkWith.size(); i++) {
textout.print(jobsToWorkWith.get(i).getParams().getOptimizer().getName());
for (int j=0; j<jobsToWorkWith.size(); j++) {
textout.print("\t" + calculateTTestEqSizeEqVar(field, jobsToWorkWith.get(i), jobsToWorkWith.get(j)));
}
textout.println("");
}
}
private static void writeMannWhitney(InterfaceTextListener textout,
ArrayList<EvAJob> jobsToWorkWith, String field) {
for (int i=0; i<jobsToWorkWith.size(); i++) {
textout.print(jobsToWorkWith.get(i).getParams().getOptimizer().getName());
for (int j=0; j<jobsToWorkWith.size(); j++) {
textout.print("\t" + calculateMannWhintey(field, jobsToWorkWith.get(i), jobsToWorkWith.get(j)));
}
textout.println("");
}
}
/**
* @param textout
* @param jobsToWorkWith
*/
private static void writeTwoSampleFirstLine(InterfaceTextListener textout,
ArrayList<EvAJob> jobsToWorkWith) {
for(int i=0; i<jobsToWorkWith.size(); i++){
textout.print("\t" + jobsToWorkWith.get(i).getParams().getOptimizer().getName());
}
textout.println("");
}
public static double roundTo2DecimalPlaces(double value){
DecimalFormat twoDForm = new DecimalFormat("#.##");
String b = twoDForm.format(value);
b = b.replace(',', '.');
Double c = Double.valueOf(b);
return c;
}
private static String calculateMean(String field, EvAJob job1){
double[] dat = job1.getDoubleDataColumn(field);
double mean = Double.NaN;
if (dat!=null) {
mean = Mathematics.mean(dat);
mean = EvAStatisticalEvaluation.roundTo2DecimalPlaces(mean);
}
return ""+mean;
}
private static String calculateMedian(String field, EvAJob job1){
double[] dat = job1.getDoubleDataColumn(field);
double median = Double.NaN;
if (dat!=null) {
median = Mathematics.median2(dat, true);
median = EvAStatisticalEvaluation.roundTo2DecimalPlaces(median);
}
return ""+median;
}
private static String calculateVariance(String field, EvAJob job1){
double[] dat = job1.getDoubleDataColumn(field);
double variance = Double.NaN;
if (dat!=null) {
variance = Mathematics.variance(dat);
variance = EvAStatisticalEvaluation.roundTo2DecimalPlaces(variance);
}
return ""+variance;
}
private static String calculateStdDev(String field, EvAJob job1){
double[] dat = job1.getDoubleDataColumn(field);
double stdDev = Double.NaN;
if (dat!=null) {
stdDev = Mathematics.stdDev(dat);
stdDev = EvAStatisticalEvaluation.roundTo2DecimalPlaces(stdDev);
}
return ""+stdDev;
}
private static String calculateTTestEqSizeEqVar(String field, EvAJob job1, EvAJob job2){
double[] dat1 = job1.getDoubleDataColumn(field);
double[] dat2 = job2.getDoubleDataColumn(field);
double t=Double.NaN;
if (dat1!=null && dat2!=null) {
t = Mathematics.tTestEqSizeEqVar(dat1, dat2);
}
// MannWhitneyTest mwt = new MannWhitneyTest(job1.getDoubleDataColumn(field), job2.getDoubleDataColumn(field));
// double t = mwt.getSP();
// t = roundTo2DecimalPlaces(t);
return ""+t;
}
private static String calculateTTestUnEqSizeEqVar(String field, EvAJob job1, EvAJob job2){
double[] dat1 = job1.getDoubleDataColumn(field);
double[] dat2 = job2.getDoubleDataColumn(field);
double t=Double.NaN;
if (dat1!=null && dat2!=null) {
t = Mathematics.tTestUnEqSizeEqVar(dat1, dat2);
}
// t = roundTo2DecimalPlaces(t);
return ""+t;
}
private static String calculateTTestUnEqSizeUnEqVar(String field, EvAJob job1, EvAJob job2){
double[] dat1 = job1.getDoubleDataColumn(field);
double[] dat2 = job2.getDoubleDataColumn(field);
double t=Double.NaN;
if (dat1!=null && dat2!=null) {
t = Mathematics.tTestUnEqSizeUnEqVar(dat1, dat2);
}
// t = roundTo2DecimalPlaces(t);
return ""+t;
}
private static String calculateMannWhintey(String field, EvAJob job1, EvAJob job2){
double[] dat1 = job1.getDoubleDataColumn(field);
double[] dat2 = job2.getDoubleDataColumn(field);
double t=Double.NaN;
if (dat1!=null && dat2!=null) {
Object obj = ReflectPackage.instantiateWithParams("jsc.independentsamples.MannWhitneyTest", new Object[]{dat1,dat2}, null);
if (obj!=null) {
Object sp = BeanInspector.callIfAvailable(obj, "getSP", new Object[]{});
// System.out.println(BeanInspector.niceToString(obj));
// System.out.println("SP val is " + sp);
t = (Double) sp;
} else System.err.println("For the MannWhitney test, the JSC package is required on the class path!");
}
return ""+t;
}
private static String compare(String field, EvAJob job1, EvAJob job2) {
// TODO do some statistical test
int numRuns1 = job1.getNumRuns();
int numRuns2 = job2.getNumRuns();
if (TRACE) System.out.println("Run 1: " + numRuns1 + " runs, Run 2: " + numRuns2);
if (TRACE) System.out.println("Data of run 1: " + BeanInspector.toString(job1.getDataColumn(field)));
if (TRACE) System.out.println("Data of run 2: " + BeanInspector.toString(job2.getDataColumn(field)));
double avg1=Mathematics.mean(job1.getDoubleDataColumn(field));
double avg2=Mathematics.mean(job2.getDoubleDataColumn(field));
if (avg1<avg2) return "-1";
else if (avg1>avg2) return "1";
else return "0";
}
/**
* Return a list of field names which occur in all jobs.
* @param jobList
* @return
*/
private static List<String> getCommonFields(List<EvAJob> jobList) {
List<String> lSoFar=null, tmpL = new LinkedList<String>();
for (EvAJob j:jobList) {
if (lSoFar==null) {
lSoFar = new LinkedList<String>();
for (String f : j.getFieldHeaders()) lSoFar.add(f);
} else {
for (String f : lSoFar) {
if (j.getFieldIndex(f)>=0) tmpL.add(f);
}
lSoFar=tmpL;
tmpL = new LinkedList<String>();
}
}
if (TRACE) System.out.println("Common fields are " + BeanInspector.toString(lSoFar));
return lSoFar;
}
}

View File

@ -0,0 +1,61 @@
package eva2.server.stat;
import java.io.Serializable;
import java.util.List;
import javax.swing.JButton;
import eva2.tools.StringSelection;
public class EvAStatisticalEvaluationParams implements Serializable {
// private StatsOnDataSetPairEnum[] pairedStats = new StatsOnDataSetPairEnum[] {StatsOnDataSetPairEnum.tTestEqual, StatsOnDataSetPairEnum.tTestUnequal};
// private StatsOnSingleDataSetEnum[] singleStats = new StatsOnSingleDataSetEnum[] {StatsOnSingleDataSetEnum.mean, StatsOnSingleDataSetEnum.median};
private StringSelection singleStats = new StringSelection(StatsOnSingleDataSetEnum.mean, StatsOnSingleDataSetEnum.getInfoStrings());
private StringSelection twoSampledStats = new StringSelection(StatsOnTwoSampledDataEnum.tTestUneqLenEqVar, StatsOnTwoSampledDataEnum.getInfoStrings());
private List<JButton> additionalButtons = null;
public void setGenericAdditionalButtons(List<JButton> buts) {
this.additionalButtons = buts;
}
public StringSelection getTwoSampledStats() {
return twoSampledStats;
}
public void setTwoSampledStats(StringSelection pairedStats) {
this.twoSampledStats = pairedStats;
}
public String twoSampledStatsTipText() {
return "Statistical tests on two-sampled data";
}
public StringSelection getOneSampledStats() {
return singleStats;
}
public void setOneSampledStats(StringSelection singleStats) {
this.singleStats = singleStats;
}
public String oneSampledStatsTipText() {
return "Statistical tests on one-sampled data";
}
public String getName() {
return "Statistical evaluation parameters";
}
public String globalInfo() {
return "Select statistical values to be calculated and paired tests to be performed.";
}
public List<JButton> getAdditionalButtons() {
return additionalButtons;
}
public boolean withGenericOkButton() {
return false;
}
public boolean withGenericLoadSafeButtons() {
return false;
}
}

View File

@ -49,4 +49,12 @@ public interface InterfaceStatisticsListener {
* @param multiRunFinalObjectData
*/
public void finalMultiRunResults(String[] header, List<Object[]> multiRunFinalObjectData);
/**
* Called after the job is finished. Return true if the listener should be removed after this multi-run.
*
* @param header
* @param multiRunFinalObjectData
*/
public boolean notifyMultiRunFinished(String[] header, List<Object[]> multiRunFinalObjectData);
}

View File

@ -5,6 +5,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Constructor;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
@ -18,6 +19,8 @@ import java.util.jar.JarInputStream;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import eva2.gui.BeanInspector;
/**
* Allow for java to list Classes that exist in one package and can be instantiated from
@ -474,4 +477,80 @@ public class ReflectPackage {
}
return ret;
}
/**
* Instantiate a class given by full name (with package) and try to set the member values given
* in the pair-value list. Returns null if the instance could not be created or any name-value
* pair could not be set. Otherwise the created object is returned.
*
* @param clsName
* @param paramValuePairs
* @return
*/
public static Object instantiateWithParams(String clsName, List<Pair<String,Object>> paramValuePairs) {
return instantiateWithParams(clsName, new Object[]{}, paramValuePairs);
}
/**
* Instantiate a class given by full name (with package) and try to set the member values given
* in the pair-value list. Returns null if the instance could not be created or any name-value
* pair could not be set. Otherwise the created object is returned.
*
* @param clsName name of the target class with full package path
* @param args constructor arguments
* @param paramValuePairs pairs of values to set using generic setter methods
* @see BeanInspector.setMem(Object,String,Object)
* @return
*/
public static Object instantiateWithParams(String clsName, Object[] args, List<Pair<String,Object>> paramValuePairs) {
Object o = getInstance(clsName, args);
if (o!=null) {
if (paramValuePairs!=null) for (Pair<String, Object> nameVal : paramValuePairs) {
boolean succ = BeanInspector.setMem(o, nameVal.head, nameVal.tail);
if (!succ) {
System.err.println("Error, unable to set " + nameVal.head + " to " + nameVal.tail + " in object " + o);
return null;
}
else if (TRACE) System.out.println("Successfully set " + nameVal.head + " to " + nameVal.tail + " in object " + o);
}
return o;
} else {
System.err.println("Error in instantiateWithParams!");
return null;
}
}
/**
* Retrieve an instance of a generic object with arbitrary arguments. Note that the
* full package path must be given and the argument array must match a signature of
* an existing constructor.
* Returns null on a failure and the constructed object otherwise.
*
* @param clsName
* @param args
* @return
*/
public static Object getInstance(String clsName, Object[] args) {
Object o;
try {
Class<?> clz = Class.forName(clsName);
Class<?>[] argClz=new Class[args.length];
for (int i=0; i<args.length; i++) argClz[i]=args[i].getClass();
Constructor<?> ct;
try {
ct = clz.getConstructor(argClz);
o=ct.newInstance(args);
} catch (Exception e) {
System.err.println("Unable to retrieve constructor of " + clsName + ", arguments " + BeanInspector.toString(args)+"\n"+e.getClass());
System.err.println(e.getMessage());
e.printStackTrace();
o=null;
}
} catch (Exception e) {
System.err.println("Unable to create instance of " + clsName + ", arguments " + BeanInspector.toString(args) + "\n"+e.getMessage());
e.printStackTrace(System.err);
o=null;
}
return o;
}
}

View File

@ -609,6 +609,71 @@ public class Mathematics {
}
}
public static double median2(double[] vector, boolean clone){
double[] in;
if (clone){
in = (double[]) vector.clone();
}else{
in = vector;
}
if(in.length == 0){
return 0;
}
Arrays.sort(in);
return in[(int) Math.floor(((double) in.length) / 2.0)];
}
public static double variance(double[] vector){
double mean = Mathematics.mean(vector);
double result = 0.0;
for(int i=0; i<vector.length; i++){
result += Math.pow(vector[i] - mean, 2);
}
return result;
}
public static double stdDev(double[] vector){
double result = variance(vector);
result = Math.sqrt(result);
return result;
}
public static double tTestEqSizeEqVar(double[] vector1, double[] vector2){
double n = (double) vector1.length;
double mean1 = mean(vector1);
double mean2 = mean(vector2);
double stdDev1 = stdDev(vector1);
double stdDev2 = stdDev(vector2);
double sX1X2 = Math.sqrt((Math.pow(stdDev1, 2) + Math.pow(stdDev2, 2)) / 2);
double result = (mean1 - mean2) / (Math.sqrt(2 / n) * sX1X2);
return result;
}
public static double tTestUnEqSizeEqVar(double[] vector1, double[] vector2){
double n1 = (double) vector1.length;
double n2 = (double) vector2.length;
double mean1 = mean(vector1);
double mean2 = mean(vector2);
double stdDev1 = stdDev(vector1);
double stdDev2 = stdDev(vector2);
double sX1X2 = Math.sqrt(((n1 - 1) * Math.pow(stdDev1, 2) + (n2 - 1) * Math.pow(stdDev2, 2)) / (n1 + n2 - 2));
double result = (mean1 - mean2) / (sX1X2 * Math.sqrt(1/n1 + 1/n2));
return result;
}
public static double tTestUnEqSizeUnEqVar(double[] vector1, double[] vector2){
double n1 = (double) vector1.length;
double n2 = (double) vector2.length;
double mean1 = mean(vector1);
double mean2 = mean(vector2);
double stdDev1 = stdDev(vector1);
double stdDev2 = stdDev(vector2);
double sX1X2 = Math.sqrt((Math.pow(stdDev1, 2) / n1) + (Math.pow(stdDev2, 2) / n2));
double result = (mean1 - mean2) / sX1X2;
return result;
}
public static double min(double[] vals) {
double minVal = vals[0];
for (int i = 1; i < vals.length; i++)
@ -1367,4 +1432,18 @@ public class Mathematics {
vec[i] *= scale;
}
}
/**
* Return true if an integer is contained in an integer list, otherwise false.
*
* @param list
* @param i
* @return
*/
public static boolean contains(int[] list, int i) {
for (int k:list) {
if (k==i) return true;
}
return false;
}
}