事件发生后如何重新绘制JPanel
Posted
技术标签:
【中文标题】事件发生后如何重新绘制JPanel【英文标题】:how to repaint JPanel after events occured 【发布时间】:2021-08-20 13:07:54 【问题描述】:我正在尝试在事件发生后重新绘制 JPanel。我真的不知道 .repaint()
和.revalidate()
是如何工作的。每个人都告诉我它会起作用,但不适用于我。
我的代码由 ParentFrame、ChildFrame 和 Test Class 组成。测试类仅适用于main
函数。
我的项目比下面的代码要复杂一些,但我只选择了我需要弄清楚的东西。
基本上,ParentFrame 显示了我定义的 ArrayList 中的字符串。一旦我点击EDIT
按钮,ChildFrame 就会出现。然后我填写 JTextField 并单击OK
按钮。
然后 ChildFrame 必须消失,ParentFrame 应该用新编辑的 ArrayList 重新绘制。
我的项目使用addMouseListener
来选择应该编辑哪个,但我只是删除了它。因为我唯一需要弄清楚的就是如何重新绘制 JPanel。我只是将目标设置为list.get(0)
,这是第一个。
我尝试使用panel.revalidate();
+ panel.repaint();
重新绘制,但根本不起作用。
这是我的代码。需要你的帮助!!!
父框架
public class ParentFrame extends JFrame
private ArrayList<String> list = new ArrayList<>()add("test1"); add("test2");;
JPanel big;
JLabel content;
public ParentFrame()
super("parent");
super.setSize(200,200);
super.setLayout(new BorderLayout());
big = new JPanel();
for(int i=0; i<list.size(); i++)
content = new JLabel();
content.setText(list.get(i));
big.add(content);
super.add(big, BorderLayout.CENTER);
JButton edit = new JButton("EDIT");
edit.addActionListener(new EditListener());
super.add(edit, BorderLayout.SOUTH);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
public ArrayList<String> getParentList()
return list;
public void setParentList(int i, String b)
this.list.set(i,b);
public class EditListener implements ActionListener
public void actionPerformed(ActionEvent e)
ChildFrame child = new ChildFrame(ParentFrame.this);
list = child.newList;
big.revalidate();
big.repaint();
ChildFrame
public class ChildFrame extends JFrame
ArrayList<String> newList;
public ChildFrame(ParentFrame pF)
super("child");
super.setSize(100,100);
super.setLayout(new BorderLayout());
newList = pF.getParentList();
JTextField edit = new JTextField(pF.getParentList().get(0));
add(edit, BorderLayout.CENTER);
JButton ok = new JButton("OK");
ok.addActionListener(new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
newList.set(0, edit.getText());
dispose();
);
add(ok, BorderLayout.SOUTH);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
测试
public class Test
public static void main(String[] args)
ParentFrame pF = new ParentFrame();
从ParentFrame代码中可以看出,我将.revalidate()
和.repaint()
放在EditListener
的函数actionPerformed
中。但它不起作用......
【问题讨论】:
您应该在父 JFrame 中使用 JList 或 JTable。您的子 JFrame 应该是 JDialog。 见:How to Use Lists。ListDemo
示例展示了如何在 JList 中维护数据。关键是你更新了ListModel
,JList
会自动重绘自己。是的,在示例中,雇用/归档按钮都在同一个面板上。但这无关紧要。如果您想要不同面板上的按钮,则只需将 ListModel
作为参数传递给该对话框,当您更新模型时,列表将被更新。
【参考方案1】:
请注意,调用 repaint() 不会在屏幕上绘制组件。而是将组件标记为脏(这意味着它正在等待重新绘制)。 实际的重绘发生在事件调度线程上。
现在,当某些事件发生时,您的事件处理程序会被触发,您很可能会更新模型并希望触发重绘。但请注意,事件处理程序是使用事件调度程序线程触发的,只要您阻止该线程,就不会发生重绘。
所以你实际上可以做以下两件事之一:
使用快速操作更新模型,然后使用SwingUtilities.invokeLater() 触发重绘。 对于运行时间较长的操作,请创建一个单独的线程来执行该操作,然后通知 UI 重新绘制。如何做到这一点的例子在网上很多,其中之一是https://www.javamex.com/tutorials/threads/invokelater.shtml
【讨论】:
以上是关于事件发生后如何重新绘制JPanel的主要内容,如果未能解决你的问题,请参考以下文章