Swing wird nicht ausgelöst, mouseEntered/mouseExited richtig nach Maus-Rad-events?
Ich habe ein Problem, wo Swing (Java 1.6, Windows) scheint nicht auslösen, mouseEntered und mouseExited-events, wie ich es möchte zu. Ich habe eine Anwendung wo ich will haben eine Anzahl von JPanels vertikal gestapelt in eine JScrollPane, und Sie sollten sein markiert mit einer anderen Farbe, wenn die Maus über Sie. Einfach genug problem, aber immer wenn ich scrollen mit dem Mausrad, es nicht ganz zu Verhalten.
Habe ich eine Beispiel-Anwendung zu veranschaulichen mein problem (code unten). Die Bilder unten sind aus, dass man nicht die "echte" Anwendung.
Wenn ich halten Sie den Mauszeiger über den Rand eines panel, es ist korrekt hervorgehoben. Nun, wenn ich mit dem Mausrad nach unten scrollen, ich erwarte, dass der cursor über das Feld B, und die richtige mouseEntered/mouseExited-events werden ausgelöst, so dass Eine wird weiß und B wird rot.
(Quelle: perp.se)
(Quelle: perp.se)
Aber das scheint nicht zu passieren.
Nun, B wird markiert, wenn ich die Auslöser-mouse-Veranstaltung, es werden "move" 1 pixel", "klicken Sie auf eine Schaltfläche" oder "scroll ein weiterer Schritt". Dies zu wissen, könnte ich vielleicht lösen Sie es in ein hackish Weg, aber ich möchte lieber nicht, wenn es eine richtige Lösung.
Also im Grunde das, was ich Fragen ist, ob Sie das als einen bug in Swing, oder bin ich einfach nur etwas falsch?
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
public class ScrollTest extends JFrame {
public static class LetterPanel extends JPanel {
private static final Font BIG_FONT = new Font(Font.MONOSPACED, Font.BOLD, 24);
public LetterPanel(String text) {
setBackground(Color.WHITE);
setBorder(BorderFactory.createLineBorder(Color.BLACK));
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
setBackground(Color.RED);
}
@Override
public void mouseExited(MouseEvent e) {
setBackground(Color.WHITE);
}
});
setLayout(new GridLayout(1, 1));
setPreferredSize(new Dimension(-1, 50));
JLabel label = new JLabel(text, SwingConstants.CENTER);
label.setFont(BIG_FONT);
add(label);
}
}
public ScrollTest() {
setLayout(new GridLayout(1, 1));
setSize(400, 400);
JPanel base = new JPanel();
JScrollPane jsp = new JScrollPane(base);
jsp.getVerticalScrollBar().setUnitIncrement(16);
add(jsp);
base.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridheight = 1;
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(0, 0, 10, 0);
gbc.weightx = 1.0;
for (char c = 'A'; c <= 'Z'; c++) {
base.add(new LetterPanel(String.valueOf(c)), gbc);
gbc.gridy++;
}
}
public static void main(String[] args) {
final JFrame f = new ScrollTest();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
f.setVisible(true);
}
});
}
}
- Die Einschränkungen gibt es für einen Grund. Ohne Sie, SO hätte ziemlich viel SPAM-posts. Ich fügte die Bilder und entfernt Ihre Bemerkungen darüber, wie "spät" die Regeln hier sind.
- Neben diesen Bemerkungen, die du gefragt hast eine ausgezeichnete Frage: klare Bilder, eine gute code-snippet: gut gemacht. Ich bin kein Swing-guru, aber ich werde haben Sie einen Blick auf es später (wenn es nicht bereits beantwortet von damals). +1
- Vielen Dank für den edit. Es war ein wenig frustrierend, zu ersten kämpfen mit dem problem, schreiben Sie die Frage, schreiben Sie die snippet, gute screenshots, laden Sie Sie auf einen server und haben dann SO barf in meinem post, nur weil ich bin ein neuer Benutzer. Ich fühle mich jetzt besser. 🙂
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie es scheint, ein ähnliches problem beschrieben, in Tooltips und Scrollpanes. Das heißt, keine Maus-events werden erzeugt, weil die Maus sich nicht bewegt, der viewport verschiebt. Ich bin mir nicht sicher, ob das genau die Lösung, die andere mit der AdjustmentListener verfolgen Sie die Komponente an der Mausposition. Zu jeder Zeit ändern können Sie das Feuer ein mouseExited-event auf dem vorherigen panel und ein mouseEntered-event auf der neuen Platte.
Kann ich Holen Sie sich Ihren code zu reproduzieren zuverlässig, aber nur wenn ich nicht ganz beenden Sie den Bildlauf. Auf meiner Maus gibt es zumindest eine Art "fangen", wenn Sie die Maus Rad scrollen fertig. Wenn ich scrollen sehr langsam ich kann es bewegen aber es ändert sich nicht das highlight, bis das Mausrad erreicht hat, die "fangen".
Wenn ich tun, dass die Maus geben Sie die Nachricht empfangen wird, auf dem vorherigen panel (dasselbe Verhalten, das Sie sehen).
Ich schaute scrollen Sie mit der Maus und ist es nicht tatsächlich erhalten die verlassen/erfasste Ereignisse, es sei denn, ich gehe genug, um die Maus-Rad "fangen". Es ist möglich, dass Windows nicht senden Sie die Nachricht an Java, bis das "fangen" passiert... von meinen Tests, das ist, wie es aussieht.
Vielleicht möchten Sie sich in die MouseWheelListener interface und die Klasse MouseInfo. Ich denke, Sie könnten in der Lage sein zu erkennen, das Rad Bewegung und dann herauszufinden, wo Sie sind mit MouseInfo.getPointerInfo().getLocation() und dann herausfinden, welche Komponente Sie sind über und ändern Sie die Hervorhebung.