调用JPanel的repaint实现淡入动画时子组件偏移如何解决
问题解决
问题根源
- 未开启JPanel的透明属性:JPanel默认
opaque属性为true,Swing会默认该组件绘制区域完全不透明,不需要处理下层内容。你设置了透明背景色但没有调用setOpaque(false),会导致重绘区域计算异常,最终触发子组件偏移。 - 淡入实现逻辑不合理:在
paintChildren之后叠加半透明黑色的实现方式,不仅性能开销更高,还可能出现绘制冲突。
修复方案
直接通过AlphaComposite控制整个面板的透明度实现淡入,同时开启面板透明属性即可解决偏移问题,修改后的完整代码如下:
public class PlayAgainScreen extends JPanel implements ActionListener { private final int UNIT_SIZE; private final Timer timer; private int actPer = 0; public PlayAgainScreen(SnakePanel snakePanel, boolean justLaunched) { this.UNIT_SIZE = SnakePanel.UNIT_SIZE; this.setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); this.setPreferredSize(new Dimension(UNIT_SIZE * 20, UNIT_SIZE * 15)); // 开启面板透明属性,修复重绘区域计算异常 this.setOpaque(false); PlayButton playButton = new PlayButton(snakePanel, justLaunched); Image image = new ImageIcon(Objects.requireNonNull(getClass().getClassLoader().getResource("snake_logo.png"))).getImage(); image = image.getScaledInstance((int) (this.getPreferredSize().height * 0.5), (int) (this.getPreferredSize().height * 0.5), Image.SCALE_SMOOTH); JLabel label = new JLabel(new ImageIcon(image)); gbc.insets = new Insets(0, UNIT_SIZE, 0, 0); gbc.gridx = 0; gbc.gridy = 0; this.add(playButton, gbc); gbc.gridx = 1; this.add(label, gbc); timer = new Timer(17, this); timer.start(); } @Override public void paint(Graphics g) { Graphics2D g2D = (Graphics2D) g; // 保存原始的Composite配置 Composite oldComposite = g2D.getComposite(); // 设置透明度,actPer从0到30,透明度从0到1实现淡入 g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, actPer / 30f)); // 绘制面板所有内容(包括背景、子组件) super.paint(g); // 还原原始配置,避免影响其他组件绘制 g2D.setComposite(oldComposite); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2D = (Graphics2D) g; g2D.setColor(new Color(0x543200)); g2D.fillRoundRect(0, 0, this.getWidth(), this.getHeight(), UNIT_SIZE, UNIT_SIZE); } @Override public void actionPerformed(ActionEvent e) { actPer++; repaint(); if (actPer == 30) { timer.stop(); } } }
内容的提问来源于stack exchange,提问作者Gal Arzi
相关产品推荐
相关产品推荐

