重绘会导致组件溢出

问题描述 投票:1回答:1

我希望这次我正确使用了问题功能。我从昨天到现在的一个问题感到困惑。我使用Google搜索来询问我的java老师并没有解决我的问题。

当我使用repaint时,形状为JPanel的子组件将超出其显示区域。如下图所示,

这就是我想要的效果

但是,当我使用重绘时,某些事情发生了变化。

一开始按钮似乎不正确。

但有时按钮会恢复正常

这些是我的代码。我使用重绘,因为我检查的信息告诉我,我可以使用它。重绘以实现动画效果。

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());
    }
}
java swing user-interface jpanel
1个回答
0
投票

首先绘制框架时,剪辑将设置在GPanel中,然后孩子们将使用相同的剪辑在Problem1上绘制,因此它将起作用。

但是,当您重新绘制Problem1时,GPanel将不会被重新绘制,因此剪辑未设置,并且没有剪辑来限制Problem1

如果不重新绘制Problem1重新绘制父母GPanel,它将解决您的问题。

另一种解决方案是将剪辑放入Problem1

请注意,您可以使用RoundRect2D替换Ellipse2D,因为您使用它来绘制椭圆。

© www.soinside.com 2019 - 2024. All rights reserved.