Смещение координат мыши на JPanel внутри JScrollPane
У меня есть JPanel внутри JScrollPane. У JPanel есть MouseListener, присоединенный, чтобы реагировать на события мыши. Когда я добавляю JPanel непосредственно в родительский JComponent (без промежуточной JScrollPane), все это работает правильно. Как только я добавляю JScrollPane к миксу, координаты мыши, отправленные в обработчики событий на JPanel, имеют положительное смещение вдоль осей x и y.
Пример (слушатель мыши на JPanel):
public void mousePressed(MouseEvent ev) {
System.out.println(ev.getPoint());
System.out.println(this.getMousePosition());
}
Когда я нажимаю на верхний левый угол JPanel вместо (0,0), я получаю что-то вроде (5,60) от обеих функций, в то время как нижний правый угол (для размера JPanel 600x400) возвращает (605,460). Есть идеи, откуда происходит это линейное смещение?
Изменить: Неважно, я сократил его до простого теста, и он работает, как ожидалось. Так что это должно быть что-то в моем окружающем коде, который вызывает такое поведение.
public class JScrollPaneTest {
public static void main(String[] args) {
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().setLayout(new BorderLayout());
MyPanel panel = new MyPanel();
window.getContentPane().add(new JScrollPane(panel), BorderLayout.CENTER);
window.setSize(new Dimension(600, 400));
window.setVisible(true);
}
}
public class MyPanel extends JPanel implements MouseListener, Scrollable {
public MyPanel() {
setLayout(null);
addMouseListener(this);
this.setAutoscrolls(true);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(2000, 2000);
}
@Override
public void mousePressed(MouseEvent ev) {
System.out.println("Event mouse position: " + ev.getPoint());
System.out.println("Panel mouse position: " + this.getMousePosition());
}
}
1 ответ
Пожалуйста, не могли бы вы воспроизвести вашу проблему на основе этого примера?
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
import javax.swing.border.LineBorder;
public class MainViewPort {
public static void main(String[] args) {
JPanel viewportPanelTop = new JPanel();
JPanel viewportPanelBottom = new JPanel();
JPanel viewportPanel = new JPanel();
viewportPanel.setBackground(Color.BLACK);
viewportPanel.setPreferredSize(new Dimension(1000, 1000));
JPanel viewportPanel1 = new JPanel();
viewportPanel1.setBackground(Color.red);
JPanel viewportPanel2 = new JPanel();
viewportPanel2.setBackground(Color.blue);
JPanel viewportPanel3 = new JPanel();
viewportPanel3.setBackground(Color.cyan);
JPanel viewportPanel4 = new JPanel();
viewportPanel4.setBackground(Color.yellow);
JPanel viewportPanel5 = new JPanel();
viewportPanel5.setBackground(Color.LIGHT_GRAY);
JPanel viewportPanel6 = new JPanel();
viewportPanel6.setBackground(Color.magenta);
viewportPanel.setLayout(new GridLayout(3, 2));
viewportPanel.add(viewportPanel1);
viewportPanel.add(viewportPanel2);
viewportPanel.add(viewportPanel3);
viewportPanel.add(viewportPanel4);
viewportPanel.add(viewportPanel5);
viewportPanel.add(viewportPanel6);
viewportPanel.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
System.out.println(e.getPoint());
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
});
JScrollPane scrollPane = new JScrollPane();
scrollPane.setPreferredSize(new Dimension(800, 600));
scrollPane.setBackground(Color.BLUE);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.getViewport().add(viewportPanel);
scrollPane.getViewport().setViewPosition(new Point(0, 0));
scrollPane.getViewport().setBackground(Color.red);
scrollPane.setBorder(new LineBorder(Color.black, 2));
JFrame frame = new JFrame();
frame.setTitle("Viewport JFrame");
frame.setLocation(150, 150);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(viewportPanelTop, BorderLayout.NORTH);
frame.add(scrollPane, BorderLayout.CENTER);
frame.add(viewportPanelBottom, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
private MainViewPort() {
}
}