• category: swing folder: PressAndHoldButton title: JPopupMenuをボタンの長押しで表示 tags: [JToolBar, JButton, JPopupMenu, MouseListener, GridLayout, Timer] author: aterai pubdate: 2009-01-26T13:29:29+09:00 description: JToolBarに、長押しでJPopupMenu、クリックで選択されたメニューを表示するボタンを追加します。 image: https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTRIzHMLNI/AAAAAAAAAgs/0_PwsyZOl-I/s800/PressAndHoldButton.png hreflang:
       href: http://java-swing-tips.blogspot.com/2014/03/long-pressing-jbutton-to-get-jpopupmenu.html
       href: https://java-swing-tips.blogspot.com/2014/03/long-pressing-jbutton-to-get-jpopupmenu.html
       lang: en

概要

JToolBarに、長押しでJPopupMenu、クリックで選択されたメニューを表示するボタンを追加します。

サンプルコード

class PressAndHoldHandler extends AbstractAction implements MouseListener {
  public final JPopupMenu pop = new JPopupMenu();
  public final ButtonGroup bg = new ButtonGroup();
  private AbstractButton arrowButton;
  private final Timer holdTimer = new Timer(1000, new ActionListener() {
    @Override public void actionPerformed(ActionEvent e) {
      System.out.println("InitialDelay(1000)");
      if (arrowButton != null && arrowButton.getModel().isPressed()
          && holdTimer.isRunning()) {
        holdTimer.stop();
        pop.show(arrowButton, 0, arrowButton.getHeight());
        pop.requestFocusInWindow();
      }
    }
  });
#spanadd

#spanend
  public PressAndHoldHandler() {
    super();
    holdTimer.setInitialDelay(1000);
    pop.setLayout(new GridLayout(0, 3, 5, 5));
    for (MenuContext m: makeMenuList()) {
      AbstractButton b = new JRadioButton(m.command);
      b.setActionCommand(m.command);
      b.setForeground(m.color);
      b.setBorder(BorderFactory.createEmptyBorder());
      b.addActionListener(new ActionListener() {
        @Override public void actionPerformed(ActionEvent e) {
          System.out.println(bg.getSelection().getActionCommand());
          pop.setVisible(false);
        }
      });
      pop.add(b);
      bg.add(b);
    }
  }
#spanadd

#spanend
  private List<MenuContext> makeMenuList() {
    return Arrays.asList(
      new MenuContext("BLACK",   Color.BLACK),
      new MenuContext("BLUE",   Color.BLUE),
      new MenuContext("CYAN",   Color.CYAN),
      new MenuContext("GREEN",   Color.GREEN),
      new MenuContext("BLACK", Color.BLACK),
      new MenuContext("BLUE", Color.BLUE),
      new MenuContext("CYAN", Color.CYAN),
      new MenuContext("GREEN", Color.GREEN),
      new MenuContext("MAGENTA", Color.MAGENTA),
      new MenuContext("ORANGE",  Color.ORANGE),
      new MenuContext("PINK",   Color.PINK),
      new MenuContext("RED",    Color.RED),
      new MenuContext("YELLOW",  Color.YELLOW));
      new MenuContext("ORANGE", Color.ORANGE),
      new MenuContext("PINK", Color.PINK),
      new MenuContext("RED", Color.RED),
      new MenuContext("YELLOW", Color.YELLOW));
  }
#spanadd

#spanend
  @Override public void actionPerformed(ActionEvent e) {
    System.out.println("actionPerformed");
    if (holdTimer.isRunning()) {
      ButtonModel model = bg.getSelection();
      if (model != null) {
        System.out.println(model.getActionCommand());
      }
      holdTimer.stop();
    }
  }
#spanadd

#spanend
  @Override public void mousePressed(MouseEvent e) {
    System.out.println("mousePressed");
    Component c = e.getComponent();
    if (SwingUtilities.isLeftMouseButton(e) && c.isEnabled()) {
      arrowButton = (AbstractButton) c;
      holdTimer.start();
    }
  }
#spanadd

#spanend
  @Override public void mouseReleased(MouseEvent e) {
    holdTimer.stop();
  }
#spanadd

#spanend
  @Override public void mouseExited(MouseEvent e) {
    if (holdTimer.isRunning()) {
      holdTimer.stop();
    }
  }
  @Override public void mouseEntered(MouseEvent e) { /* not needed */ }
  @Override public void mouseClicked(MouseEvent e) { /* not needed */ }
#spanadd

#spanend
  @Override public void mouseEntered(MouseEvent e) {
    /* not needed */
  }
#spanadd

#spanend
  @Override public void mouseClicked(MouseEvent e) {
    /* not needed */
  }
}
View in GitHub: Java, Kotlin

解説

  • 長押し
    • ボタンクリックが1000ミリ秒以上継続されると、JRadioButtonを配置したJPopupMenuを表示
      • JPopupMenuのレイアウトをpop.setLayout(new GridLayout(0, 3))で変更し、JRadioButton3列並べて表示
    • ボタンクリックが1000ミリ秒以上継続するとJRadioButtonを配置したJPopupMenuを表示
      • JPopupMenuのレイアウトをpop.setLayout(new GridLayout(0, 3))で変更しJRadioButton3列並べて表示
  • シングルクリック
    • 現在選択されているJRadioButtonの色をコンソールに出力

参考リンク

コメント