我正在编写一个简单的swing程序,在其中创建JFrame并向其中添加我的自定义JComboBox。

public class CustomJComboBox<T> extends JComboBox<T> {

public static void main(String[] args) {
    new CustomJComboBox<>().initUI();
}

/**
 *
 */
private static final long serialVersionUID = 1L;

@Override
public Point getToolTipLocation(MouseEvent event) {
    System.out.println("getToolTipLocation called");
    return super.getToolTipLocation(event);
}

private void initUI() {

    JComboBox<String> box = new CustomJComboBox<>();

    box.addItem("Item 1");
    box.addItem("Item 2");

    box.setToolTipText("TooTip");

    JFrame frame = new JFrame();

    frame.setBounds(0, 0, 300, 300);

    frame.add(box);

    frame.setVisible(true);

}

}


当我将鼠标悬停在组合框上时,将调用覆盖的getToolTipLocation()方法,但是当我将鼠标悬停在下拉箭头按钮上时,不会将此方法称为其单独的JButton。

是否还有一种方法可以控制箭头按钮的工具提示位置?

最佳答案

尝试添加将鼠标事件转移到父MouseMotionListenerJComboBoxArrowButton

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
//import javax.swing.plaf.metal.*;

public class CustomJComboBoxTest {
  public JComponent makeUI() {
    JComboBox<String> box = new JComboBox<String>() {
      private transient MouseAdapter handler;
      @Override public Point getToolTipLocation(MouseEvent e) {
        System.out.println("getToolTipLocation called");
        return super.getToolTipLocation(e);
      }
      @Override public void updateUI() {
        for (Component c : getComponents()) {
          if (c instanceof JButton) {
            ((JButton) c).removeMouseListener(handler);
            ((JButton) c).removeMouseMotionListener(handler);
          }
        }
        super.updateUI();
        handler = new ComboBoxMouseEventHelper();
        for (Component c : getComponents()) {
          if (c instanceof JButton) {
            ((JButton) c).addMouseListener(handler);
            ((JButton) c).addMouseMotionListener(handler);
          }
        }
//         //TEST:
//         setUI(new BasicComboBoxUI() {
//           @Override protected JButton createArrowButton() {
//             //JButton button = super.createArrowButton();
//             boolean iconOnly = true;
//             JButton button = new MetalComboBoxButton(comboBox, new MetalComboBoxIcon(),
//             iconOnly, currentValuePane, listBox) {
//               @Override public Point getToolTipLocation(MouseEvent e) {
//                 System.out.println("ArrowButton: getToolTipLocation called");
//                 return super.getToolTipLocation(e);
//               }
//             };
//             button.setMargin(new Insets(0, 1, 1, 3));
//             button.setName("ComboBox.arrowButton");
//             return button;
//           }
//         });
      }
    };
    box.addItem("Item 1");
    box.addItem("Item 2");
    box.setToolTipText("TooTip");

    JPanel p = new JPanel(new BorderLayout());
    p.setBorder(BorderFactory.createEmptyBorder(60, 20, 60, 20));
    p.add(box);
    return p;
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(() -> {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new CustomJComboBoxTest().makeUI());
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

class ComboBoxMouseEventHelper extends MouseAdapter {
  private void dispatchEvent(MouseEvent e) {
    Component s = e.getComponent();
    Container c = SwingUtilities.getAncestorOfClass(JComboBox.class, s);
    if (c instanceof JComboBox) {
      ((JComboBox) c).dispatchEvent(SwingUtilities.convertMouseEvent(s, e, c));
    }
  }
// @Override public void mouseClicked(MouseEvent e) {
//   dispatchEvent(e);
// }
  @Override public void mouseEntered(MouseEvent e) {
    dispatchEvent(e);
  }
  @Override public void mouseExited(MouseEvent e) {
    dispatchEvent(e);
  }
// @Override public void mousePressed(MouseEvent e) {
//   dispatchEvent(e);
// }
// @Override public void mouseReleased(MouseEvent e) {
//   dispatchEvent(e);
// }
  @Override public void mouseMoved(MouseEvent e) {
    dispatchEvent(e);
  }
// @Override public void mouseDragged(MouseEvent e) {
//   dispatchEvent(e);
// }
}

10-07 12:59