Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #34083

Scrollable Popup Menu Keyboard Navigation

Newsgroups comp.lang.java.programmer
Date 2016-04-07 12:21 -0700
Message-ID <dfd94962-3cdc-4cf0-a142-2ccd54c2bb41@googlegroups.com> (permalink)
Subject Scrollable Popup Menu Keyboard Navigation
From Eric Douglas <e.d.programmer@gmail.com>

Show all headers | View raw


Below is some runnable code of my scrollable popup menu, I think about as simple as I can get it.  I did write a hack with the key map to make page-up and page-down work.  I'm just wondering if I'm missing something.  Am I supposed to have to manually tell it what to do when someone presses page-up, page-down, home, end?  Why does just the up and down arrow keys work by default?  This also allows the down arrow to select menu items you can't see, so I also wrote a hack to keep the current item visible.


public class TestClass1 {

     public static void main(final String[] args) {

          EventQueue.invokeLater(new Runnable() {

               @Override
               public void run() {
                    final int maximumVisibleRows = 5;
                    final JFrame win = new JFrame();
                    final JScrollBar myScroll = new JScrollBar();
                    final JPopupMenu myMenu = new JPopupMenu() {

                         {
                              setLayout(new ScrollPopupMenuLayout());
                              add(myScroll);
                         }

                         @Override
                         public void show(final Component invoker, final int x, final int y) {
                              if (invoker instanceof JTextComponent && !(invoker.isFocusOwner())) {
                                   invoker.requestFocusInWindow();

                              }
                              if (myScroll.isVisible()) {
                                   int extent = 0;
                                   int max = 0;
                                   int i = 0;
                                   int unit = -1;
                                   int width = 0;
                                   for (final Component comp : getComponents()) {
                                        if (!(comp instanceof JScrollBar)) {
                                             final Dimension preferredSize = comp.getPreferredSize();
                                             width = Math.max(width, preferredSize.width);
                                             if (unit < 0) {
                                                  unit = preferredSize.height;
                                             }
                                             if (i++ < maximumVisibleRows) {
                                                  extent += preferredSize.height;
                                             }
                                             max += preferredSize.height;
                                        }
                                   }

                                   final Insets insets = getInsets();
                                   final int widthMargin = insets.left + insets.right;
                                   final int heightMargin = insets.top + insets.bottom;
                                   myScroll.setUnitIncrement(unit);
                                   myScroll.setBlockIncrement(extent);
                                   myScroll.setValues(0, heightMargin + extent, 0, heightMargin + max);

                                   width += myScroll.getPreferredSize().width + widthMargin;
                                   final int height = heightMargin + extent;

                                   setPopupSize(new Dimension(width, height));
                              }

                              super.show(invoker, x, y);
                         }
                    };
                    myMenu.add(new JMenuItem("A"));
                    myMenu.add(new JMenuItem("B"));
                    myMenu.add(new JMenuItem("C"));
                    myMenu.add(new JMenuItem("D"));
                    myMenu.add(new JMenuItem("E"));
                    myMenu.add(new JMenuItem("F"));
                    myMenu.add(new JMenuItem("G"));
                    win.addMouseListener(new MouseAdapter() {

                         @Override
                         public void mousePressed(final MouseEvent e) {
                              checkPopup(e);
                         }

                         @Override
                         public void mouseClicked(final MouseEvent e) {
                              checkPopup(e);
                         }

                         @Override
                         public void mouseReleased(final MouseEvent e) {
                              checkPopup(e);
                         }

                         private void checkPopup(final MouseEvent e) {
                              if (e.isPopupTrigger()) {
                                   myMenu.show(win, e.getX(), e.getY());
                              }
                         }
                    });
                    win.setSize(200, 120);
                    win.setVisible(true);
               }

          });
     }

     protected static class ScrollPopupMenuLayout implements LayoutManager, Serializable {

          @Override
          public void addLayoutComponent(final String name, final Component comp) {
          }

          @Override
          public void removeLayoutComponent(final Component comp) {
          }

          @Override
          public Dimension preferredLayoutSize(final Container parent) {
               int visibleAmount = Integer.MAX_VALUE;
               final Dimension dim = new Dimension();
               for (final Component comp : parent.getComponents()) {
                    if (comp.isVisible()) {
                         if (comp instanceof JScrollBar) {
                              final JScrollBar scrollBar = (JScrollBar) comp;
                              visibleAmount = scrollBar.getVisibleAmount();
                         } else {
                              final Dimension pref = comp.getPreferredSize();
                              dim.width = Math.max(dim.width, pref.width);
                              dim.height += pref.height;
                         }
                    }
               }

               final Insets insets = parent.getInsets();
               dim.height = Math.min(dim.height + insets.top + insets.bottom, visibleAmount);

               return dim;
          }

