Zobrazují se příspěvky se štítkemJava. Zobrazit všechny příspěvky
Zobrazují se příspěvky se štítkemJava. Zobrazit všechny příspěvky

pondělí 21. října 2013

Java Swing: Change Global Action Key

Java Swing Look and Feel defines it's own actions and register them globally on key strokes. It may happen, such a global keystroke is the same you need to use for own action. E.g. you define an action hooked on F8 key in the JPanel. But when the user has focused a JTable inside the JPanel and hit F8, then it still triggers the "focusHeader" action instead your action. One solution is to put your action on every component in the JPanel. Or you can change default keys globally:

private static void reregisterGlobalKeys() {
 // F8 to Ctrl+F8
 reregisterGlobalKey("Table.ancestorInputMap", KeyStroke.getKeyStroke(KeyEvent.VK_F8), KeyStroke.getKeyStroke(KeyEvent.VK_F8, KeyEvent.CTRL_DOWN_MASK));
 reregisterGlobalKey("SplitPane.ancestorInputMap", KeyStroke.getKeyStroke(KeyEvent.VK_F8), KeyStroke.getKeyStroke(KeyEvent.VK_F8, KeyEvent.CTRL_DOWN_MASK));
}

private static void reregisterGlobalKey(String uiManagerKey, KeyStroke oldKeyStroke, KeyStroke newKeyStroke) {
 Object inputMapObj = UIManager.get(uiManagerKey);
 if (inputMapObj == null || !(inputMapObj instanceof InputMap)) {
  System.err.println("reregisterGlobalKey inputMap not found: " + uiManagerKey);
  return;
 }
 InputMap inputMap = (InputMap) inputMapObj;
 String actionCommand = (String) inputMap.get(oldKeyStroke);
 if (actionCommand == null) {
  System.err.println("reregisterGlobalKey actionCommand not found for inputMap: " + uiManagerKey + " keyStroke: " + oldKeyStroke);
  return;
 }
 inputMap.remove(oldKeyStroke);
 if (newKeyStroke != null) {
  inputMap.put(newKeyStroke, actionCommand);
 }
}

Keep in mind that these uiManagerKeys and key strokes are Look and Feel dependend.

čtvrtek 25. dubna 2013

Guava ClassPath Suite

Sometimes, one needs to run just a subset of JUnit test. The very good library ClassPathSuite (cpsuite) address this problem and is able to select test based on a class name, or another class properties (annotation, super class, etc.)

In our project, we have needed a little bit more complicated filter conditions than it offers. Afters studying ClassPathSuite and  Google Guava internals, I just figure out, some kind of more flexible ClassPathSuite can be created using Guava Predicate and ClassPath classes. So I have coded just one core file, GuavaClassPathSuite which does what we need - scans the class path for JUnit tests and filter them by user defined Predicates. I have pushed the solution to GitHub as gcpsuite, Guava ClassPath Suite, project. (Not very distinct name, but points to the Guava ClassPath). Either use it as a library, or simply copy&paste the GuavaClassPathSuite.java, write your predicates and enjoy!

čtvrtek 13. září 2012

Java Swing: MigLayout, JScrollPane and JTextField Showing Horizontal Scrollbar

MigLayout is a great layout manager for Java Swing. However, it needs some time to discover it's nooks and crannies. One common problem is with components inside JScrollPane.

We place all components inside the JPanel, which has a JScrollPane as parent. And we use MigLayout mostly with fill and grow parameters. Such layout ensures that a user can access all components by scrolling when she has a small screen.

But I have a faces a problem with JTextField containing a very long text. I usually use MigLayuot

growx, width 50::

constraints for text fields. However, when a text files contains a very long String, then it forces JScrollPane to to enlarge it's width and show the horizontal scrollbar. The user usually need the text field to be as long as possible, but not to overflow the screen width, if possible. After a while, I have found a proper and simple solution, just set the preferred size as minimum:

growx, width 50:50:

Note: I have described the problem using component constraints, the solution is similar with row constraints

fill, grow, 50:50:

pátek 20. ledna 2012

Eclipse: Manual and Automatic Code Formatting

I like automatic code formatting in the Eclipse IDE. For Java see the settings in Window -> Preferences -> Java -> Code Style -> Formatter. I Just hit CTRL+SHIFT+F time from time and let the IDE do the boring job for me.

Occasionally, I want the different result then the Eclipse Formatter produce. Especially when a method has many parameters. Sometimes I like to have all of them on one line, sometimes I like to break them into multiple times. Of course, the Eclipse automatic formatter cannot be configured to meet wishes.

The Eclipse formatter has a nice option On/Off Tags:
  • @formatter:off
  • @formatter:on
