Java - repaint (x, y, w, h) не вызывает paintComponent?(с SSCCE) - PullRequest
3 голосов
/ 15 февраля 2012

Я спрашивал об этом раньше, но только теоретически, без 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 Ответ

4 голосов
/ 15 февраля 2012

Вы вызываете это

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