javaswingjmenujpopup

How to force a scrollable popup menu to scroll to a specific menu item?


I have a Java Swing application, and i have created a special sub JPopupMenu for it that is scrollable so a user can simply scroll through it and select one item from it, like in this screenshot :

enter image description here

I have used the code from this post and i have pasted it here so you can check it: http://codeshare.io/Jgqa7

Now if the user has opened this sub-menu for an item that he has already made a selection for it before from that sub-menu then i want to automatically scroll to the selected item to show it, just like the ensureIndexIsVisible(...) method for a JList. I have spent some time trying to figure this out but with no progress. So, is there a way to accomplish this ?

--------------------------------------------------------> Edit: The code i'm using :

I have tried using this code to force scroll to the item "invented" in the scrollable menu but it failed :

JScrollPopupMenu pm = (JScrollPopupMenu)myPopupMenu.getPopupMenu();

for( Component comp: myPopupMenu.getMenuComponents() ) {
    if( comp instanceof JRadioButtonMenuItem ) {
        JRadioButtonMenuItem rb = (JRadioButtonMenuItem)comp;

        if( rb.getText().equals( "invented" ) ) {
            myPopupMenu.scrollRectToVisible( rb.getBounds() );  // Does nothing.
            pm.setSelected( rb );  // Does nothing.
        }
    }
}

For some reason it doesn't scroll to the item i want !


Solution

  • I needed a solution to scroll as well. Since I did not find a scrollpane, I needed to implement my own scrollRectToVisible method in JScrollPopupMenu:

    @Override
    public void scrollRectToVisible(Rectangle t){
        // need to adjust scrollbar position
        if (t.getY()<0){
            // scroll up
            JScrollBar scrollBar = getScrollBar();
            scrollBar.setValue(scrollBar.getValue() + (int)(t.getY()));
        }else if (t.getY()+t.getHeight()>getBounds().getHeight()){
            // scroll down
            JScrollBar scrollBar = getScrollBar();
            scrollBar.setValue(scrollBar.getValue() - (int)(getBounds().getHeight()-t.getY()-t.getHeight()));
        }
        doLayout();
        repaint();
    }
    

    Calling this with the bounds of the clicked JMenuItem (I used a mouselistener with mouseentered) scrolls the panel so that the item is visible.

    Hope it helps!