Hallo allerseits,
ich habe ein kleines Beispielprogramm geschrieben, das eine JComboBox mit einem MouseListener versieht, der anspringt, wenn man mit dem Mauszeiger den Arrow-Button verlässt. Der Arrow-Button ist der, der den Popup aufklappt bzw. unter Mac OS X die gesamte ComboBox überdeckt. Ziel ist es herauszubekommen, ob man den Arrow-Button nach links, rechts, oben oder unten verlassen hat.
Dazu mache ich ein wenig Rechnerei mit Koordinaten und gebe dann aus "Exit: left", "Exit: right", "Exit: top" oder "Exit: bottom" - eben jenachdem in welcher Richtung der Mauszeiger den Button verlassen hat.
Wenn man das Beispielprogramm laufen lässt, dann funktioniert das zunächst auch recht gut, aber sobald man den Button anklickt und damit das PopupMenu aufklappt, entsteht ein Problem: das Verlassen des Arrow-Buttons nach unten wird plötzlich angezeigt als "Exit: top", was daran liegt, dass das MouseEvent hier auf einmal eine negative Y-Koordinate hat. Ich hätte erwartet, dass das nur der Fall ist, wenn man den Button nach oben verlässt, da der ja auf der relativen Position Y = 0 beginnt. Ein negativer Y-Wert müsste also darüber liegen.
Hat hier jemand eine Idee? Getestet habe ich das KSKB auf dem Mac, aber es sollte auch unter Windows oder Linux dasselbe Phänomen zeigen, wenn auch dort der Arrow-Button kleiner ist.
Ulrich
ich habe ein kleines Beispielprogramm geschrieben, das eine JComboBox mit einem MouseListener versieht, der anspringt, wenn man mit dem Mauszeiger den Arrow-Button verlässt. Der Arrow-Button ist der, der den Popup aufklappt bzw. unter Mac OS X die gesamte ComboBox überdeckt. Ziel ist es herauszubekommen, ob man den Arrow-Button nach links, rechts, oben oder unten verlassen hat.
Dazu mache ich ein wenig Rechnerei mit Koordinaten und gebe dann aus "Exit: left", "Exit: right", "Exit: top" oder "Exit: bottom" - eben jenachdem in welcher Richtung der Mauszeiger den Button verlassen hat.
Wenn man das Beispielprogramm laufen lässt, dann funktioniert das zunächst auch recht gut, aber sobald man den Button anklickt und damit das PopupMenu aufklappt, entsteht ein Problem: das Verlassen des Arrow-Buttons nach unten wird plötzlich angezeigt als "Exit: top", was daran liegt, dass das MouseEvent hier auf einmal eine negative Y-Koordinate hat. Ich hätte erwartet, dass das nur der Fall ist, wenn man den Button nach oben verlässt, da der ja auf der relativen Position Y = 0 beginnt. Ein negativer Y-Wert müsste also darüber liegen.
Hat hier jemand eine Idee? Getestet habe ich das KSKB auf dem Mac, aber es sollte auch unter Windows oder Linux dasselbe Phänomen zeigen, wenn auch dort der Arrow-Button kleiner ist.
Ulrich
Java:
import java.awt.Component;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class ComboBoxCoordTest {
public static void main(String[] args) {
ComboBoxCoordTest test = new ComboBoxCoordTest();
}
public ComboBoxCoordTest() {
JFrame frame = new JFrame("Test Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComboBox comboBox = new MyComboBox();
String[] items = new String[] { "One", "Two", "Three", "Four", "Five" };
comboBox.setModel(new DefaultComboBoxModel(items));
comboBox.setMaximumRowCount(3);
comboBox.setOpaque(true);
frame.getContentPane().add(comboBox);
// Display the window.
frame.pack();
frame.setVisible(true);
}
private class MyComboBox extends JComboBox {
public MyComboBox() {
Component[] c = getComponents();
for (int j = 0; j < c.length; j++) {
// add event listeners to the ComboBox's Button
if (c[j] instanceof JButton) {
final Component comp = c[j];
c[j].addMouseListener(new MouseAdapter() {
@Override
public void mouseExited(MouseEvent e) {
Point p = e.getLocationOnScreen();
Point topLeft = new Point(comp.getLocationOnScreen());
int width = SwingUtilities.getLocalBounds(comp).width;
int height = SwingUtilities.getLocalBounds(comp).height;
Point bottomRight = new Point(topLeft.x + width, topLeft.y + height);
if (p.y <= topLeft.y) System.out.println("Exit: top");
else if (p.x <= topLeft.x) System.out.println("Exit: left");
else if (p.x >= bottomRight.x) System.out.println("Exit: right");
else if (p.y >= bottomRight.y) System.out.println("Exit: bottom");
System.out.println("Bounds: " + topLeft.toString() + " - " + bottomRight.toString());
System.out.println("Point: " + p.toString() + "\n");
}
});
}
}
}
}
}