01 February 2010 | Uncategorized |Kevin Rogiers
The following feature has been added to the GenericSelectorForm: setting initial default values and setting default values after the form is cleared.
This feature might come in handy when you want to have some default values entered when a selector is shown, and when you want these default values to be retained after the clear button is clicked. Some similar features already exist (e.g. runFastProperties, @PropertyEvents, and the GenericSelectorFormWithReadOnlyFields class), but these don’t quite provide the desired functionality.
The new method is to add a GenericSelectorDefaultValuesProvider to your SelectorForm. This interface provides two methods:
/**
* Sets default values after clear command is called
* @param formModel
*/
void setDefaultValuesAfterClear(FormModel formModel);
/**
* Sets initial default values
* @param formModel
*/
void setInitialDefaultValues(FormModel formModel);
You have to create a class which implements this interface, and set it on your selectorformDescriptor bean, like this:
Note:
– For setDefaultValuesAfterClear(FormModel): Create a new FormObject, set the default values on it and set that new formObject on the specified FormModel. If you use FormModelUtils, or if you set the value on the existing formObject, you might get problems with the revert-icon.
– For setInitialDefaultValues(FormModel): You can use whatever method you like. Either use FormModelUtils, or update the existing FormObject, or create a new one.
No Comments
20 January 2010 | Uncategorized |Jan Mariën
for all of those who are wondering what the TSVNCache.exe process is doing, and why the windows explorer is rather slow after installing Tortoise SVN.
By default, TortoiseSVN looks in every folder you open for SVN information. It tries to get SVN info for all files in the folder you’re opening because it wants to show those nice svn status icons for each file. But the directories with svn info are probably all in c:\projects (or similar).
You can configure TortoiseSVN which directories should be omitted when looking for SVN info.
- Right-click on folder or file and select “TortoiseSVN -> Settings…
- go to the Context Menu Settings screen
- insert all directories that contain no folders with SVN info: I did a “dir /B /AD c:\” to get all the directories on my disk and removed c:\projects and c:\workspaces
- optional: complain you can’t use “include paths” and “exclude paths” anymore, this was possible in previous versions of TortoiseSVN
No Comments
12 January 2010 | Uncategorized |Boris Vereertbrugghen
Since our business didn’t want us to use floating points any more, but something more precise, we decided to start using BigDecimals instead of doubles.
Our calculations are actually fairly straight forward. Something like
private double calc(double x, double y, double previous){
return previous * (x/y);
}
So I converted the code to BigDecimal (remark x and y are coming from somewhere else so they are still double (for now))
private BigDecimal calc(double x, double y, BigDecimal previous){
return previous.multiply(new BigDecimal(x).divide(new BigDecimal(y));
}
“Ah quite easy” you would think, but when running this code I sometimes get a java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
This happens when, for example, we use x = 2 and y = 3. 2/3 is 0.666666666…. (endless). So BigDecimal doesn’t know what to do and gives a runTimeException.
This means we should actually use some rounding method.
private BigDecimal calc(double x, double y, BigDecimal previous){
return new BigDecimal(x).divide(new BigDecimal(y),RoundingMode.HALF_UP).multiply(previous);
}
So now we don’t get the ArithmeticException any more but the result with 2,3 and 1 now gives 1, while we expect somthing like 0.6666666666…7
2/3 is 0.6… rounded this is 1. So this is still not what we wanted.
What you can do now is:
- define the scale you want to have after division (amount of decimals after comma)
- Use a MathContext (and basically defining percision and rounding mode with that)
Some examples:
|
| 2/3 |
2000/3 |
0.2/0.3 |
| scale = 5 |
0.66667 |
666.66667 |
0.66667 |
| mathContext (presision=5) |
0.66667 |
666.67 |
0.66667 |
| only rounding |
1 |
667 |
0.666666666666666728345723590286476750563174908436298048 |
When using only the round we discover another problem: when converting double to BigDecimal the BigDecimal is not completely the number we meant to have. Because of this 0.2/0.3 seems quite exact but it is actually wrong. This is caused by the fact that 0.3 is actually 0.299999999999999988897769753748… this is caused by the nature of double values). So to be correct, we should/can actually also round the original starting numbers.
Since we also have a limited amount of numbers after the comma which are interesting for us, I ended up to convert every number before using it to a number with a certain scale. Then we don’t have to care any more about this scale or precision when multiplying and dividing (however still about the rounding method).
So finally I got this method:
private static BigDecimal calc(double x, double y, BigDecimal previous){
BigDecimal bigX = new BigDecimal(x).setScale(5, RoundingMode.HALF_UP);
BigDecimal bigY = new BigDecimal(y).setScale(5, RoundingMode.HALF_UP);
return bigX.divide(bigY,RoundingMode.HALF_UP).multiply(previous);
}
One last thing:
new BigDecimal(1).equals(new BigDecimal(1).setScale(10)) returns false.
Basically we are comparing 1 and 1.0000000000 here. These two are not the same!
No Comments
22 December 2009 | Java |Youri De Bondt
The other day I tried to perform the following code:
public @interface MyAnn {
String value();
}
@MyAnn(value = "foo")
public class MyClass {
}
..
MyClass.class.getAnnotation(MyAnn.class).value();
This gave me a NullPointerException because the annotation was not found.
I cursed, I googled, and I felt stupid for a whole day
Later, I figured out it has something to do with retention. It’s an annotation which tells the VM how long the annotation has to be retained.
So the solution to my problem was just setting the right retention policy on my annotation:
@Retention(Retention.RUNTIME)
public @interface MyAnn {
String value();
}
For more info refer to the javadoc: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/annotation/Retention.html
Source: http://java.nullpointer.be/2009/12/annotations-using-reflection.html
No Comments
14 December 2009 | Camel, Java |Steven Verhaegen
Jaxb is part of the jdk since jdk version 6. The earliest versions of the jdk 6 (update 1 till 3) have jaxb 2.0 included. The later versions of jdk 6 make use of jaxb 2.1.
Our pearlchain application makes use of camel which on its turn depends on jaxb version 2.1. In order to be compatible with java version 5 we’ve added a maven dependency to this jaxb 2.1 jar. When running the application with java 5 we’ve encountered no problems however when running the application with jdk 6 some developers got the following error :
java.lang.LinkageError: JAXB 2.0 API is being loaded from the bootstrap classloader, but this RI (from jar:file:/C:/Documents%20and%20Settings/steven/.m2/repository/com/sun/xml/bind/jaxb-impl/2.1.10/jaxb-impl-2.1.10.jar!/com/sun/xml/bind/v2/model/impl/ModelBuilder.class) needs 2.1 API. Use the endorsed directory mechanism to place jaxb-api.jar in the bootstrap classloader. (See http://java.sun.com/j2se/1.5.0/docs/guide/standards/)
Those developers were running the application with an earlier version of jdk 6 (update 1 -3).
There are 2 solutions:
- update jdk6 to at least jdk update 4 release
- use the guideline in the error message : override jaxb 2.0 and put jaxb 2.1 jar before rt.jar in bootclasspath. See http://java.sun.com/j2se/1.5.0/docs/guide/standards/ for more details about Endorsed Standards Override Mechanism.
We’ve chosen the first solution. However keep the second solution in mind when you can’t change the jdk6 to a more recent update release.
Cheers,
Steven
No Comments