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.