Java JPanel中,repaint(),paint(),方法的区别?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java JPanel中,repaint(),paint(),方法的区别?相关的知识,希望对你有一定的参考价值。

麻烦详细一点。

repaint方法调用时会向你的程序发送一个消息,要求重绘你的程序的窗口的无效区域。

但这个消息会首先保存到应用程序的消息队列,并不会马上得到处理。

每个图形用户界面应用程序都有一个消息循环,作用是不断地从应用程序消息队列提取各种消息并交由指定的方法进行处理。

所以,repaint方法的作用就是发送一个刷新窗口的消息到消息队列,而消息循环时如果提取到了这个repaint方法发送的消息,就会调用paint方法来处理这个消息。

即repaint只负责发送消息,而消息的处理是由paint方法完成的。

所以,应该重写paint方法,将绘图逻辑放置其中。追问

已采纳

那我调用paint()会怎么样?

还有个就是我调用super.paint(g);和super.repaint(g);方法有什么用?

参考技术A paint是在画板一创建的时候就执行了
repaint在特定的情况下执行重绘
paint只执行一次,而repaint可以执行无数次

事件发生后如何重新绘制JPanel

【中文标题】事件发生后如何重新绘制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 中维护数据。关键是你更新了ListModelJList 会自动重绘自己。是的,在示例中,雇用/归档按钮都在同一个面板上。但这无关紧要。如果您想要不同面板上的按钮,则只需将 ListModel 作为参数传递给该对话框,当您更新模型时,列表将被更新。 【参考方案1】:

请注意,调用 repaint() 不会在屏幕上绘制组件。而是将组件标记为脏(这意味着它正在等待重新绘制)。 实际的重绘发生在事件调度线程上。

现在,当某些事件发生时,您的事件处理程序会被触发,您很可能会更新模型并希望触发重绘。但请注意,事件处理程序是使用事件调度程序线程触发的,只要您阻止该线程,就不会发生重绘。

所以你实际上可以做以下两件事之一:

使用快速操作更新模型,然后使用SwingUtilities.invokeLater() 触发重绘。 对于运行时间较长的操作,请创建一个单独的线程来执行该操作,然后通知 UI 重新绘制。

如何做到这一点的例子在网上很多,其中之一是https://www.javamex.com/tutorials/threads/invokelater.shtml

【讨论】:

以上是关于Java JPanel中,repaint(),paint(),方法的区别?的主要内容,如果未能解决你的问题,请参考以下文章

如果在 JFrame 代码中调用 repaint(),JPanel 不会重新绘制

java游戏开发杂谈 - 界面刷新坐标系

什么决定了 Java 中的组件可见性?

Java 的 JPanel 子类中重写父类的 paint 方法 会被自动调用,请问调用的条件或时机

交换JPanel,第二个JPanel不显示

事件发生后如何重新绘制JPanel