2015-03-26 6 views
8

enter image description hereJavaFX MenuItem दूर

माउस को ले जाकर रद्द नहीं किया जा सकता आप MenuItems में से एक पर माउस क्लिक करके रखते हैं, और उसके बाद खींचें माउस दूर, बटन चयनित रहेंगे। यहां तक ​​कि यदि आप माउस को New या Save पर खींचते हैं, तो Open बटन चयनित रहेगा। यदि आप कहीं भी Open के बाहर माउस छोड़ते हैं, तो आदेश अभी भी निष्पादित करेगा। शब्दों के क्रम में, जिस क्षण आपने माउस को नीचे रखा था, यह आसन्न है कि Open का onAction() कहा जाएगा।

यह मैक ओएसएक्स में सामान्य व्यवहार से अलग है और, मुझे लगता है, विंडोज मूल अनुप्रयोग। उनमें, भले ही आप मेनूइटम पर क्लिक दबा रहे हों, अगर आप माउस को दूर ले जाते हैं, तो बटन ट्रिगर नहीं होगा। लेकिन यह जावाएफएक्स के साथ होता है।

इसे ठीक करने के लिए मैं क्या कर सकता हूं? जावाएफएक्स 8.

+0

शायद इस बारे में एक [बग रिपोर्ट] (https://javafx-jira.kenai.com) दर्ज करें। – jewelsea

+0

क्या कोई और इसे फाइल कर सकता है? मैं उस मंच के साथ वास्तव में बिल्कुल परिचित नहीं हूँ। – Voldemort

+1

यह पहले से ही एक ज्ञात मुद्दा है, [यहां] (https://javafx-jira.kenai.com/browse/RT-22442) – crusam

उत्तर

0

मुझे नहीं पता कि मैं जो कहने जा रहा हूं वह बेवकूफ है। लेकिन आपको एक क्रिया के बजाए माउस इवेंट का उपयोग करने का प्रयास करना चाहिए। बस कह रहा है।

0

अस्वीकरण: यह उचित समाधान नहीं है, यह बदसूरत है, अच्छी तरह से परीक्षण नहीं किया गया है, और इसमें कई सीमाएं हैं (नीचे देखें)। इसके अलावा यह शायद अगली जावा रिलीज, लेकिन के साथ तोड़ देगा, इसने मेरे सुंदर मानक सादे वेनिला मामले में समस्या हल की है, इसलिए मैंने इसे साझा करने का फैसला किया, अगर किसी को इसे उपयोगी लगे। इसे अपने जोखिम का प्रयोग करें! :)

मुझे भी एक छोटी उम्मीद है कि जावाएफएक्स स्किनिंग एपीआई के बेहतर ज्ञान वाले किसी व्यक्ति को इसमें सुधार हो सकता है, मैं सराहना करता हूं!

सीमाएं:

  • केवल ContextMenu लिए काम करता है, मुख्य मेनू (यह मेरा उपयोग मामला था)
  • केवल एक स्तर के मेनू के लिए काम करता है (के साथ नहीं समझ नहीं सकता है के लिए विस्तार करने के लिए कैसे सबमेनस)
  • यह सुनिश्चित नहीं है कि यह CustomMenuItem एस के साथ काम करता है, या MenuItem एस Graphic के साथ काम करता है, लेकिन यह हो सकता है!
  • यह ContextMenu के लिए एक त्वचा के रूप में मानक ContextMenuContent पर निर्भर करता है। यदि आपकी अपनी त्वचा है तो यह काम नहीं करेगा।

    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(); 
         }); 
    
        }); 
    } 
    

    }

    प्रयोग बहुत सीधा है::

    ContextMenuFixer.fix(myContextMenu); 
    

    पी.एस.

यहाँ सहायक वर्ग है एक क्लीनर समाधान आपकी खुद की उचित त्वचा कक्षा (यानी ContextMenuContent को प्रतिस्थापित करने के लिए) लिखना होगा, लेकिन मैं जानबूझकर रखरखाव लागत के कारण इस तरह से नहीं जाना चाहता था।