修改JList后重绘JDialog [英] JDialog repaint after JList modification
问题描述
我有一个由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
放入JDialog
或JOptionPane
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屋!