Thursday, 26 November 2015

JTable: overriding default behaviours

JTable and Tab/Shift-Tab

By default when the focus in in a JTable then Tab changes focus to the next cell. If the cell is the last one then the 1st cell is focused. Shift-Tab does the opposite.

disable Tab/Shift-Tab

    KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "none");
    KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK), "none");


moving to next component

Assuming we want to move out of the JTable to the next/prev UI component (instead of the next/prev cell) we can do the following to modify the default behaviour:

 Set<AWTKeyStroke> forward = new HashSet<AWTKeyStroke>(
myJTable.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forward);
Set<AWTKeyStroke> backward = new HashSet<AWTKeyStroke>(
backward.add(KeyStroke.getKeyStroke("shift TAB"));
myJTable.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backward);

// create the policy which determines what will be the next/prev UI component on Tab/Shift-Tab   
class TabFocusTraversalPolicy extends DefaultFocusTraversalPolicy  {

      private static final long serialVersionUID = 1L;
      public Component getComponentAfter(Container container, Component component) {
          Component nextComponent = null;
          if(...) {
              nextComponent = ...;
          } else if(component == ...) {
              nextComponent = ...;
          }  else {
              nextComponent = super.getComponentAfter(container, component);
          return nextComponent;

      public Component getComponentBefore(Container container, Component component) {
          Component nextComponent = null;
          if(...) {
              nextComponent = ...;
          } else if(...) {
              nextComponent = ...;
         }  else {
              nextComponent = super.getComponentBefore(container, component);
          return nextComponent;

        public Component getDefaultComponent(Container container) {
            return super.getDefaultComponent(container);

        public Component getFirstComponent(Container container) {
            return super.getFirstComponent(container);

        public Component getLastComponent(Container container) {
            return super.getLastComponent(container);
// install the policy to the JTable
 myTable.setFocusCycleRoot(true); // if not true then the policy is not triggered


JTable and Enter

Enter: selects next row

By default when we click Enter in a JTable where a row is selected then the next row gets the focus.

In order to disable this do the following:
myJTable.getActionMap().put("Enter", new AbstractAction() {
        private static final long serialVersionUID = 1L;

        public void actionPerformed(ActionEvent ae) {
            // override default behaviour which selects the next row

Saturday, 12 September 2015

How to sort an Array of Strings

This is a silly mistake I did..

Don't use
Arrays.sort(strs.toArray(new String[0]));

Instead use the following:

Wednesday, 9 September 2015

MongoDB: The ugly things

Here is a list of all the ugly things that I have found so far regarding MongoDB:

Writes that return errors to the client due to wtimeout may in fact succeed (link)

Regarding the option wtimeout:
This option specifies a time limit, in milliseconds, for the write concern. wtimeout is only applicable for w values greater than 1.
wtimeout causes write operations to return with an error after the specified limit, even if the required write concern will eventually succeed. When these write operations return, MongoDB does not undo successful data modifications performed before the write concern exceeded the wtimeout time limit.
If you do not specify the wtimeout option and the level of write concern is unachievable, the write operation will block indefinitely. Specifying a wtimeout value of 0 is equivalent to a write concern without the wtimeout option.


Maximum document size is 16MB (link)

The maximum BSON document size is 16 megabytes.

A client may think that a write was successful but it wasn't!

Even with (w=1 or w='majority') and (j=1), it is possible to wind up rolling back a committed write to the primary on failover (link) and the client may think that the write was successful but it wasn't!

  • The network TCP connection between the application and the server was reset after the server received a write but before a response could be sent.
  • The MongoDB server terminates between receiving the write and responding to it.
  • The network fails between the time of the write and the time the client receives a response to the write. 

w='majority' doesn't resolve the problem because the parameter j doesn't affect the replicas (link):
Requiring journaled write concern in a replica set only requires a journal commit of the write operation to the primary of the set regardless of the level of replica acknowledged write concern.
 You can find more information on the official MongoDB docs and a relative StackOverflow post.

A client doesn't get a response after a write and thinks that the write didn't happen but happened!

Usually the MongoDB client (e.g. Java driver) tackles the following problems transparently to the developer:
  • insert isn't acknowledged --> re-execute it (provided the _id was set by the client and is the same on both executions)
  • update isn't acknowledged --> treat it as deletion and insertion 
  • deletion isn't acknowledged --> idempotent; re-execute it
  • find isn't acknowledged --> idempotent; re-execute it

During failover writes cannot occur (i.e. they fail)

When the primary node fails, another is elected from its replica set. During the election the client cannot write. This is because in MongoDB only the primary node can accept writes.

Therefore you may have to guard your code and try to re-execute the failed write.
By the way can the MongoDB driver do anything about it?