2017-02-02 8 views
7

Я использую одну строку JTabel с прикрепленным к ней адаптером мыши. Модель таблицы заполнена некоторыми случайными значениями. После щелчка правой кнопкой мыши на таблице появится JPopupMenu с несколькими JMenuItems. Визуальные артефакты начинают показывать, если часть всплывающего окна была выведена за пределы панели, к которой она привязана в какой-то момент. Интересно, что это происходит только в том случае, если всплывающее окно не содержит много элементов. Любое всплывающее окно с более чем семью элементами постоянно работает для меня.Почему небольшой JPopupMenu вызывает визуальные артефакты, а другой - нет?

Проверено только на Windows 10 64 бит с Java 1.8.0_112-b15.

Почему это происходит и есть ли обходной путь?

JPopupMenu artifact

public class PopupTest { 

    private static final int NUM_POPUP_ITEMS = 3; 

    private JFrame frame = new JFrame(); 
    private JPanel panel = new JPanel(); 
    private TableModel model = new TableModel(); 
    private JTable table = new JTable(); 

    public static void main(String[] a) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new PopupTest(); 
      } 
     }); 
    } 

    public PopupTest() { 
     panel.setLayout(new BorderLayout()); 
     panel.add(table, BorderLayout.CENTER); 
     panel.setPreferredSize(new Dimension(400, 500)); 
     table.setModel(model); 
     table.addMouseListener(new MouseAdapter() { 
      @Override 
      public void mousePressed(MouseEvent event) { 
       popup(event); 
      } 
     }); 
     frame.setLocation(150, 150); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setContentPane(panel); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    private void popup(MouseEvent e) { 
     if (SwingUtilities.isRightMouseButton(e)) { 
      JPopupMenu menu = new JPopupMenu(); 
      for (int i = 0; i < NUM_POPUP_ITEMS; i++) { 
       menu.add(new JMenuItem(String.valueOf(i))); 
      } 
      menu.show(panel, e.getX(), e.getY()); 
     } 
    } 

    private class TableModel extends AbstractTableModel { 

     private List<Double> dataList = new ArrayList<>(); 

     public TableModel() { 
      for (int i = 0; i < 40; i++) { 
       dataList.add(Math.random()); 
      } 
     } 

     @Override 
     public int getRowCount() { 
      return dataList.size(); 
     } 

     @Override 
     public int getColumnCount() { 
      return 1; 
     } 

     @Override 
     public Object getValueAt(int rowIndex, int columnIndex) { 
      return dataList.get(rowIndex); 
     } 
    } 
} 
+0

Does добавление таблицы в scrollpane делает разницу – MadProgrammer

+0

Нет, это не так. В моем коде orignal таблица добавляется в JScrollPane, и она ведет себя точно так же. – Emiel

+3

Я пробовал предоставленный код (что было отлично, BTW) с JDK 7/8, но не смог воспроизвести проблему в Windows 10. Может ли это быть проблемой драйвера дисплея или imilar? –

ответ

0

К сожалению, не могу добавить комментарий «причину низкой репутации :(. Вместо создания нового JPopupMenu для каждого клика, создать только одну меню. См http://www.java2s.com/Tutorial/Java/0260__Swing-Event/Rightclicktotriggerthepopupmenu.htm.

+0

Это вряд ли станет причиной проблемы. – VGR

+0

Я ржавый: что происходит со всеми остальными JPopupMenu? –

+0

Как только компонент не имеет ссылок и не отображается [https://docs.oracle.com/javase/8/docs/api/java/awt/Component.html#isDisplayable--), он имеет право на мусор как любой другой объект. – VGR