2011-08-26 4 views
2

저는 Swing에서 Touch User 인터페이스로 작업 중입니다. 이것이 최적이 아니라는 것을 알고있는 동안, 나는 짧은 마감 시간을 가지며 Touch-screen 특정 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의이 JComponent의 모든 종류의 컨테이너 것입니다. 처음 작업을 시작했을 때 MouseMovedEvent 및 MouseDraggedEvent가 해당 이벤트에 대한 수신기와 함께 Component를 만날 때까지 'GUI 트리'를 전파한다고 생각했습니다. 이제는 panScrollPane에 추가 한 모든 구성 요소가 이러한 MouseMotion 이벤트를 차단하여 팬이 표시되지 않는 것으로 보입니다.

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

나는 (모든 단일 구성 요소에 청취자를 추가 한 다음 자신의 부모에게 이벤트를 보내도록) 일 것이다 손으로 된 MouseEvent를 전파하는 생각. 그러나 이것은 매우 시간이 많이 걸리는 작업이며 다른 것들에 대한 작업에 시간을 할애하기 때문에이 문제에 대한 해결 방법을 알고 있는지 궁금합니다.

읽고 감사드립니다. 답변 해 주셔서 감사합니다. :)

편집 : 나의 의도를 명확하게하기. panPanel에서 mousemotion 이벤트를 잡아 주기만하면 MouseEvent, MouseRelease와 같은 다른 이벤트는 정상적으로 처리되어야합니다.

답변

2

GlassPane을 사용하는 것은 어떻습니까? 나는 그것이 상황의 이러한 유형을 정확하게 다루는 것을 의미한다고 생각합니다.

+0

유망하지만 유리판은 'catch'(MouseMotion 것) 또는 가능한 모든 이벤트에 관심이있는 이벤트 만 '캐치'합니까? –

+0

튜토리얼 코드는 잔여 이벤트를 전파하는 방법을 보여줍니다.이 유리 창으로 테스트 해 보겠습니다 :) 고마워요! –

+0

@Erwin 드래그 이벤트를 수신하기 위해서, MouseInputAdapter를 mouseListner로서 부모에게 추가 할 수 있습니다. 다른 이벤트들, 나는 그것을 통해서만 자식 구성 요소로 보내질 것이라고 생각합니다. –

2

구성 요소 및 모든 해당 하위 항목에 대한 mouseEvents 가져 오기는 ... 옳다는 것은 까다 롭습니다. 안정적인 (그리고 광범위하게 테스트 된 :-) 코드에 의존하는 것을 고려할 수 있습니다. jdk7 방법은 JLayer를 사용하는 것입니다. JLayer는 모든 권한을 가지고 있기 때문에 AWTEventListener를 내부적으로 등록합니다. 이전 버전의 경우 이전 모델이 임시 접근 방식은 일반적으로 key bindings에서 사용되는 기존의 JScrollPane 조치를 활용 JXLayer

+0

또는 MouseButton이 여전히 눌려 졌는지 확인하려면 +1 – mKorbel

7

를 사용할 수 있습니다. 을 구현하려면 N을 조정해야합니다.

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

좋은, 좋은 hmmm ... – mKorbel

관련 문제