Java Swing自定义JButton移动时消失问题求助
问题根源
- 自定义
MovingButton中维护了独立的x、y变量,绘图时基于该变量定位,但Swing组件的实际显示区域由自身bounds控制。更新自定义x、y后,组件的实际位置未改变,导致绘图内容超出组件可视区域,看起来消失。 paintComponent中调用super.paintComponent(g)会绘制默认按钮样式,与自定义绘图重叠干扰。
修改方案
1. 移除自定义位置变量,复用组件自身位置
删除MovingButton中的private int x;和private int y;,直接通过getX()、getY()获取组件当前位置。
2. 调整移动逻辑,更新组件bounds
修改actionPerformed中的移动处理代码,直接更新组件的bounds来改变位置:
//Effetto movimento if (e.getSource().equals(timerMovimento)) { System.out.println("Sono qui"); int currentX = getX(); int currentY = getY(); if (currentX == finalx && currentY == finaly) { timerMovimento.stop(); System.out.println("Terminato movimento"); } int newX = currentX; int newY = currentY; // 计算新X坐标,避免超出目标位置 if (currentX != finalx) { newX += deltaX; if ((deltaX > 0 && newX > finalx) || (deltaX < 0 && newX < finalx)) { newX = finalx; } } // 计算新Y坐标,避免超出目标位置 if (currentY != finaly) { newY += deltaY; if ((deltaY > 0 && newY > finaly) || (deltaY < 0 && newY < finaly)) { newY = finaly; } } // 更新组件位置 setBounds(newX, newY, getWidth(), getHeight()); repaint(); }
3. 修正绘图逻辑,基于组件自身区域绘制
修改paintComponent,去掉默认按钮样式绘制,基于组件自身的宽高中心定位绘图:
@Override protected void paintComponent(Graphics g) { // 禁用默认按钮样式绘制,避免干扰自定义卡片绘图 // super.paintComponent(g); int centerX = getWidth() / 2; int centerY = getHeight() / 2; Graphics2D g2d = (Graphics2D) g.create(); g2d.translate(centerX, centerY); g2d.scale(scaleX, 1.0); if (!revealing) g2d.drawImage(frontCardImage, -frontCardImage.getWidth(null) / 2, -frontCardImage.getHeight(null) / 2, null); else g2d.drawImage(backCardImage, frontCardImage.getWidth(null) / 2, -backCardImage.getHeight(null) / 2, -backCardImage.getWidth(null), backCardImage.getHeight(null), null); g2d.dispose(); }
4. 调整构造函数,初始化组件位置
在MovingButton构造函数中直接设置组件初始位置,无需在main方法中重复设置:
public MovingButton(int x, int y, String cartaVisualizzataPath, String retroCartaVisualizzataPath) { // 初始化组件位置和大小 setBounds(x, y, 77, 88); this.cartaVisualizzataPath = cartaVisualizzataPath; this.retroCartaVisualizzataPath = retroCartaVisualizzataPath; timerMovimento = new Timer(10, this); timerRotazione = new Timer(10, this); try { frontCardImage = ImageIO.read(new File(this.cartaVisualizzataPath)); backCardImage = ImageIO.read(new File(this.retroCartaVisualizzataPath)); } catch (IOException e) { e.printStackTrace(); } }
5. 简化main方法
移除main方法中重复的button.setBounds(0,0,77, 88);调用:
MovingButton button = new MovingButton(0,0, backCardPath, backCardPath); // 移除该行:button.setBounds(0,0,77, 88);
说明
修改后,按钮的移动通过更新自身bounds实现,绘图区域始终在组件可视范围内,不会出现消失问题。同时保留了旋转效果的逻辑,可正常运行。
内容的提问来源于stack exchange,提问作者Andrea
相关产品推荐
相关产品推荐

