Refactor BeanInspector and ToolTip Text fetching

- added test

refs #53
This commit is contained in:
Fabian Becker 2015-12-31 01:28:56 +01:00
parent 846a066071
commit 62ddb5480f
4 changed files with 84 additions and 81 deletions

View File

@ -3,16 +3,15 @@ package eva2.gui;
import eva2.optimization.population.Population;
import eva2.tools.Pair;
import eva2.tools.SelectedTag;
import eva2.tools.StringTools;
import eva2.tools.Tag;
import eva2.util.annotation.Description;
import eva2.util.annotation.Parameter;
import java.beans.*;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
@ -253,9 +252,9 @@ public class BeanInspector {
* found. This of course means that the caller is unable to distinguish
* between "method not found" and "method found and it returned null".
*
* @param obj
* @param mName
* @param args
* @param obj Target object
* @param mName Method name
* @param args Array of arguments
* @return the return value of the called method or null
*/
public static Object callIfAvailable(Object obj, String mName, Object[] args) {
@ -830,63 +829,20 @@ public class BeanInspector {
}
}
/**
* This method simply looks for an appropriate tiptext
*
* @param name The name of the property
* @param methods A list of methods to search.
* @param target The target object
* @return String for the ToolTip.
*/
public static String getToolTipText(String name, MethodDescriptor[] methods, Object target, boolean stripToolTipToFirstPoint, int toHTMLLen) {
String result = "";
String tipName = name + "TipText";
// Find by deprecated TipText method
for (MethodDescriptor method : methods) {
String mname = method.getDisplayName();
Method meth = method.getMethod();
if (mname.equals(tipName)) {
if (meth.getReturnType().equals(String.class)) {
try {
Object args[] = {};
String tempTip = (String) (meth.invoke(target, args));
result = tempTip;
if (stripToolTipToFirstPoint) {
int ci = tempTip.indexOf('.');
if (ci > 0) {
result = tempTip.substring(0, ci);
}
}
} catch (Exception ex) {
LOGGER.log(Level.FINE, "Error calling TipText method.", ex);
}
break;
}
}
} // end for looking for tiptext
if(result.isEmpty()) {
LOGGER.fine(String.format("No ToolTip for %s.%s available.", target.getClass().getName(), name));
}
if (toHTMLLen > 0) {
return StringTools.toHTML(result, toHTMLLen);
} else {
return result;
}
}
/**
* This method simply looks for an appropriate tool tip text
*
* @param name The name of the property
* @param methods A list of methods to search.
* @param target The target object
* @param target The target object
* @param property {@code PropertyDescriptor} for the property
* @return String for the ToolTip.
*/
public static String getToolTipText(String name, MethodDescriptor[] methods, Object target) {
return getToolTipText(name, methods, target, false, 0);
public static String getToolTipText(Object target, PropertyDescriptor property) {
// If the property's setter has the Parameter annotation use the description as tipText
if (property.getWriteMethod() != null && property.getWriteMethod().isAnnotationPresent(Parameter.class)) {
Parameter parameter = property.getWriteMethod().getAnnotation(Parameter.class);
return parameter.description();
} else {
return (String)callIfAvailable(target, property.getDisplayName().concat("TipText"), null);
}
}
}

View File

@ -9,14 +9,11 @@ import eva2.util.annotation.Parameter;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.beans.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -34,10 +31,6 @@ public final class PropertySheetPanel extends JPanel implements PropertyChangeLi
* Holds properties of the target.
*/
private PropertyDescriptor propertyDescriptors[];
/**
* Holds the methods of the target.
*/
private MethodDescriptor methodDescriptors[];
/**
* Holds property editors of the object.
*/
@ -214,9 +207,7 @@ public final class PropertySheetPanel extends JPanel implements PropertyChangeLi
targetObject = targ;
try {
BeanInfo bi = Introspector.getBeanInfo(targetObject.getClass());
propertyDescriptors = bi.getPropertyDescriptors();
methodDescriptors = bi.getMethodDescriptors();
} catch (IntrospectionException ex) {
LOGGER.log(Level.SEVERE, "Could not create editor for object.", ex);
return;
@ -281,13 +272,8 @@ public final class PropertySheetPanel extends JPanel implements PropertyChangeLi
continue;
}
// If the property's setter has the Parameter annotation use the description as tipText
if (propertyDescriptors[i].getWriteMethod() != null && propertyDescriptors[i].getWriteMethod().isAnnotationPresent(Parameter.class)) {
Parameter parameter = propertyDescriptors[i].getWriteMethod().getAnnotation(Parameter.class);
toolTips[itemIndex] = parameter.description();
} else {
toolTips[itemIndex] = BeanInspector.getToolTipText(name, methodDescriptors, targetObject);
}
toolTips[itemIndex] = BeanInspector.getToolTipText(targetObject, propertyDescriptors[i]);
itemIndex++;
views[i] = getView(propertyEditors[i]);
// We filter by this.. not necessarily the prettiest solution but it tends to work

View File

@ -261,13 +261,8 @@ public abstract class AbstractObjectEditor implements PropertyEditor, java.beans
result.propertyType = propertyDescriptor.getPropertyType();
result.name = propertyDescriptor.getDisplayName();
result.label = new JLabel(result.name, SwingConstants.RIGHT);
// If the property's setter has the Parameter annotation use the description as tipText
if (propertyDescriptor.getWriteMethod() != null && propertyDescriptor.getWriteMethod().isAnnotationPresent(Parameter.class)) {
Parameter parameter = propertyDescriptor.getWriteMethod().getAnnotation(Parameter.class);
result.tipText = parameter.description();
} else {
result.tipText = BeanInspector.getToolTipText(result.name, methods, target);
}
result.tipText = BeanInspector.getToolTipText(target, propertyDescriptor);
try {
result.value = result.getMethod.invoke(target, args);
result.editor = PropertyEditorProvider.findEditor(propertyDescriptor, result.value);

View File

@ -0,0 +1,66 @@
package eva2.gui;
import eva2.util.annotation.Parameter;
import org.junit.Test;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import static org.junit.Assert.*;
public class BeanInspectorTest {
private class DummyBean {
private int foo;
private int bar;
public void setFoo(int f) {
foo = f;
}
public int getFoo() {
return foo;
}
public String fooTipText() {
return "This is foo";
}
@Parameter(description = "This is bar")
public void setBar(int b) {
bar = b;
}
public int getBar() {
return bar;
}
}
@Test
public void testGetToolTipText() throws Exception {
DummyBean dummy = new DummyBean();
BeanInfo bi = Introspector.getBeanInfo(dummy.getClass());
PropertyDescriptor[] pds = bi.getPropertyDescriptors();
// bar, class, foo
assertEquals(3, pds.length);
// bar is 0
assertEquals("This is bar", BeanInspector.getToolTipText(dummy, pds[0]));
// foo is 2
assertEquals("This is foo", BeanInspector.getToolTipText(dummy, pds[2]));
}
@Test
public void testCallIfAvailable() throws Exception {
DummyBean dummy = new DummyBean();
dummy.setBar(12);
assertEquals(12, (int)BeanInspector.callIfAvailable(dummy, "getBar", null));
BeanInspector.callIfAvailable(dummy, "setFoo", new Object[]{42});
assertEquals(42, dummy.getFoo());
assertNull(BeanInspector.callIfAvailable(dummy, "derp", null));
}
}