But it's tedious and ugly to write these tags into the code. (Even Code templates does not simply usage of On/Off Tags very much). Much more simpler solution is to append the Java comment // ant the and of line, which you want to break. For example, I have configured the Eclipse formatter to have all method parameters on a single line. But when I write
this.someMethod(param1, //
    param2, //
    param3, //
    param4, //
    param5);
Then the CTRL+SHIFT+F reformatting let this piece of the code as is.

úterý 31. května 2011

Java zsync

The very first implementation of zsync in Java: http://sourceforge.net/projects/jazsync/. It has no release yet, check out the source code from SVN.

středa 11. května 2011

ZK-DL Released!

ZK-DL, an extension to the ZKoss framework (ZK 5), has been released under LGPL just a few weeks ago!. ZK_DL provides especially:

  1. Integration with Spring.
  2. Flexible listbox, combobox and lovbox (a kind of combobox) components with automatic sorting and searching build upon the Hibernate Criteria API.
  3. And much more, see http://zk.datalite.cz/zk-dl.

The documentation is at http://zk.datalite.cz/zk-dl and the source code can be found at http://code.google.com/p/zk-dl/.

I have used DL-ZK with EJB3 on JBoss 5.1 successfully. So I had not taken the advantage of ZK-DL Spring integration (IMHO better than original ZK Spring integration). Anyway the ZK-DL listobox, combobox and lovbox components has greatly simplified our development and provided a rich yet simple interface to our users.

Many thanks to Jiří Bubník and Karel Čemus for their valuable help and cooperation. I wish DL-ZK long life and have many users!

čtvrtek 10. března 2011

JPA Queries - A Few Methods to Simplify the Life with JPA/JPQL

The JPA Query.getSingleResult() method is usable only when the JPQL has exactly one result. Yeah, you can catch NoResultException or NonUniqueResultException exceptions, but the try ... catch block make the code less readable. So I have coded three static method to overcome this JPA deficiency:
public class Queries {
    /**
     * @param query
     * @return {@code true}, the query has one or more results, otherwise returns {@code false}.
     */
    public static boolean hasAnyResult(Query query) {
        query.setMaxResults(1);
        final List<?> list = query.getResultList();
        return list.size() > 0;
    }

    /**
     * @param query
     * @return The only one result or {@code null}, when the query has no result.
     * @throws NonUniqueResultException
     *             when the query has more than one result.
     */
    public static Object singleResultOrNull(Query query) {
        query.setMaxResults(2);
        final List<?> list = query.getResultList();
        final int size = list.size();
        if (size <= 0) {
            return null;
        }
        if (size > 1) {
            throw new NonUniqueResultException("result returns more than one element");
        }

        // return first element from the list
        return list.get(0);
    }

    /**
     * @param query
     * @return The first result or {@code null}, when the query has no result.
     */
    public static Object firstResultOrNull(Query query) {
        query.setMaxResults(1);
        final List<?> list = query.getResultList();
        final int size = list.size();
        if (size <= 0) {
            return null;
        }
        if (size > 1) { // should not happened, Hibernate bug?
            Logger.getLogger(Queries.class).error("firstResultOrNull more rows returned. setMaxResults(1) does not work?");
        }

        return list.get(0);
    }

    /**
     * Constructor. No instances.
     */
    private Queries() {
    }
}
The hasAnyResult is the boolean query method - you may test if something exists in database. The best is to use it with some JPQL query returning only id of an entity, e.g.:
Queries.hasAnyResult(em.createQuery("SELECT id FROM Person WHERE ..."));
I think the usage of the singleResultOrNull is obvious. Use it, when you are sure the result returns one or no result. The exception NonUniqueResultException should warn you that something is wrong, wither the query or the data.

The firstResultOrNull returns just the first result of the query. Typically, use it with queries with "ORDER BY" statement, like "get the Person with lowest/highest salary."

úterý 15. února 2011

Oracle Like Decode in JasperReports

Oracle SQL has a nice function DECODE. I am using Java Beans data source for JasperReports and sometimes I have missed such a function in JasperReports expressions. One can achieve the same functionality by a ternary operator ? :. But it is not nice for more complicated conditions. So I have created my own Java decode:
public static Object decode(Object value, Object... arg) {
  if (arg == null) {
    return value;
  }
  int n = arg.length;
  for (int i = 0; i < n; i+=2) {
    int j = i + 1;
    if (j >= n) {
      // only the default remains
      return arg[i];
    }
    if (equal(value, arg[i])) {
      return arg[j];
    }
  }
  // no match found, no default is specified
  return value;
}
Then import it into JasperReports *.jrxml report by:
<import value="static com.mypackage.MyClass.decode"/>
And use it in the report like:
"" + decode(count, 0, "no one", 1, "one", 2, "two", "too many: " + count);

úterý 25. ledna 2011

ZK and Converting to a Negative Number

