Перекраска JDialog после модификации JList - PullRequest
1 голос
/ 29 декабря 2011

У меня есть JDialog dlg, созданный JFrame frm, который содержит список JList. Когда я изменяю список (через ListModel), сам список перерисовывается, но не JDialog. Это означает, что, если я удаляю строку, список остается с пустой строкой, в то время как, если я добавляю строку, эта новая строка не будет отображаться (потому что в диалоговом окне нет места), пока я не буду принудительно перерисовывать dlg вручную ( двойной клик в фрм).

Следующие советы в этом посте: Как сделать перерисовку для JDialog в Swing?

и в этом посте: Принудительная перекраска после нажатия кнопки

Я попытался вызвать из класса моего контроллера (где производятся обновления списка) следующую строку:

SwingUtilities.getWindowAncestor(dlg).repaint();

но это не сработало. Я также попробовал:

dlg.repaint();

Не повезло, либо ...

Есть подсказка? Большое спасибо.

EDIT: Организация моих занятий выглядит следующим образом: класс контроллера, который содержит ссылку на основной JFrame, frm. Я также расширил JDialog в MyDialog, который содержит JList. Когда обнаружен двойной щелчок по frm, я показываю экземпляр MyDialog (или создаю, если я его показываю впервые), и JList заполняется данными, передаваемыми в DefaultListModel. MyDialog нарисован так, чтобы в списке было только то место, которое ему нужно. Теперь, когда контроллер обнаруживает определенное событие, я получаю конкретный MyDialog, получаю ListModel из JList и обновляю его. Здесь JList действительно обновляется, но диалог остается прежним. Я использую код, подобный этому:

MyDialog dlg = group.getDlg();
if(dlg != null){
    DefaultListModel listModel = ((DefaultListModel) dlg.getMyJList().getModel());
    listModel.addElement(idStock);
    SwingUtilities.getWindowAncestor(dlg).repaint();
}

Это не перекрашивает dlg. Я тоже попробовал:

SwingUtilities.getWindowAncestor(dlg.getMyJList()).repaint();

но это не работает.

Я проверил с помощью отладчика, что строки действительно выполняются.

У меня не так много кода, чтобы показать, правда .....

1 Ответ

6 голосов
/ 29 декабря 2011

Я думаю, что вы идете не так, определите DefaultListModel, который будет доступен через все методы и классы Java, этот Model будет содержать ваш Objects, затем поместите JList в JDialog или JOptionPane, например

import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;

// based on @trashgod code
/** @see http://stackoverflow.com/questions/5759131 */
// /7009528/perekraska-jdialog-posle-modifikatsii-jlist

public class ListDialog {

    private static final int N = 12;
    private JDialog dlg = new JDialog();
    private DefaultListModel model = new DefaultListModel();
    private JList list = new JList(model);
    private JScrollPane sp = new JScrollPane(list);
    private int count;

    public ListDialog() {
        list.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        JPanel panel = new JPanel();
        panel.add(new JButton(new AbstractAction("Add") {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                append();
                if (count <= N) {
                    list.setVisibleRowCount(count);
                    dlg.pack();
                }
            }
        }));
        panel.add(new JButton(new AbstractAction("Remove") {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                int itemNo = list.getSelectedIndex();
                if (itemNo > -1) {
                    removeActionPerformed(e, itemNo);
                }
            }
        }));
        for (int i = 0; i < N - 2; i++) {
            this.append();
        }
        list.setVisibleRowCount(N - 2);
        dlg.add(sp, BorderLayout.CENTER);
        dlg.add(panel, BorderLayout.SOUTH);
        dlg.pack();
        dlg.setLocationRelativeTo(null);
        dlg.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dlg.setVisible(true);
    }

    private void removeActionPerformed(ActionEvent e, int itemNo) {
        System.out.println("made_list's model: " + list.getModel());
        System.out.println("Model from a fresh JList: " + new JList().getModel());
        model = (DefaultListModel) list.getModel();
        if (model.size() > 0) {
            if (itemNo > -1) {
                model.remove(itemNo);
            }
        }
    }

    private void append() {
        model.addElement("String " + String.valueOf(++count));
        list.ensureIndexIsVisible(count - 1);
    }

    public static void main(String[] a_args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                ListDialog pd = new ListDialog();
            }
        });
    }
}
...