2011-07-05 45 views
0

我在JScrollPane中有一個JPanel。 JPanel有一個MouseListener,用於響應鼠標事件。當我將JPanel直接添加到父JComponent(其間沒有JScrollPane)時,它都可以正常工作。一旦將JScrollPane添加到混合中,發送到JPanel上的事件處理程序的鼠標座標都沿着x軸和y軸具有正偏移量。JScrollPane中的JPanel上的鼠標座標偏移量

例(在JPanel的鼠標監聽):

public void mousePressed(MouseEvent ev) { 
    System.out.println(ev.getPoint()); 
    System.out.println(this.getMousePosition()); 
} 

當我點擊JPanel的,而不是左上角(0,0)我得到,而這兩個功能類似(5,60)右下角(對於尺寸爲600x400的JPanel)返回(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()); 
} 
} 
+0

*「JPanel有一個MouseListener附加..」*我最好的選擇是'MouseListener'附加到別的東西上。發佈一個[SSCCE](http://pscode.org/sscce.html),如** mMorbel **所發佈的那樣,以證明不然。 –

+0

是的,如果沒有擴展的代碼示例(包括如何創建JPanel/JScrollPane) - 理想地發佈兩個描述這兩種情況的示例,很難/不可能診斷此問題。 –

+0

'JPanel'的默認佈局是'FlowLayout';查看對@ mKorbel的答案的評論。 – trashgod

回答

3

請你能重現你的問題基於這個例子嗎?

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() { 
    } 
} 
+0

+1好[sscce](http://sscce.org/)。你明確的佈局是關鍵; FlowLayout是OP的原因。 'MouseAdapter'會是apropos嗎? – trashgod

+0

@trashgod goooood :-)是的我原本想放在那裏MouseMotionListener,但我無盡的懶惰:-)和OP很大程度上消散,所以我們的任何反思是... – mKorbel