2015-03-26 14 views
8

enter image description hereJavaFX MenuItem không thể hủy bằng cách di chuyển con chuột đi

Nếu bạn giữ click chuột vào một trong các MenuItems, và sau đó kéo chuột đi, nút sẽ vẫn được chọn. Ngay cả khi bạn kéo chuột đến New hoặc Save, nút Open sẽ vẫn được chọn. Nếu bạn nhả chuột ra bất kỳ nơi nào bên ngoài Open, lệnh sẽ vẫn thực hiện. Theo thứ tự, thời điểm bạn giữ chuột xuống, sắp xảy ra rằng Open 's onAction() sẽ được gọi.

Điều này khác với hành vi bình thường trong Mac OSX và, tôi đoán là các ứng dụng gốc của Windows. Trong đó, ngay cả khi bạn đang giữ nút bấm trên MenuItem, nếu bạn di chuyển chuột đi, nút sẽ không kích hoạt. Nhưng nó xảy ra với JavaFX.

Tôi có thể làm gì để khắc phục vấn đề này? JavaFX 8.

+0

Có thể gửi một [báo cáo lỗi] (https://javafx-jira.kenai.com) về việc này. – jewelsea

+0

Ai đó có thể nộp nó không? Tôi hoàn toàn không quen thuộc với nền tảng đó. – Voldemort

+1

Đã xảy ra sự cố đã biết, được báo cáo [tại đây] (https://javafx-jira.kenai.com/browse/RT-22442) – crusam

Trả lời

0

Tôi không biết nếu tôi định nói gì là ngu ngốc. Nhưng bạn nên thử sử dụng một sự kiện chuột thay vì một sự kiện hành động. Chỉ cần nói.

0

TUYÊN BỐ TỪ CHỐI: Đây không phải là giải pháp thích hợp, nó là xấu xí, không được kiểm tra tốt và có nhiều hạn chế (xem bên dưới). Ngoài ra nó có thể sẽ phá vỡ với bản phát hành Java tiếp theo, NHƯNG nó giải quyết được vấn đề trong trường hợp vani trơn chuẩn của tôi vì vậy tôi quyết định chia sẻ nó chỉ trong trường hợp ai đó có thể thấy nó hữu ích. Sử dụng nó rủi ro của riêng bạn! :)

Tôi cũng có một hy vọng nhỏ rằng ai đó có kiến ​​thức tốt hơn về API skin JavaFX có thể cải thiện nó, tôi sẽ đánh giá cao!

Những hạn chế:

  • Chỉ làm việc cho ContextMenu, không phải với menu chính (đây là trường hợp sử dụng của tôi)
  • Chỉ làm việc cho các menu một cấp (không thể tìm ra cách để mở rộng cho menu con)
  • Không chắc chắn nếu nó hoạt động với CustomMenuItem s hoặc với MenuItem s với số Graphic, nhưng có thể!
  • Nó dựa trên tiêu chuẩn ContextMenuContent làm da cho ContextMenu. Nếu bạn có làn da của riêng bạn thì nó sẽ không hoạt động.

Đây là lớp helper:

public class ContextMenuFixer { 

public static void fix(ContextMenu contextMenu) { 
    if (contextMenu.getSkin() != null) { 
     fix(contextMenu, (ContextMenuContent) contextMenu.getSkin().getNode()); 
    } else { 
     contextMenu.skinProperty().addListener((observable, oldValue, newValue) -> { 
      if(newValue != null) { 
       fix(contextMenu, (ContextMenuContent) contextMenu.getSkin().getNode()); 
      } 
     }); 
    } 
} 

private static void fix(ContextMenu menu, ContextMenuContent content) { 

    content.getItemsContainer().getChildren().forEach(node -> { 

     EventHandler<? super MouseEvent> releaseEventFilter = event -> { 
      if (!((Node) event.getTarget()).isFocused()) { 
       event.consume(); 
       menu.hide(); 
      } 
     }; 
     node.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> { 
      node.removeEventFilter(MouseEvent.MOUSE_RELEASED, releaseEventFilter); 

     }); 

     node.addEventHandler(MouseEvent.DRAG_DETECTED, event -> { 
      node.startFullDrag(); 
      node.addEventFilter(MouseEvent.MOUSE_RELEASED, releaseEventFilter); 
     }); 

     node.addEventHandler(MouseDragEvent.MOUSE_DRAG_ENTERED, event -> { 
      MouseEvent e = event.copyFor(event.getSource(), event.getTarget(), MouseEvent.MOUSE_ENTERED); 
      node.fireEvent(e); 
     }); 

     node.addEventHandler(MouseDragEvent.MOUSE_DRAG_RELEASED, event -> { 
      Event e = event.copyFor(event.getSource(), event.getTarget(), MouseEvent.MOUSE_RELEASED); 
      node.fireEvent(e); 
     }); 

     node.addEventHandler(MouseDragEvent.MOUSE_DRAG_EXITED, event -> { 
      node.getParent().requestFocus(); 
     }); 

     node.addEventHandler(MouseEvent.MOUSE_RELEASED, event -> { 
      menu.hide(); 
     }); 

    }); 
} 

}

Cách sử dụng rất đơn giản:

ContextMenuFixer.fix(myContextMenu); 

T.B. Một giải pháp sạch sẽ là viết lớp da thích hợp của riêng bạn (tức là, để thay thế ContextMenuContent) nhưng tôi cố ý không muốn đi theo cách đó vì chi phí bảo trì.

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