When I was working with ZK Web Framework, I have needed to convert some number to the negatives for the databinding. I have created a new type converter NumberNegativeConverter. Hope, someone else may find it useful, see http://sites.google.com/site/xmedeko/code/zk-web-framework/numbernegativeconverter.

pátek 3. prosince 2010

Java: A Simple Assert Class for Design By Contract Checks

Very often, the programmer are lazy to include design by contract checks into the code. That means argument checking in the beginning of the method, checking of a wrong state in the method body, etc. The Java assert construct cannot be used for this purpose, since it is switched off by default (one has tu run java -ea to switch on the Java asserts). To simplify the design by contract checks, I have made three simple static methods:

/**
 * A static class for simple run-time checks. The methods from this class may (and should) be used to check arguments
 * and code for design-by-contract.
 * <p>
 * These are the methods for lazy programmers. If you like to write more complicated messages (and God bless you for
 * that), use the classic {@code if (...) throw ... } way.
 * <p>
 * It is not possible to switch off these checks, do not use them for any memory or CPU consuming operations.
 * 
 * @author xmedeko
 * 
 */
public class Assert {

 /**
  * Check, that the condition is {@code true}.
  * <p>
  * Usage:
  * 
  * <pre>
  * Assert.state(i &lt;= maxIter, &quot;iteration number exceeded&quot;);
  * </pre>
  * 
  * @param check
  * @param message
  *            An error message.
  */
 public static void state(boolean check, String message) {
  if (check)
   return;
  throw new IllegalStateException(message);
 }

 /**
  * Check, that the object is not null. 
  * <p>
  * Usage:
  * 
  * <pre>
  * Assert.notNull(entity, &quot;entity&quot;);
  * </pre>
  * 
  * 
  * @param o
  * @param message
  *            An error message.
  */
 public static void notNull(Object o, String message) {
  if (o != null)
   return;
  throw new NullPointerException(message);
 }

 /**
  * Check, that the argument fullfills the given condition.
  * <p>
  * Usage:
  * 
  * <pre>
  * Assert.argument(from &gt; 0, &quot;from has to be greater then zero&quot;);
  * </pre>
  * 
  * @param check
  * @param message
  *            An error message.
  */
 public static void argument(boolean check, String message) {
  if (check)
   return;
  throw new IllegalArgumentException(message);
 }

 /** No instances. */
 private Assert() {
  throw new UnsupportedOperationException();
 }

}

Note, to check argument for not null value, do not use
Assert.argument(obj != null, "obj is null");
but use instead:
Assert.argument(obj != null, "obj");

Also, do not put any String concatenation or other operation into the argument. These are the methods for lazy programmers. If you like to write more complicated messages (and God bless you for that), use the classic if (...) throw ... way.

Update 29.3.2011: I have just found out that Spring frameworks has org.springframework.util.Assert class, too.
Update 30.7.2012: Google Guava has a very similar solution in the class Preconditions.

čtvrtek 2. prosince 2010

ZK Calendar Colors

Unfortunately, colours for the ZK Calendar has to be specified in the Java. They cannot be set in a CSS file. Because writing hexadecimal colour codes directly in the code is error prone, I have created a simple enum constant with a set of ZK Calendar colors:

public enum ZkCalendarsColor  {
 GREY("#B4BAB7", "#72706F"),
 GREEN("#4CB052", "#0D7813"),
 KHAKI("#BFBF4D", "#88880E"),
 PURPLE("#B373B3", "#7A367A"),
 RED("#D96666", "#A32929"),
 BLUE("#668CD9", "#3467CE");
 
 private String contentColor;
 private String headerColor;
 
 private ZkCalendarsColor(String contentColor, String headerColor) {
  this.contentColor = contentColor;
  this.headerColor = headerColor;
 }

 public String getContentColor() {
  return contentColor;
 }

 public String getHeaderColor() {
  return headerColor;
 }
}

úterý 31. srpna 2010

JasperReports PDF Font Mapping

Are your font bold and italic font properties lost when you export your JasperReports report into the PDF? Do you wander, why PDF preview in the iReport has all fonts right? Check this link out, mate: http://sites.google.com/site/xmedeko/code/misc/jasperreports-pdf-font-mapping

čtvrtek 5. srpna 2010

JBoss and HSQLDB 2.0.0

HSQLBD 2.0 GA has been released on 7 June 2010 with a lot of new cool features. I have needed some of them for my JBoss 5.1.0GA, so I have just replaced the library common/lib/hsqldb.jar and voilà, it runs almost without any problem (Hibernate/JPA usage) as before. I have made just one small change, see bellow. Even the HSQLDB Database Manager starts from JMX console. My personal feeling is that the version 2.0 is a little bit faster than 1.8.0, but I have not made any benchmarks.

