Swing (Java 1.6, Windows)이 mouseEntered 및 mouseExited 이벤트를 원하는 방식으로 트리거하지 않는 것 같습니다. JScrollPane에 세로로 쌓아 놓은 JPanel을 여러 개 갖고 자하는 응용 프로그램이 있으며 마우스가 위에있을 때 다른 색상으로 강조 표시해야합니다. 문제는 간단하지만 마우스 휠을 사용하여 스크롤 할 때마다 동작하지 않습니다.마우스 휠 이벤트 이후에 Swing이 mouseEntered/mouseExited를 제대로 트리거하지 않습니까?
문제점 (코드는 아래 참조)을 설명하기 위해 샘플 애플리케이션을 만들었습니다. 아래의 이미지는 "진짜"어플리케이션이 아니라 그 이미지입니다.
패널의 가장자리 위로 마우스 커서를 올리면 올바르게 강조 표시됩니다. 이제 마우스 휠을 사용하여 아래로 스크롤하면 커서가 상자 B 위에 있고 마우스 오른쪽 단추가 흰색으로 표시되고 B가 빨간색이되도록 적절한 mouseEntered/mouseExited 이벤트가 트리거 될 것으로 예상됩니다. 일하지 않는 것 같습니다 그러나
alt text http://perp.se/so/2.png
alt text http://perp.se/so/1.png
.다른 마우스 이벤트를 "1 픽셀 이동", "버튼 클릭"또는 "다른 단계 스크롤"으로하면 B가 강조 표시됩니다. 이것을 알면 아마 해킹 된 방식으로 해결할 수 있지만, 적절한 해결책이 있다면 오히려하지 않을 것입니다.
기본적으로 내가 궁금해하는 점은 이것이 Swing에서 버그로 간주되는지 아니면 그냥 잘못하고있는 것인가?
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);
}
});
}
}
이유가 있습니다. 그것 없이는 SO가 스팸 게시물을 꽤 많이 가지고 있었을 것입니다. 이미지를 추가하고 규칙이 "지연됨"에 대한 의견을 삭제했습니다. –
이러한 말 외에, 당신은 훌륭한 질문을 해왔다 : 선명한 이미지, 코드 스 니펫. 나는 스윙 전문가는 아니지만 나중에 (이미 답변하지 않은 경우) 나중에 살펴볼 것입니다. +1 –
편집 해 주셔서 감사합니다.그것은 처음으로 문제와 싸우고, 질문을 쓰고, 스 니펫을 작성하고, 좋은 스크린 샷을 찍고, 서버에 업로드 한 다음, 내가 새로운 사용자이기 때문에 내 게시물에 SO barf를 갖는 것에 조금 실망했습니다. 기분이 나아 졌어. :-) – perp