2017-02-02 39 views
7

Używam JTabel z jednym wierszem i dołączonym do niego MouseAdapter. Model tabeli jest wypełniany losowymi wartościami. Po kliknięciu prawym przyciskiem myszy na stole pojawi się JPopupMenu z kilkoma JMenuItems. Wizualne artefakty zaczynają się pojawiać, jeśli część wyskakującego okienka została narysowana poza panelem, do którego jest przyłączona w pewnym momencie. Interesujące jest to, że zdarza się to tylko wtedy, gdy do wyskakującego okienka nie jest dołączonych wiele elementów. Wszelkie wyskakujące okienka z więcej niż siedmioma elementami działały dla mnie konsekwentnie.Dlaczego małe JPopupMenu powoduje wizualne artefakty, a większe nie?

Testowany tylko na Windows 10 64 bit z Javą 1.8.0_112-b15.

Dlaczego tak się dzieje i czy istnieje obejście problemu?

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 umieszczenie tabeli w scrollpane robi różnicę – MadProgrammer

+0

Nie, to nie działa W moim kodzie ortograficznym tabela jest dodawana do JScrollPane i zachowuje się dokładnie w ten sam sposób: – Emiel

+3

Próbowałem dostarczonego kodu (który był doskonały, BTW) z JDK 7/8, ale nie udało się odtworzyć problemu w systemie Windows 10. Czy może to być problem z wyświetlaniem sterownika? nie podobni? –

Odpowiedz

0

Niestety, nie można dodać komentarza „przyczynę niskiej reputacji :(. Zamiast tworzenia nowego JPopupMenu za każde kliknięcie, tworzenie tylko jednego menu. Zobacz http://www.java2s.com/Tutorial/Java/0260__Swing-Event/Rightclicktotriggerthepopupmenu.htm.

+0

Jest mało prawdopodobne, aby było to przyczyną problemu. – VGR

+0

Jestem zardzewiały: co dzieje się z wszystkimi innymi JPopupMenu? –

+0

Gdy komponent nie ma żadnych odniesień i nie można go wyświetlić (https://docs.oracle.com/javase/8/docs/api/java/awt/Component.html#isDisplayable--), kwalifikuje się do usuwania śmieci kolekcja jak każdy inny obiekt. – VGR