修改JList后重绘JDialog [英] JDialog repaint after JList modification

查看:74
本文介绍了修改JList后重绘JDialog的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个由JFrame frm创建的JDialog dlg,其中包含一个JList列表. 当我修改列表(通过ListModel)时,列表本身会重新绘制,但JDialog不会. 这意味着,如果我删除一行,该列表将保留为空行,而如果添加一行,则在我手动强制重新绘制dlg之前,将不会显示此新行(因为对话框中没有空格).双击frm).

I have a JDialog dlg, created by a JFrame frm, that contains a JList list. When I modify the list (through the ListModel), the list itself is repainted but not the JDialog. This means that, if I delete a line, the list remains with an empty line while if I add a line, this new line won't be shown (because there is no space in the dialog) until I manually force repainting of dlg (doubleclicking in frm).

此帖子中的以下建议: 如何在Swing中为JDialog进行重绘?

Following advices in this post : How to make repaint for JDialog in Swing?

在这篇文章中: 单击按钮后强制重涂

我试图从我的控制器类(进行列表更新的地方)中调用以下行:

I tried to call, from my controller class (which is where updates to list are made), the following line:

SwingUtilities.getWindowAncestor(dlg).repaint();

但是没有用. 我也尝试过:

but it didn't work. I also tried:

dlg.repaint();

也没有运气...

有任何线索吗? 非常感谢.

Any clue? Thank you very much.

我的课程安排如下: 包含对主JFrame frm的引用的控制器类. 我还将JDialog扩展到MyDialog中,该对话框包含一个JList. 当检测到对frm的双击时,我将显示MyDialog的实例(如果是我第一次显示,则创建一个),并且JList会填充传递给DefaultListModel的数据. MyDialog已绘制,因此列表仅具有所需的空间. 现在,当控制器检测到特定事件时,我将获取特定的MyDialog,从JList获取ListModel并对其进行更新.这里的JList确实已更新,但是Dialog保持不变. 我使用这样的代码:

The organization of my classes is as follows: a controller class that contains a reference to the main JFrame, frm. I also extended JDialog into MyDialog, which contains a JList. When a doubleclick on frm is detected, I show the instance of MyDialog (or create, if it is the first time I show it) and the JList is filled with the data passed to the DefaultListModel. MyDialog is painted so that the list has only the space that it needs. Now, when a specific event is detected by the controller, I get the specific MyDialog, get the ListModel from JList and update it. Here the JList is indeed updated, but Dialog remains the same. I use a code like this:

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

这不会重绘dlg. 我也尝试过:

This doesn't repaint dlg. I also tried:

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

但它不起作用.

我与调试器一起检查了这些行是否已实际执行.

I checked with the debugger that the lines are actually executed.

我没有更多的代码要显示,真的.....

I don't have much more code to show, really.....

推荐答案

我认为您做错了事,定义在所有Java方法和类中均可使用的DefaultListModel,此Model将保存您的Objects,然后例如,将JList放入JDialogJOptionPane

I think that you going wrong way, define DefaultListModel that accesible throught all Java methods and Classes, this Model would holds your Objects, then put JList to the JDialog or JOptionPane, for example

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

// based on @trashgod code
/** @see http://stackoverflow.com/questions/5759131 */
// http://stackoverflow.com/questions/8667719/jdialog-repaint-after-jlist-modification

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();
            }
        });
    }
}

这篇关于修改JList后重绘JDialog的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