Jpopupmenu Bug/Glitch (؟) عند إظهار القائمة الفرعية
-
29-09-2019 - |
سؤال
لدي هذا الخطأ الغريب مع القائمة المنبثقة الخاصة بي. يحدث نادرا ويبدو بشكل عشوائي. المشكلة هي عندما يكون لديّ قائمة فرعية في jpopupmenu - عندما أقوم بتحديد القائمة الفرعية ، تختفي القائمة الرئيسية ويتم رسم القائمة الفرعية بشكل غير صحيح (يشبه المخزن المؤقت للقائمة الرئيسية على القائمة الفرعية). لا يزال بإمكاني التنقل فيها باستخدام لوحة المفاتيح.
فيما يلي بعض لقطات الشاشة: هكذا يجب أن تبدو
وهذا ما يبدو عليه عندما يظهر الخطأ:
بحيث يكون خلل في الصورة الثانية هو المكان الذي يجب أن يكون فيه القائمة الفرعية.
ما الذي يمكن أن يسبب هذا؟ لا توجد استثناءات يتم إلقاؤها ، لا يبدو مرتبطًا بالمنصة ، لذلك ليس لدي أي فكرة عن كيفية تضييق هذا الأمر. الرجاء المساعدة.
تعديل فيما يلي 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);