【问题标题】:Java - repaint(x, y, w, h) doesn't call paintComponent? (with SSCCE)Java - repaint(x, y, w, h) 不调用paintComponent? (与SSCCE)
【发布时间】:2012-02-15 05:04:03
【问题描述】:

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

两个类:

沙盒

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);
    }
}

【问题讨论】:

    标签: java swing paint repaint paintcomponent


    【解决方案1】:

    你打电话给这个

    repaint(TLabel.this.getBounds());
    

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

    试试这个:

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

    【讨论】:

    • +1 或(在 EDT 中需要)paintImmediately docs.oracle.com/javase/6/docs/api/javax/swing/…
    • 这就是诀窍 - 将大小存储在调用之外!我也在使用 getLocationOnScreen(),但无济于事。
    • 也许您可以在我最后一个重复的问题中在这里为这个问题添加注释:stackoverflow.com/questions/9287194/… 要求删除模组,但请求被拒绝(或忽略)。无论哪种方式,到达那个问题的人都希望在这里被引导 - 再加上你的另一个接受:)
    猜你喜欢
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 2017-01-03
    • 1970-01-01
    • 2015-08-26
    • 2013-12-13
    • 2021-07-18
    • 1970-01-01
    相关资源
    最近更新 更多