Adding vertical scroll to a JPopupMenu?

后端 未结 7 1738
余生分开走
余生分开走 2020-12-30 05:04

I would like to add a way to scroll through menu items in a JPopupMenu, much like scrolling through a list of items in a JComboBox.

Let\'s

相关标签:
7条回答
  • 2020-12-30 05:44

    Here's another one I found very useful: https://tips4java.wordpress.com/2009/02/01/menu-scroller/

    It can be called on JMenu or JPopupMenu like this:

    MenuScroller.setScrollerFor(menuInstance, 8, 125, 3, 1);

    0 讨论(0)
  • 2020-12-30 05:44

    As I needed popup menu with Scrollbar, I just reused popup menu from JComboBox. The trick was to put JComboBox in a JViewport, so that only arrow button was visible. You may make it just one pixel small or even lesser and use event from JideSplitButton to open popup.

    You may find code on github.

    0 讨论(0)
  • 2020-12-30 05:49

    In addition to the JScrollPopupMenu above, I also needed a a scroll bar in a sub menu (aka a "Pull Right Menu.") This seems to be a more common case. So I adapted a JMenu to use the JScrollPopupMenu called JScrollMenu:

    import javax.swing.Action;
    import javax.swing.JButton;
    import javax.swing.JMenu;
    import javax.swing.JMenuItem;
    import javax.swing.JPopupMenu;
    import javax.swing.MenuElement;
    import javax.swing.UIManager;
    import javax.swing.plaf.MenuItemUI;
    import javax.swing.plaf.PopupMenuUI;
    import java.awt.Component;
    import java.awt.ComponentOrientation;
    
    
    
    public class JScrollMenu extends JMenu {
        // Covers the one in the JMenu because the method that creates it in JMenu is private
        /** The popup menu portion of the menu.*/
        private JPopupMenu popupMenu;
    
    
        /**
         * Constructs a new <code>JMenu</code> with no text.
         */
        public JScrollMenu() {
            this("");
        }
    
        /**
         * Constructs a new <code>JMenu</code> with the supplied string as its text.
         *
         * @param s the text for the menu label
         */
        public JScrollMenu(String s) {
            super(s);
        }
    
        /**
         * Constructs a menu whose properties are taken from the <code>Action</code> supplied.
         *
         * @param a an <code>Action</code>
         */
        public JScrollMenu(Action a) {
            this();
            setAction(a);
        }
    
    
        /**
         * Lazily creates the popup menu. This method will create the popup using the <code>JScrollPopupMenu</code> class. 
         */
        protected void ensurePopupMenuCreated() {
            if(popupMenu == null) {
                this.popupMenu = new JScrollPopupMenu();
                popupMenu.setInvoker(this);
                popupListener = createWinListener(popupMenu);
            }
        }
    
    //////////////////////////////
    //// All of these methods are necessary because ensurePopupMenuCreated() is private in JMenu
    //////////////////////////////
        @Override
        public void updateUI() {
            setUI((MenuItemUI) UIManager.getUI(this));
    
            if(popupMenu != null) {
                popupMenu.setUI((PopupMenuUI) UIManager.getUI(popupMenu));
            }
        }
    
    
        @Override
        public boolean isPopupMenuVisible() {
            ensurePopupMenuCreated();
            return popupMenu.isVisible();
        }
    
    
        @Override
        public void setMenuLocation(int x, int y) {
            super.setMenuLocation(x, y);
            if(popupMenu != null) {
                popupMenu.setLocation(x, y);
            }
        }
    
        @Override
        public JMenuItem add(JMenuItem menuItem) {
            ensurePopupMenuCreated();
            return popupMenu.add(menuItem);
        }
    
        @Override
        public Component add(Component c) {
            ensurePopupMenuCreated();
            popupMenu.add(c);
            return c;
        }
    
        @Override
        public Component add(Component c, int index) {
            ensurePopupMenuCreated();
            popupMenu.add(c, index);
            return c;
        }
    
    
        @Override
        public void addSeparator() {
            ensurePopupMenuCreated();
            popupMenu.addSeparator();
        }
    
        @Override
        public void insert(String s, int pos) {
            if(pos < 0) {
                throw new IllegalArgumentException("index less than zero.");
            }
    
            ensurePopupMenuCreated();
            popupMenu.insert(new JMenuItem(s), pos);
        }
    
        @Override
        public JMenuItem insert(JMenuItem mi, int pos) {
            if(pos < 0) {
                throw new IllegalArgumentException("index less than zero.");
            }
            ensurePopupMenuCreated();
            popupMenu.insert(mi, pos);
            return mi;
        }
    
        @Override
        public JMenuItem insert(Action a, int pos) {
            if(pos < 0) {
                throw new IllegalArgumentException("index less than zero.");
            }
    
            ensurePopupMenuCreated();
            JMenuItem mi = new JMenuItem(a);
            mi.setHorizontalTextPosition(JButton.TRAILING);
            mi.setVerticalTextPosition(JButton.CENTER);
            popupMenu.insert(mi, pos);
            return mi;
        }
    
        @Override
        public void insertSeparator(int index) {
            if(index < 0) {
                throw new IllegalArgumentException("index less than zero.");
            }
    
            ensurePopupMenuCreated();
            popupMenu.insert(new JPopupMenu.Separator(), index);
        }
    
    
        @Override
        public void remove(JMenuItem item) {
            if(popupMenu != null){
                popupMenu.remove(item);
            }
        }
    
        @Override
        public void remove(int pos) {
            if(pos < 0) {
                throw new IllegalArgumentException("index less than zero.");
            }
            if(pos > getItemCount()) {
                throw new IllegalArgumentException("index greater than the number of items.");
            }
            if(popupMenu != null){
                popupMenu.remove(pos);
            }
        }
    
        @Override
        public void remove(Component c) {
            if(popupMenu != null){
                popupMenu.remove(c);
            }
        }
    
        @Override
        public void removeAll() {
            if(popupMenu != null){
                popupMenu.removeAll();
            }
        }
    
        @Override
        public int getMenuComponentCount() {
            return (popupMenu == null) ? 0 : popupMenu.getComponentCount();
        }
    
        @Override
        public Component getMenuComponent(int n) {
            return (popupMenu == null) ? null : popupMenu.getComponent(n);
        }
    
        @Override
        public Component[] getMenuComponents() {
            return (popupMenu == null) ? new Component[0] : popupMenu.getComponents();
        }
    
        @Override
        public JPopupMenu getPopupMenu() {
            ensurePopupMenuCreated();
            return popupMenu;
        }
    
        @Override
        public MenuElement[] getSubElements() {
            return popupMenu == null ? new MenuElement[0] : new MenuElement[]{popupMenu};
        }
    
    
        @Override
        public void applyComponentOrientation(ComponentOrientation o) {
            super.applyComponentOrientation(o);
    
            if(popupMenu != null) {
                int ncomponents = getMenuComponentCount();
                for(int i = 0; i < ncomponents; ++i) {
                    getMenuComponent(i).applyComponentOrientation(o);
                }
                popupMenu.setComponentOrientation(o);
            }
        }
    
        @Override
        public void setComponentOrientation(ComponentOrientation o) {
            super.setComponentOrientation(o);
            if(popupMenu != null) {
                popupMenu.setComponentOrientation(o);
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-30 05:52

    Basically you can add any JComponents to the JPopupMenu, you can add JScrollpane to the JPopup by nesting JPanel / JList with another JComponents,

    Notice but there is rule that swing GUI doesn't allowing two lightweight popup window in same time, best example is common Bug in Swing about JComboBox in the JPopup

    you have look at JWindow, create once time and re_use that for another Action, nothing best around as to check how popup JWindow really works for JCalendar by Kai Toedter

    0 讨论(0)
  • 2020-12-30 06:02

    Alternately you may want to consider JidePopupMenu: Scrollable JPopupMenu

    0 讨论(0)
  • 2020-12-30 06:09

    May be this http://www.javabeginner.com/java-swing/java-scrollable-popup-menu

    0 讨论(0)
提交回复
热议问题