The HSQLDB 2.0 upgrade notes:
  1. In my import.sql I had to change all timestamp formats from '2010-08-06 8:00:00' to '2010-08-06 08:00:00', i.e. I had to zero pad the hours into two decimal places.

středa 21. července 2010

ZK 3.6 CSRF Protection

Unfortunately, ZK Web Framework version 3.6 and earlier lack any CSRF protection. i have created a very basic event filter to tackle this issue. Hope, someone else may find it useful, see http://sites.google.com/site/xmedeko/code/zk-web-framework/zk-3-6-csrf-protection. It is just a very first version, leave me a comment, if you have some suggestion.

Update 15th Sep 2010: Improved protection and logging.

středa 14. července 2010

ZK - Converting Null Values

A common problem in database programming is to display some meaningful labels instead of NULL values in the list of database rows. Fortunately, ZK Web Framework, offers a comfortable TypeConverter class to address this issue. I have created a general type converter NullToLabelConverter to convert NULL values into any localised text. Hope, someone else may find it useful, see http://sites.google.com/site/xmedeko/code/zk-web-framework/nulltolabelconverter.

středa 19. května 2010

ZK Logging in ZUL zscript Code

I have created a very simple class to simplify getting Java logger for the ZUL file (see ZK Web Framework). It is targeted especially for the JBoss logging org.jboss.logging.Logger, but can be easily changed for java.util.logging or any other logging library. Hope, someone else may find it useful, see http://sites.google.com/site/xmedeko/code/zk-web-framework/zul-logging.

středa 7. dubna 2010

ZK and Very Long Strings

When I was working with ZK Web Framework, I have needed to display just a beginning of a very long String in a listbox. I have created a new type converter StringTrimConverter, which trims a string to the specified length. Hope, someone else may find it useful, see http://sites.google.com/site/xmedeko/code/zk-web-framework/stringtrimconverter.

čtvrtek 11. března 2010

JPA: Mapping from Enum to Char(1)

Very often, enumerations are stored in SQL databases as char(1) columns. However, JPA annotation Enumerated allows mapping from Java Enum type into javax.persistence.EnumType.STRING (i.e. SQL type VARCHAR) or javax.persistence.EnumType.ORDINAL (i.e. SQL type INTERGER) only.

I have read a few rather complicated advices, how to make a mapping from general Java Enum type into SQL char(1) in Hibernate. After a while, I have found out, that when all constant names in the Enum have length just character, one can make an easy JPA mapping:
@Basic(optional = false)
@Enumerated(EnumType.STRING)
@Column(nullable = false, columnDefinition = "char(1) default 'A'")
private FruitType fruit_type = FruitType.A;
So, the FruitType may be:
public enum FruitType {
  /** Apples */
  A,
  /** Apricots */
  B,
  /** Cherries */
  C,
  /** Pears */
  P;
}

Well, it has a disadvantage, that "apricots" are represented by FruitType.B. But all modern IDE (like Eclipse) shows Javadoc when the developer types the code. Beside the simplicity, the other great advantage is, that the application developer knows that the "apricots" are represented by 'B' in the database. So, it is easier for the developer to write JPQL/HQL/SQL queries. When you a complicated JPA/Hibernate mapping from some type FruitTypeLong.APPRICOT to the 'B' in database, then it will be just confusing after some time to write JPQL/HQL/SQL queries.

čtvrtek 11. února 2010

Java Web Container: Hunting Redeploy Memory Leaks

Using a ThreadLocal in a web application (WAR) may simplify the development, but one must have a very deep understanding of the web container (e.g. Tomcat) internals and Java class loading to avoid memory leaks when WAR is redeployed. See


The problem might be hidden deep in any library used by the application. To check, if the redeploy memory leak occurs is simple with Eclipse Memory Analyzer (MAT). Just redeploy the WAR several times, make a heap dump (e.g. by jmap or jconsole). Then open the heap dump in MAT and click the link Duplicate Classes: List classes loaded by more than one class loader. If there are some duplicated classes, then you have a memory leak.

Tip: how to clean ThreadLocals in a servlet: http://www.dewavrin.info/?p=196

středa 20. ledna 2010

Eclipse: An error occurred while collecting items to be installed

I have tried to update my Eclipse 3.5 Galileo plugins, and all what I have seen was:
An error occurred while collecting items to be installed
No repository found containing: org.eclipse.net4j.jms.api/osgi.bundle/1.0.0.v200806180305
I could not find the solution for a couple of hours. Finally, BINGO!, reinstalling EclipseLink packages solved it.

Just go to Help -> Install New Software ->, choose Galile update site Galileo - http://download.eclipse.org/releases/galileo and search for all installed EclipseLink packages. (You must uncheck Hide items that are already installed also.) The installed packages have grey icon. Just check them, press Next, and then Finish. Restart the Eclipse and then try to update plugins again.