我有一个由JFrame frm创建的JDialog dlg,它包含一个JList列表。 当我修改列表(通过ListModel)时,列表本身被重新绘制,但不是JDialog。 这意味着,如果我删除一行,列表将保留一个空行,而如果我添加一行,则不会显示此新行(因为对话框中没有空格),直到我手动强制重新绘制dlg(双击frm)。
根据这篇文章中的建议: How to make repaint for JDialog in Swing?
并在这篇文章中: Force repaint after button click
我试图从我的控制器类(这是列表更新的位置)调用,如下所示:
SwingUtilities.getWindowAncestor(dlg).repaint();
但它不起作用。 我也尝试过:
dlg.repaint();
没有运气......
有任何线索吗? 非常感谢你。
编辑: 我的课程组织如下: 一个控制器类,包含对主JFrame的引用,frm。 我还将JDialog扩展为MyDialog,其中包含一个JList。 当检测到双击frm时,我会显示MyDialog的实例(或创建,如果它是我第一次显示它),并且JList填充了传递给DefaultListModel的数据。绘制了MyDialog,使列表只有它所需的空间。 现在,当控制器检测到特定事件时,我得到特定的MyDialog,从JList获取ListModel并更新它。这里JList确实更新了,但Dialog保持不变。 我使用这样的代码:
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();
但它不起作用。
我检查了调试器实际执行的行。
我没有更多的代码可以显示,真的.....
答案 0 :(得分:6)
我认为你错误的方式,定义可通过所有Java方法和类访问的DefaultListModel
,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 */
// 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();
}
});
}
}