2011-08-26 46 views
2

我正在使用Swing中的Touch用戶界面。雖然我知道這不是最佳的,但我只是在一個很短的截止日期,沒有時間觸摸特定的GUI軟件包(如果有的話)。Java Swing中的MouseMotionListener,使用它與組件內部的組件等

我希望我的用戶能夠在屏幕上「滑動」他們的手指,並且我製作的特殊JScrollPane的視圖也隨之移動。 的代碼非常簡單 -

public class PanScrollPane extends JScrollPane implements MouseMotionListener{ 
public PanScrollPane() { 
    super();   
    this.addMouseMotionListener(this);  
} 
@Override 
public void mouseDragged(MouseEvent arg0) { 
    System.out.println("Mouse Dragged!");  
} 
@Override 
public void mouseMoved(MouseEvent arg0) { 
    System.out.println("Mouse Moved!");  
} 

我遇到的問題是,JScrollPane的是各種JComponents的容器。當我第一次開始研究這個時,我認爲MouseMovedEvent和MouseDraggedEvent會向上傳播'GUI樹',直到他們遇到一個具有特定於該事件的偵聽器的Component。現在看來,我添加到panScrollPane的任何組件都會阻止任何這些MouseMotion事件,使我無法平移。

panScrollPane.add(new JButton("This thing blocks any mouse motion events")); 

我想通手傳播的MouseEvent(添加聽衆每一個部件,然後讓他們的事件發送到他們的父母)會工作。但是,這是一項非常耗時的工作,因爲我寧願花時間處理其他事情,所以我想知道您是否有任何人知道解決此問題的方法。

感謝您的閱讀,並希望謝謝您的回答! :)

編輯:使我的意圖更清晰。我只希望mousemotion事件被panPanel捕獲,任何其他事件(如MouseClick,MouseRelease)都應該正常處理

回答

2

如何使用GlassPane?我認爲它意在處理這些類型的情況。

+0

看起來很有希望,但玻璃窗會「捕捉」我感興趣的「捕捉」事件(MouseMotion的事件)還是每一個可能的事件? –

+0

對,教程代碼展示瞭如何讓它傳播任何剩餘的事件,我會用這個玻璃窗格來測試:)謝謝! –

+0

@Erwin您可以將MouseInputAdapter作爲mouseListner添加到父級以偵聽拖動事件。其他事件,我認爲只會通過它發送給子組件。 –

2

獲取組件及其所有子組件的mouseEvent是很棘手的。你可能會考慮依賴於穩定(和廣泛測試:-)的代碼。這樣做的jdk7方式是使用JLayer(內部註冊AWTEventListener,因爲它具有所有權限)。對於早期版本,您可以使用其前身JXLayer

+0

或只是爲了確定鼠標按鍵是否仍然按下+1 – mKorbel

7

特設方法利用了通常在key bindings使用現有JScrollPane行動。您必須調整N才能執行Scrollable

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.Action; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JViewport; 
import javax.swing.Timer; 

/** @see http://stackoverflow.com/questions/7201509 */ 
public class ScrollAction extends JPanel { 

    private static final int TILE = 64; 
    private static final int DELTA = 16; 

    public ScrollAction() { 
     this.setOpaque(false); 
     this.setFocusable(true); 
     this.setPreferredSize(new Dimension(50 * TILE, 50 * TILE)); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.setColor(Color.lightGray); 
     int w = this.getWidth()/TILE + 1; 
     int h = this.getHeight()/TILE + 1; 
     for (int row = 0; row < h; row++) { 
      for (int col = 0; col < w; col++) { 
       if ((row + col) % 2 == 0) { 
        g.fillRect(col * TILE, row * TILE, TILE, TILE); 
       } 
      } 
     } 
    } 

    private void display() { 
     JFrame f = new JFrame("ScrollAction"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     final JScrollPane scrollPane = new JScrollPane(this); 
     final ScrollTimer left = new ScrollTimer(scrollPane, "scrollLeft"); 
     final ScrollTimer right = new ScrollTimer(scrollPane, "scrollRight"); 
     final ScrollTimer up = new ScrollTimer(scrollPane, "scrollUp"); 
     final ScrollTimer down = new ScrollTimer(scrollPane, "scrollDown"); 
     final JViewport viewPort = scrollPane.getViewport(); 
     viewPort.setPreferredSize(new Dimension(5 * TILE, 5 * TILE)); 
     viewPort.addMouseMotionListener(new MouseAdapter() { 

      @Override 
      public void mouseMoved(MouseEvent e) { 
       left.stop(); 
       if (e.getX() < DELTA) { 
        left.start(); 
       } 
       right.stop(); 
       if (e.getX() > viewPort.getWidth() - DELTA) { 
        right.start(); 
       } 
       up.stop(); 
       if (e.getY() < DELTA) { 
        up.start(); 
       } 
       down.stop(); 
       if (e.getY() > viewPort.getHeight() - DELTA) { 
        down.start(); 
       } 
      } 
     }); 
     f.add(scrollPane); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    private static final class ScrollTimer implements ActionListener { 

     private static int N = 10; 
     private static int DELAY = 100; 
     private String cmd; 
     private Timer timer; 
     private Action action; 
     private JScrollPane scrollPane; 
     private int count; 

     public ScrollTimer(JScrollPane scrollPane, String action) { 
      this.cmd = action; 
      this.timer = new Timer(DELAY, this); 
      this.action = scrollPane.getActionMap().get(action); 
      this.scrollPane = scrollPane; 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      if (count++ < N) { 
       action.actionPerformed(new ActionEvent(scrollPane, 0, cmd)); 
      } else { 
       timer.stop(); 
      } 
     } 

     public void start() { 
      count = 0; 
      timer.start(); 
     } 

     public void stop() { 
      timer.stop(); 
      count = 0; 
     } 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new ScrollAction().display(); 
      } 
     }); 
    } 
} 
+0

然後只需添加mouseDragged()用於垂直動作+1 – mKorbel

+0

添加了包含垂直動作的示例。 – trashgod

+0

不錯,很好嗯... – mKorbel