2010-09-29 26 views
8

Tôi muốn tạo một ứng dụng trong đó một số sự kiện được cho là được xử lý như thể chúng được gửi đến vùng chứa chính. Ví dụ tôi có một JPanel chứa JLabel. JPanel hàng đầu thực hiện việc nhấn và kéo chuột ngay bây giờ. Tôi cần phải làm gì, để làm cho các sự kiện giống như họ đã đến JPanel thay vì chính nhãn hiệu đó. (đối tượng nguồn thay đổi là quan trọng)Truyền sự kiện cho phụ huynh

Có giải pháp nào tốt hơn so với thực sự triển khai các sự kiện và sao chép chúng trong phụ huynh không? (điều này sẽ có được tẻ nhạt sau khi một số đối tượng với> 5 trẻ em).

+0

Tại sao bạn cần phải làm điều này (ví dụ)? – Pete

+0

Tôi có các đối tượng có nhiều nhãn, có thể kéo được ở bất cứ nơi nào chúng thực sự được nhấp vào lần đầu tiên. Ngay bây giờ chúng chỉ có thể kéo được khi tôi nhấp vào nền của phần tử, không phải bất kỳ nhãn nào bên trong. – viraptor

Trả lời

10

Tại trình xử lý sự kiện, bạn có thể gửi sự kiện đến thành phần chính.

myEvent xử lý sự kiện tranh cãi chức năng:

Component source=(Component)myEvent.getSource(); 
source.getParent().dispatchEvent(myEvent); 

Nhưng giải pháp này ngụ ý tạo ra một EventListener mới cho mỗi phần tử thêm vào.

Vì vậy, bạn có thể tạo một handler sự kiện duy nhất và tái sử dụng nó, thêm nó vào tất cả các trẻ em được lựa chọn, như thế này:

final Container parent=this; //we are a the parent container creation code 
MouseListener myCommonListener=new MouseListener() { 
    @Override 
    public void mouseClicked(MouseEvent e) { 
     parent.dispatchEvent(e); 
    } 
    @Override 
    public void mouseEntered(MouseEvent e) { 
     parent.dispatchEvent(e); 
    } 
    @Override 
    public void mouseExited(MouseEvent e) { 
     parent.dispatchEvent(e); 
    } 
    @Override 
    public void mousePressed(MouseEvent e) { 
     parent.dispatchEvent(e); 
    } 
    @Override 
    public void mouseReleased(MouseEvent e) { 
     parent.dispatchEvent(e); 
    } 
}; 

JLabel label=new JLabel("This is the first Label"); 
label.addMouseListener(myCommonListener); 

JLabel label2=new JLabel("This is the second Label"); 
label2.addMouseListener(myCommonListener); 
//... and so on 
+0

Điều này tạo ra một tràn ngăn xếp trong chủ đề awt (như cha mẹ đã vượt qua sự kiện trở lại kiểm soát trẻ em). Bất kỳ ý tưởng về cách để có được xung quanh vấn đề này? Tôi không thể chỉnh sửa lớp cha, nhưng tôi cần nó để có được sự kiện nhưng ngăn chặn hành động trên sự kiện mà phụ huynh sẽ quay trở lại kiểm soát của tôi. – ed22

+0

Tài nguyên-khôn ngoan đây là một ý tưởng tồi. Bạn đang thêm rất nhiều chi phí cho không có gì. Hiệu quả hơn khi loại bỏ trình lắng nghe chuột trên các phần tử con. Bạn có thể thấy câu trả lời của tôi về cách thực hiện điều đó một cách đệ quy. – qwertzguy

2

Bạn nên chuyển đổi sự kiện trước khi được phát nó cho phụ huynh. Chuyển đổi bao gồm các tọa độ dịch sang phụ huynh-người thân.

public class RedispatchingMouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener{ 

    public void mouseClicked(MouseEvent e) { 
     redispatchToParent(e); 
    } 

    public void mousePressed(MouseEvent e) { 
     redispatchToParent(e); 
    } 

    public void mouseReleased(MouseEvent e) { 
     redispatchToParent(e); 
    } 

    public void mouseEntered(MouseEvent e) { 
     redispatchToParent(e); 
    } 

    public void mouseExited(MouseEvent e) { 
     redispatchToParent(e); 
    } 

    public void mouseWheelMoved(MouseWheelEvent e){ 
     redispatchToParent(e); 
    } 

    public void mouseDragged(MouseEvent e){ 
     redispatchToParent(e); 
    } 

    public void mouseMoved(MouseEvent e) { 
     redispatchToParent(e); 
    } 

    private void redispatchToParent(MouseEvent e){ 
     Component source = (Component) e.getSource(); 
     MouseEvent parentEvent = SwingUtilities.convertMouseEvent(source, e, source.getParent()); 
     source.getParent().dispatchEvent(parentEvent); 
    } 
} 
+0

Câu trả lời của bạn thực sự là một bình luận cho câu trả lời của Tomas Narros. – SeniorJD

+0

@SeniorJD Đây là câu trả lời hoàn toàn hợp lệ. Nó đơn giản xây dựng trên câu trả lời khác và có thể tự đứng vững. Sẽ tốt hơn nếu Wojtek mô tả thêm một chút lý do tại sao điều chỉnh này là cần thiết. –

+0

Tài nguyên-khôn ngoan đây là một ý tưởng tồi. Bạn đang thêm rất nhiều chi phí cho không có gì. Hiệu quả hơn khi loại bỏ trình lắng nghe chuột trên các phần tử con. Bạn có thể thấy câu trả lời của tôi về cách thực hiện điều đó một cách đệ quy. – qwertzguy

-1

Chuột sự kiện sẽ được tự động nhắm mục tiêu đến các thành phần sâu nhất mà có nghe chuột.

Vì điều này, để đạt được mục tiêu của mình, bạn chỉ cần xóa tất cả người nghe chuột trên JLabel và nó sẽ không bao giờ được chọn làm mục tiêu cho sự kiện chuột.

Đoạn mã dưới đây sẽ vô hiệu hóa người nghe chuột trên các thành phần nhất định và con cái của họ một cách đệ quy:

private void disableMouseForComponent(Component... components) { 
    for (Component c : components) { 
     if (c instanceof Container) { 
      disableMouseForComponent(((Container) c).getComponents()); 
     } 
     for (MouseListener l : c.getMouseListeners()) { 
      c.removeMouseListener(l); 
     } 
     for (MouseMotionListener l : c.getMouseMotionListeners()) { 
      c.removeMouseMotionListener(l); 
     } 
    } 
} 
+0

Người đã -1 tuổi: bạn có quan tâm giải thích tại sao không? Làm theo cách này là tốt hơn nhiều tài nguyên khôn ngoan hơn việc thêm một người nghe gửi đến phụ huynh. – qwertzguy

Các vấn đề liên quan