简体   繁体   中英

repaint causes component overflow

I hope that I used the question function correctly this time. I have been confused by a question from yesterday to now. I used Google search to ask my java teacher and did not solve my problem.

When I use repaint , the child components in the shaped JPanel will exceed their display area. As in the following figures,

This is the effect I want 这就是我想要的效果

But when I use repaint somethings changes. 但是当我使用重绘时,某些东西会改变。

The button doesn't seem right at first. 一开始该按钮似乎不正确。

But sometimes the button will return to normal 但有时按钮会恢复正常

these are my code. I use repaint because the information I checked tells me that I can use it. Repaint to achieve animation effects.

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.RoundRectangle2D;

class GPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D)g;
        g2d.clip(new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), getWidth(), getHeight()));
        g2d.setPaint(Color.BLUE);
        g2d.fillRect(0, 0, getWidth(), getHeight());
    }
}

public class MainComponentOverflow {

    public static void main(String[] args) {
        JFrame frame = new JFrame();

        // This is a panel with a shape
        GPanel panel = new GPanel();

        // This one is the effect I am looking for, the rectangle is displayed in the Panel.
        //panel.add(new Normal());
        // The following two will have problems, the rectangle will be displayed outside the Panel
        //panel.add(new Problem1());
        panel.add(new Problem2());

        //panel.add(new JButton("This will also cause problems, but it may also display properly when I resize the window."));

        frame.add(panel);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

class Normal extends JPanel {

    public Normal() {
        setPreferredSize(new Dimension(500, 500));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.fillRect(0, 0, getWidth(), getHeight());
    }
}

class Problem1 extends JPanel implements ActionListener {

    public Problem1() {
        Timer timer = new Timer(16, this);
        timer.start();
        setPreferredSize(new Dimension(500, 500));
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.fillRect(0, 0, getWidth(), getHeight());
    }
}

class Problem2 extends JPanel implements ActionListener {

    public Problem2() {
        Timer timer = new Timer(16, this);
        timer.start();
        setPreferredSize(new Dimension(500, 500));
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        setBackground(new Color((float) Math.random(), (float)Math.random(), (float)Math.random()));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(getBackground());
        g.fillRect(0, 0, getWidth(), getHeight());
    }
}

When the frame is painted first, the clip will be set in GPanel , and then the children will be painted in Problem1 with the same clip, so it will work.

However, when you repaint Problem1 , GPanel will not be repainted first, so the clip isn't set, and there is no clip to restrict Problem1 .

If instead of repainting Problem1 you repaint the parent, GPanel , it will resolve your problem.

Another solution would be to put the clip in Problem1 too.

Note that you can replace your RoundRect2D with an Ellipse2D , as you use it to paint an ellipse.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM