Не удаляются контролы, созданные в цикле

213
28 февраля 2017, 15:40

Путем цикла я создала метки. Мне нужно, чтобы, когда я кликну на них мышкой, они исчезали. Кликнула на одну, она исчезла, на другую и так далее. Но, когда я запускаю, метки не пропадают. Что нужно сделать, чтобы все работало так, как надо?

    lol = new JPanel();
    lol.setBounds(10, 47, 974, 693);
    contentPane.add(lol);
    lol.setLayout(null);
    for (int k = 0; k < 50; k++){
        label_2 = new JLabel("");
        label_2.setIcon(new ImageIcon(P.class.getResource("/images/00.png")));
        int w = randomRange(10, 974);
        int r = randomRange(10, 693);
        label_2.setBounds(w, r, 200, 200);
        label_2.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                lol.remove(label_2);
            }
        });
        lol.add(label_2);
    }
Answer 1
lol.remove((JLabel)e.getComponent());

или

lol.remove((JLabel)e.getSource());
Answer 2

И вариант с циклом для полноты картины:

for (int k = 0; k < 50; k++)
{
    JLabel label_2 = new JLabel("Label" + k);
    label_2.addMouseListener(new MouseAdapter()
    {
        @Override
        public void mouseClicked(MouseEvent e)
        {
            lol.remove(label_2);
        }
    });
    lol.add(label_2);
}

Разница в том, что переменная label_2 объявляется внутри цикла, а не снаружи. Поэтому во внутреннем классе используется метка из текущей итерации, а не последняя из созданных.

После lol.remove(label_2); в обработчик события можно добавить frame.repaint();, если отсутствует постоянная отрисовка в цикле.

Answer 3

Проблема в замыкании, а именно в этой строчке:

lol.remove(label_2);

Когда цикл завершается, в переменной label_2 находится последняя поставленная метка. Когда отрабатывает событие клика, то удаляется только эта последняя метка. Вам нужно изменить способ удаления (а точнее, способ получения нужного экземпляра метки)

Answer 4
for(...) {...}

Выполняется мгновенно, и по этому Event не проверяется, ибо Проверка на клик находиться в теле for'a

Должно быть что-то типо:

...    
for (int k = 0; k < 50; k++){
    label_2 = new JLabel("");
    label_2.setIcon(new ImageIcon(P.class.getResource("/images/00.png")));
    int w = randomRange(10, 974);
    int r = randomRange(10, 693);
    label_2.setBounds(w, r, 200, 200);
    label_2.addMouseListener(new MouseAdapter() {
    });
    lol.add(label_2);
        @Override
        public void mouseClicked(MouseEvent e) {
            lol.remove(label_2);
        }
READ ALSO
Я хочу отображать на экране файлы, которые были созданы time или менее минут назад, и папки их содержащие.

Я хочу отображать на экране файлы, которые были созданы time или менее минут назад, и папки их содержащие.

В эмуляторе все работает как надо, однако на реальных устройствах появляется куча давно созданных файловНе подскажете, почему так происходит?

237
LazyInitializationException и JasperException в JSP

LazyInitializationException и JasperException в JSP

Есть MySQL база с 1 таблицей пользователей, есть простейшее CRUD приложение со Spring MVC и, собственно, Hibernate для работы с этой базойВсе по туториалам:...

279
Нужно ли обходить NAT при p2p использовании RtpStream?

Нужно ли обходить NAT при p2p использовании RtpStream?

Я собираюсь стримить звук с микрофона смартфона android на другой android смартфонЕсть сервер который используется только для идентификации, после...

219
Не отображается MyLocationButton google maps на android 6.0

Не отображается MyLocationButton google maps на android 6.0

На android 60 не отображается LocationButton google maps

260