          @Override
          public Dimension minimumLayoutSize(final Container parent) {
               int visibleAmount = Integer.MAX_VALUE;
               final Dimension dim = new Dimension();
               for (final Component comp : parent.getComponents()) {
                    if (comp.isVisible()) {
                         if (comp instanceof JScrollBar) {
                              final JScrollBar scrollBar = (JScrollBar) comp;
                              visibleAmount = scrollBar.getVisibleAmount();
                         } else {
                              final Dimension min = comp.getMinimumSize();
                              dim.width = Math.max(dim.width, min.width);
                              dim.height += min.height;
                         }
                    }
               }

               final Insets insets = parent.getInsets();
               dim.height = Math.min(dim.height + insets.top + insets.bottom, visibleAmount);

               return dim;
          }

          @Override
          public void layoutContainer(final Container parent) {
               final Insets insets = parent.getInsets();

               int width = parent.getWidth() - insets.left - insets.right;
               final int height = parent.getHeight() - insets.top - insets.bottom;

               final int x = insets.left;
               int y = insets.top;
               int position = 0;

               for (final Component comp : parent.getComponents()) {
                    if ((comp instanceof JScrollBar) && comp.isVisible()) {
                         final JScrollBar scrollBar = (JScrollBar) comp;
                         final Dimension dim = scrollBar.getPreferredSize();
                         scrollBar.setBounds(x + width - dim.width, y, dim.width, height);
                         width -= dim.width;
                         position = scrollBar.getValue();
                    }
               }

               y -= position;
               for (final Component comp : parent.getComponents()) {
                    if (!(comp instanceof JScrollBar) && comp.isVisible()) {
                         final Dimension pref = comp.getPreferredSize();
                         comp.setBounds(x, y, width, pref.height);
                         y += pref.height;
                    }
               }
          }
     }
}

Back to comp.lang.java.programmer | Previous | Next — Next in thread | Find similar | Unroll thread


Thread

Scrollable Popup Menu Keyboard Navigation Eric Douglas <e.d.programmer@gmail.com> - 2016-04-07 12:21 -0700
  Re: Scrollable Popup Menu Keyboard Navigation Jeff Higgins <jeff@invalid.invalid> - 2016-04-08 00:12 +0000
    Re: Scrollable Popup Menu Keyboard Navigation Eric Douglas <e.d.programmer@gmail.com> - 2016-04-08 04:29 -0700
      Re: Scrollable Popup Menu Keyboard Navigation Jeff Higgins <jeff@invalid.invalid> - 2016-04-08 15:27 +0000
        Re: Scrollable Popup Menu Keyboard Navigation Eric Douglas <e.d.programmer@gmail.com> - 2016-04-08 08:52 -0700
          Re: Scrollable Popup Menu Keyboard Navigation Jeff Higgins <jeff@invalid.invalid> - 2016-04-08 16:31 +0000
            Re: Scrollable Popup Menu Keyboard Navigation Eric Douglas <e.d.programmer@gmail.com> - 2016-04-08 11:07 -0700
              Re: Scrollable Popup Menu Keyboard Navigation Jeff Higgins <jeff@invalid.invalid> - 2016-04-08 20:39 +0000
                Re: Scrollable Popup Menu Keyboard Navigation Eric Douglas <e.d.programmer@gmail.com> - 2016-04-08 14:00 -0700
                Re: Scrollable Popup Menu Keyboard Navigation Jeff Higgins <jeff@invalid.invalid> - 2016-04-08 21:43 +0000
                Re: Scrollable Popup Menu Keyboard Navigation Jeff Higgins <jeff@invalid.invalid> - 2016-04-09 11:46 +0000
                Re: Scrollable Popup Menu Keyboard Navigation Jeff Higgins <jeff@invalid.invalid> - 2016-04-08 22:33 +0000
                Re: Scrollable Popup Menu Keyboard Navigation Robert Klemme <shortcutter@googlemail.com> - 2016-04-10 11:20 +0200
          Re: Scrollable Popup Menu Keyboard Navigation Robert Klemme <shortcutter@googlemail.com> - 2016-04-10 11:20 +0200
            Re: Scrollable Popup Menu Keyboard Navigation Eric Douglas <e.d.programmer@gmail.com> - 2016-04-11 05:00 -0700
  Re: Scrollable Popup Menu Keyboard Navigation Jeff Higgins <jeff@invalid.invalid> - 2016-04-08 23:09 +0000
    Re: Scrollable Popup Menu Keyboard Navigation Eric Douglas <e.d.programmer@gmail.com> - 2016-04-11 05:13 -0700
    Re: Scrollable Popup Menu Keyboard Navigation Fredrik Jonson <fredrik@jonson.org> - 2016-04-18 08:50 +0000
      Re: Scrollable Popup Menu Keyboard Navigation Eric Douglas <e.d.programmer@gmail.com> - 2016-04-18 05:00 -0700
  Re: Scrollable Popup Menu Keyboard Navigation Martin Gregorie <martin@address-in-sig.invalid> - 2016-06-07 16:58 +0000

csiph-web