java - 父面板未正确重绘

标签 java swing repaint invalidation

我有一个面板,其中包含已添加到其中的自定义组件。它正确绘制,除非组件(有自己的鼠标监听器)被拖动时它开始奇怪地绘制。

有趣的是,如果我稍微调整父面板的大小,它现在将按预期绘制。我知道父面板正在通过

重新绘制
 super.paintComponent(g);

以及面板内的打印语句

paintComponent(Graphics g):

方法。我尝试在组件被拖动时重新验证(因为组件正在重新设置其边界),它会变得无效。我仍然没有成功,想知道是否有人可以提供帮助。

是否有一些地方我没有正确重新绘制,可能会导致此行为?

另外作为附录,我在面板及其组件上都有一个鼠标监听器,有没有一种方法可以使单击组件时面板鼠标监听器也会做出响应(除了从组件返回到父类之外)

这是我遇到的问题的一个工作示例

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Line2D;
import javax.swing.*;

public class testHome {

    private JFrame frame;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    testHome window = new testHome();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public testHome() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new myPanel();
        frame.getContentPane().add(panel, BorderLayout.CENTER);
    }
}

class myPanel extends JPanel {

    MyComponent comp;

    public myPanel() {
        super(null);
        comp = new MyComponent(5, 5);
        this.add(comp);
        revalidate();
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        Line2D.Double line = new Line2D.Double(10, 10, comp.getX(), comp.getY());
        System.out.println(comp.getX() + " " + comp.getY());
        g2d.draw(line);
    }
}

class MyComponent extends JComponent implements MouseListener, MouseMotionListener {

    int x;
    int y;

    int mx;
    int my;

    public MyComponent(int x, int y) {
        this.setVisible(true);
        this.setBounds(x, y, 15, 15);
        this.x = x;
        this.y = y;
        addMouseMotionListener(this);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.black);
        g2d.fillRect(this.x, this.y, 15, 15);
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        // TODO Auto-generated method stub
        System.out.println("dragging");
        int dx = e.getX() - mx;
        int dy = e.getY() - my;
        this.setBounds(this.getX() + dx, this.getY() + dy, 15, 15);
    }

    @Override
    public void mousePressed(MouseEvent e) {
        mx = e.getX();
        my = e.getY();
    }

    @Override
    public void mouseMoved(MouseEvent e) {}

    @Override
    public void mouseClicked(MouseEvent e) {}

    @Override
    public void mouseEntered(MouseEvent e) {}

    @Override
    public void mouseExited(MouseEvent e) {}

    @Override
    public void mouseReleased(MouseEvent e) {}
}

最佳答案

父面板实际上并没有完全自动重新绘制。 paintComponent() 被调用,但如果您检查剪辑,例如通过:

System.out.println(g.getClipBounds());

您将看到仅绘制了较小组件下方的区域。 (该组件不是不透明的,因此父组件需要绘制其下方的区域)。您需要为父面板显式调用 repaint():

getParent().repaint();

(或者使用指定区域的 repaint() 变体,如果父组件的绘制成本很高并且可以优化部分绘制)。

关于java - 父面板未正确重绘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33195070/

相关文章:

java - 如何在 Android 中制作持久抽屉导航?

java - 如何解决第 1 行第 "Incorrect integer value: ' 列的错误 'type_id' null'?

java - 第一次调用 JPanel repaint() 方法会创建不需要的背景图像

java - Swing 中的绘画不起作用

java - 线程和重绘()

java - EclipseLink - 合并更新尚未更改的列

java - 获取 java.io.IOException : CreateProcess: c:\Windows\System32\My_exe 1 error=2

Java Swing - 使用 JScrollPane 并让它滚动回顶部

游戏循环和按钮的 Java 图形问题

java - 单击按钮时如何显示新的 Jframe