javaswinglistenermousemousemotionlistener

Resize jpopupmenu using Mouse Adapter


I'm using the Swing bits library to add filters to my jtable column headers. The library works as expected, but the jpopupmenu that appears on a column right click does not re-size. (re-sizing allowed only from the bottom right corner using a mouse drag) Screenshot shown below.

Swing Bits column filter jpopupmenu

I got hold of the swing bits library source code to try and figure out this issue, This is what I found.

The jpopupmenu resizing is handled by a MouseMotionListner and a MouseListener. Basically a MouseDragged method gets called continuously, which should update the jpopupmenu size until the mouse is released. The code is shown below.

    public void mouseDragged(MouseEvent e) {

    //System.out.println("test_0"); 

    if ( !isResizing ){
    //System.out.println("test_3"); 
    return;}

    Point p = toScreen(e);

    int dx = p.x - mouseStart.x;
    int dy = p.y - mouseStart.y;

    Dimension minDim = menu.getMinimumSize();
    Dimension newDim = new Dimension(startSize.width + dx, startSize.height + dy);

    if ( newDim.width >= minDim.width && newDim.height >= minDim.height) {
        menu.setPopupSize(newDim);
        //System.out.println("test_1");         
    }
    //System.out.println("test_2");
}

Through a bit of debugging, I realized the problem lies in the menu.setPopUpSize(newDim) method call.

Without this bit of code, the mouseDragged() method gets called continuously when I try to re-size the jpopupmenu. (as it should) Figured this out using the commented print statements.

With menu.setPopUpSize(newDim) included, the mouseDragged() method is only called once. For some reason, the mouse drag event is not registered again after the call to the setPopUpSize method. Note that the method does NOT return. On that single call, the setPopUpSize() slightly re-sizes the popupmenu with the updated newDim value. Ideally the mouseDragged() method should be called repeatedly until the user releases the mouse drag action, re-sizing the popupmenu continuously.

One work around I figured is to declare the newDim value publicly and call the setPopUpSize(newDim) method inside the mouseReleased() method. This gets the final coordinates from the mouse drag and uses that to re-size the popup menu. But this does not show the dragging of the edges for the user, which is very inconvenient.

Any help would be highly appreciated.

Execution without the setPopUpSize(newDim) method:

test_0
test_1
test_2
test_0
test_1
test_2 ...

this pattern is repeated till the mouse drag is released.

Execution with the setPopUpSize(newDim) method:

test_0
test_1
test_2

The mouseDragged() method is called only once.


Solution

  • Well! Turns out the problem was with the java version. I was running java 1.8.0_25 (x64) , updated it to the latest (1.8.0_66) and the issue has disappeared. The library works fine. More information about this issue can be found here.

    https://github.com/eugener/oxbow/issues/44