Google Tag Manager

2021/11/30

Add a vertical JSlider in the JPopupMenu and display it at the top of the JToggleButton

Code

JPopupMenu popup = new JPopupMenu();
popup.setLayout(new BorderLayout());
popup.addMouseWheelListener(InputEvent::consume);

UIManager.put("Slider.paintValue", Boolean.TRUE);
UIManager.put("Slider.focus", UIManager.get("Slider.background"));
JSlider slider = new JSlider(SwingConstants.VERTICAL, 0, 100, 80);
slider.addMouseWheelListener(e -> {
  JSlider s = (JSlider) e.getComponent();
  if (s.isEnabled()) {
    BoundedRangeModel m = s.getModel();
    m.setValue(m.getValue() - e.getWheelRotation() * 2);
  }
  e.consume();
});
popup.add(slider);

JToggleButton button = new JToggleButton("🔊") {
  @Override public JToolTip createToolTip() {
    JToolTip tip = super.createToolTip();
    tip.addHierarchyListener(e -> {
      long flg = e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED;
      if (flg != 0 && e.getComponent().isShowing()) {
        Dimension d = popup.getPreferredSize();
        popup.show(this, (getWidth() - d.width) / 2, -d.height);
      }
    });
    return tip;
  }

  @Override public Point getToolTipLocation(MouseEvent e) {
    return new Point(getWidth() / 2, -getHeight());
  }

  @Override public void setEnabled(boolean b) {
    super.setEnabled(b);
    setText(b ? "🔊" : "🔇");
  }
};
button.setToolTipText("");
button.addMouseListener(new MouseAdapter() {
  @Override public void mousePressed(MouseEvent e) {
    if (!button.isEnabled()) {
      slider.setValue(80);
      button.setEnabled(true);
    }
    Component b = (Component) e.getSource();
    Dimension d = popup.getPreferredSize();
    popup.show(b, (b.getWidth() - d.width) / 2, -d.height);
  }

  @Override public void mouseEntered(MouseEvent e) {
    if (!popup.isVisible()) {
      ToolTipManager.sharedInstance().setEnabled(true);
    }
  }

  @Override public void mouseExited(MouseEvent e) {
    if (!popup.isVisible()) {
      ToolTipManager.sharedInstance().setEnabled(true);
    }
  }
});
popup.addPopupMenuListener(new PopupMenuListener() {
  @Override public void popupMenuCanceled(PopupMenuEvent e) {
    /* not needed */
  }

  @Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
    EventQueue.invokeLater(() -> ToolTipManager.sharedInstance().setEnabled(false));
  }

  @Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
    button.setSelected(false);
  }
});

References