سؤال

لدي هذا الخطأ الغريب مع القائمة المنبثقة الخاصة بي. يحدث نادرا ويبدو بشكل عشوائي. المشكلة هي عندما يكون لديّ قائمة فرعية في jpopupmenu - عندما أقوم بتحديد القائمة الفرعية ، تختفي القائمة الرئيسية ويتم رسم القائمة الفرعية بشكل غير صحيح (يشبه المخزن المؤقت للقائمة الرئيسية على القائمة الفرعية). لا يزال بإمكاني التنقل فيها باستخدام لوحة المفاتيح.

فيما يلي بعض لقطات الشاشة: هكذا يجب أن تبدو

alt text

وهذا ما يبدو عليه عندما يظهر الخطأ:

alt text

بحيث يكون خلل في الصورة الثانية هو المكان الذي يجب أن يكون فيه القائمة الفرعية.

ما الذي يمكن أن يسبب هذا؟ لا توجد استثناءات يتم إلقاؤها ، لا يبدو مرتبطًا بالمنصة ، لذلك ليس لدي أي فكرة عن كيفية تضييق هذا الأمر. الرجاء المساعدة.

تعديل فيما يلي SSCCE يعيد إنتاج المشكلة:

import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class Test {
    private static Popup popup;

    public static void main(String[] args) {
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.getContentPane().addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                showMenu(e);
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                showMenu(e);
            }

            private void showMenu(final MouseEvent e) {
                if (e.isPopupTrigger()) {
                    JPopupMenu menu = new JPopupMenu();
                    JMenu subMenu = new JMenu("SubMenu");
                    menu.add(subMenu);

                    subMenu.add("Item 1");
                    subMenu.add("Item 2").addMouseMotionListener(new MouseAdapter() {
                        @Override
                        public void mouseMoved(MouseEvent e) {
                            hidePopup();
                            // this is where I call the hide twice, in my case it was
                            // caused by some action or mouse listener calling it twice
                            hidePopup();
                            showPopup(e, frame);
                        }
                    });
                    subMenu.add("Item 3");

                    menu.show(frame.getContentPane(), e.getX(), e.getY());
                }
            }

            private void showPopup(MouseEvent e, JFrame frame) {
                PopupFactory popupFactory = PopupFactory.getSharedInstance();
                JToolTip toolTip = new JToolTip();
                toolTip.setTipText("wfkwdlpfhd ");
                popup = popupFactory.getPopup(frame, toolTip, e.getXOnScreen(), e.getYOnScreen());
                popup.show();
            }

            private void hidePopup() {
                if (popup != null)
                    popup.hide();
            }
        });

        frame.setSize(300, 300);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
هل كانت مفيدة؟

المحلول

بفضل أحد المستخدمين ، وجدت مشكلة.

فقط في حالة قيام شخص ما بالاختراق أكثر مما ينبغي أن يفعله - هذا ما حدث: في جزء واحد من برنامجي ، أعرض رسالة منبثقة على jprogressbar التي تعرض الموقف عندما ينقل المستخدم إبهام شريط التقدم. للقيام بذلك ، أقوم بإنشاء ملف Popup باستخدام PopupFactory. بعد ذلك ، باستخدام مستمعي الماوس ، أعرض وأخفي المنبثقة. بعد الاتصال hide() لم أقم بتعيين الكائن المنبثقة على null والتي قد تؤدي إلى الاتصال hide() مرتين ، أو الحفاظ على المنبثقة من GC - لا أعرف بالضبط. ولكن يبدو أن هذا قد أفسد آلية jpopupmenu المنبثقة.

اقتباس من Popup.hide() يشرح Javadoc ذلك بشكل أفضل:

يختبئ والتخلص من المنبثقة. بمجرد التخلص من النوافذ المنبثقة ، لم تعد يجب أن تستدعي الأساليب عليها. يمكن استرداد نافذة منبثقة تم التخلص منها واستخدامها لاحقًا بناءً على popupfactory. على هذا النحو ، إذا كنت تستدعي أساليب على نافذة منبثقة ، فسوف ينتج عن السلوك غير المحدد.

نصائح أخرى

لست متأكدًا مما إذا كان سيساعد في مشكلتك ، ولكن يجب إضافة القائمة المنبثقة عادةً على هذا النحو:

table.setComponentPopupMenu(popup);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top