Swing/PressAndHoldButton のバックアップ(No.18)
- バックアップ一覧
 - 差分 を表示
 - 現在との差分 を表示
 - 現在との差分 - Visual を表示
 - ソース を表示
 - Swing/PressAndHoldButton へ行く。
  
- 1 (2011-04-27 (水) 19:19:08)
 - 2 (2013-01-12 (土) 21:44:48)
 - 3 (2014-03-27 (木) 17:57:20)
 - 4 (2014-11-19 (水) 20:16:50)
 - 5 (2014-11-21 (金) 18:11:05)
 - 6 (2015-12-18 (金) 16:30:28)
 - 7 (2017-06-13 (火) 15:43:22)
 - 8 (2017-11-07 (火) 13:02:39)
 - 9 (2018-02-24 (土) 19:51:30)
 - 10 (2019-06-14 (金) 20:37:19)
 - 11 (2021-02-25 (木) 10:47:26)
 - 12 (2024-08-31 (土) 17:36:42)
 - 13 (2025-01-03 (金) 08:57:02)
 - 14 (2025-01-03 (金) 09:01:23)
 - 15 (2025-01-03 (金) 09:02:38)
 - 16 (2025-01-03 (金) 09:03:21)
 - 17 (2025-01-03 (金) 09:04:02)
 - 18 (2025-06-19 (木) 12:41:37)
 - 19 (2025-06-19 (木) 12:43:47)
 
 
- 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: 
hreflang:
href: https://java-swing-tips.blogspot.com/2014/03/long-pressing-jbutton-to-get-jpopupmenu.html lang: en
 
Summary
JToolBarに、長押しでJPopupMenu、クリックで選択されたメニューを表示するボタンを追加します。
Screenshot

Advertisement
Source Code Examples
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, e -> {
    if (arrowButton != null && arrowButton.getModel().isPressed()
        && holdTimer.isRunning()) {
      holdTimer.stop();
      pop.show(arrowButton, 0, arrowButton.getHeight());
      pop.requestFocusInWindow();
    }
  });
  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(e -> {
        System.out.println(e.getActionCommand());
        pop.setVisible(false);
      });
      pop.add(b);
      bg.add(b);
    }
  }
  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("MAGENTA", Color.MAGENTA),
      new MenuContext("ORANGE", Color.ORANGE),
      new MenuContext("PINK", Color.PINK),
      new MenuContext("RED", Color.RED),
      new MenuContext("YELLOW", Color.YELLOW));
  }
  @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();
    }
  }
  @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();
    }
  }
  @Override public void mouseReleased(MouseEvent e) {
    holdTimer.stop();
  }
  @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 */
  }
}
View in GitHub: Java, KotlinExplanation
- 長押し
- ボタンクリックが
1000ミリ秒以上継続するとJRadioButtonを配置したJPopupMenuを表示JPopupMenuのレイアウトをpop.setLayout(new GridLayout(0, 3))で変更しJRadioButtonを3列並べて表示
 
 - ボタンクリックが
 - シングルクリック
- 現在選択されている
JRadioButtonの色をコンソールに出力 
 - 現在選択されている