我正在编写一个简单的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。
是否还有一种方法可以控制箭头按钮的工具提示位置?
最佳答案
尝试添加将鼠标事件转移到父MouseMotionListener
和JComboBox
的ArrowButton
:
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);
// }
}