Java - 重绘(x,y,w,h)不调用paintComponent? (与SSCCE)

时间:2012-02-15 05:04:04

标签: java swing paint repaint paintcomponent

之前我问过这个问题,但理论上只是在没有SSCCE的情况下问过。现在,我创建了一个,问题仍然存在。我想知道为什么paintComponent未在repaint(x, y, w, h)上调用,而是在repaint()上调用。

两个班级:

SANDBOX

import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.JFrame;

public class Sandbox {
    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.setMinimumSize(new Dimension(800, 600));
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLayout(new FlowLayout());

        // Add label
        f.getContentPane().add(new TLabel());

        f.setVisible(true);
    }
}

TLabel (带有一点造型):

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;

@SuppressWarnings("serial")
public class TLabel extends JLabel {
    public TLabel() {
    super("TEST LABEL, NON-STATIC");
    this.setHorizontalAlignment(SwingConstants.CENTER);
    TLabel.this.setPreferredSize(new Dimension(200, 50));
    TLabel.this.setMaximumSize(new Dimension(200, 50));
    TLabel.this.setMinimumSize(new Dimension(200, 50));

    TLabel.this.setOpaque(true);
    TLabel.this.setBackground(Color.cyan.darker().darker());
    TLabel.this.setForeground(Color.white);
    TLabel.this.setBorder(new LineBorder(Color.orange, 2));

    this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                // EXPECTED BEHAVIOR HERE: This line will call paint and paintComponent.
                //repaint();

                // PROBLEM HERE: This line will not call paint or paintComponent.
                repaint(TLabel.this.getBounds());
        }
    });
    }

    @Override
    public void paint(Graphics g) {
    // Note: This is called once when the label is realised.
    // Note: This is called when the mouse enters the frame.
    System.out.println("PAINT.");
    super.paint(g);
    }

    @Override
    public void paintComponent(Graphics g) {
    // Note: This is called once when the label is realised.
    // Note: This is called when the mouse enters the frame.
    System.out.println("REPAINT.");
    super.paintComponent(g);
    }
}

1 个答案:

答案 0 :(得分:4)

你在说这个

repaint(TLabel.this.getBounds());

TLabel对象内部。因此重绘将尝试在Bounds位置绘制相对于其自身的矩形,但getBounds()返回相对于此组件包含对象位置的矩形,而重绘期望相对于组件本身的边界。因此,您尝试绘制一个矩形,该矩形具有JLabel的宽度和高度,但相对于JLabel 位于x = 292和y = 5 时相反,你希望x和y都为0.本质上你试图在这个组件之外绘制方式。

而是试试这个:

        //!! repaint(TLabel.this.getBounds());
        Dimension d = TLabel.this.getSize();
        repaint(new Rectangle(0, 0, d.width, d.height));