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!