You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Swing自定义JButton移动时消失问题求助

解决自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 00:49:53