首页 > 解决方案 > 我的 Jbutton 需要鼠标悬停才能显示图片

问题描述

需要鼠标悬停才能看到带有图片的 Jbutton,我没有在任何地方@Override 我的绘图功能。如何在不需要鼠标悬停的情况下显示所有带有图像的按钮?!

鼠标悬停前图片

鼠标悬停在所有 Jbutton 上后

public class JPicButton extends JButton {
int x, y, max;

/**
 * @param path
 *            :"resources/graphics/index.jpg"
 */
public JPicButton(String fileName, int max) {
    this.max = max;
    try {
        // ImageIcon mx = new ImageIcon(JPicButton.class.getResource("/graphics/" +
        // fileName)); #works
        Image img = ImageIO.read(JPicButton.class.getResource("/graphics/" + fileName));
        img = img.getScaledInstance(10 * (40 / max), 10 * (45 / max), Image.SCALE_SMOOTH);
        ImageIcon mc = new ImageIcon(img);
        this.setIcon(mc);
    } catch (Exception ex) {
        System.out.println(ex);
        ex.printStackTrace();
    }

}

public JPicButton() {

}

public void setOrigin(int x, int y) {
    this.x = x;
    this.y = y;
}

public void setPath(String fileName) {
    try {
        Image img = ImageIO.read(JPicButton.class.getResource("/graphics/" + fileName));
        img = img.getScaledInstance(10 * (40 / max), 10 * (45 / max), Image.SCALE_SMOOTH);
        ImageIcon mc = new ImageIcon(img);
        this.setIcon(mc);
    } catch (Exception ex) {
        System.out.println(ex);
        ex.printStackTrace();
    }
}

/**
 * @return the x
 */
public synchronized int getX() {
    return x;
}

/**
 * @return the y
 */
public synchronized int getY() {
    return y;
} }

此按钮也在 Jpanel 的构造函数中初始化为

package Gui;

import javax.swing.JPanel;

 import javax.swing.JLabel;
 import javax.swing.SwingConstants;
 import java.awt.Font;
 import java.awt.Color;
 import javax.swing.JButton;
 import javax.swing.JFrame;

 @SuppressWarnings("serial")
 public class GamePage extends JPanel {
JPicButton groundMatrix[][];
int xMax, yMax;

public GamePage() {
    setBackground(Color.WHITE);
    setVisible(false);

    setLayout(null);
    setSize(700, 500);

    JLabel lblNewLabel = new JLabel("MineSweeper");
    lblNewLabel.setBounds(48, 13, 250, 50);
    add(lblNewLabel);
    lblNewLabel.setBackground(Color.PINK);
    lblNewLabel.setOpaque(true);
    lblNewLabel.setFont(new Font("Comic Sans MS", Font.PLAIN, 18));
    lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);

    JPanel game = new JPanel();
    game.setBounds(50, 80, 600, 400);
    add(game);
    game.setLayout(null);

    JLabel lblNewLabel_1 = new JLabel("");
    lblNewLabel_1.setBounds(342, 15, 66, 50);
    add(lblNewLabel_1);

    JLabel label = new JLabel("");
    label.setBounds(584, 13, 66, 50);
    add(label);

    JButton btnNewButton = new JButton("Reset");
    btnNewButton.setBounds(446, 15, 97, 50);
    add(btnNewButton);

    xMax = 15;
    yMax = 10;
    int Width = 40;
    groundMatrix = new JPicButton[xMax][yMax];

    for (int y = 0; y < yMax; y++) {
        for (int x = 0; x < xMax; x++) {
            groundMatrix[x][y] = new JPicButton("Layout1d.jpg", 10);
            groundMatrix[x][y].setLocation(Width * x, Width * y);
            groundMatrix[x][y].setSize(Width, Width);
            game.add(groundMatrix[x][y]);
            groundMatrix[x][y].setOrigin(x, y);

        }

    }

    // GridBagConstraints mineGround = new GridBagConstraints();
    // mineGround.gridheight = 45;
    // mineGround.gridwidth = 40;

}

/**
 * @return the groundMatrix
 */
public synchronized JPicButton[][] getGroundMatrix() {
    return groundMatrix;
}

/**
 * @param groundMatrix
 *            the groundMatrix to set
 */
public synchronized void setGroundMatrix(JPicButton[][] groundMatrix) {
    this.groundMatrix = groundMatrix;
}

/**
 * @return the xMax
 */
public synchronized int getxMax() {
    return xMax;
}

/**
 * @return the yMax
 */
public synchronized int getyMax() {
    return yMax;
}

public static void main(String args[]) {
    JFrame js = new JFrame();
    GamePage gd = new GamePage();
    gd.setVisible(true);
    js.add(gd);
    js.pack();
    js.setSize(700, 500);
    js.setVisible(true);
}
}

完整代码访问 https://bitbucket.org/sarjuns/minesweeper/src

标签: javaimageswingjbuttonmousehover

解决方案


观察 (tl;dr)

浏览完您的代码后,有许多问题可能会复合在一起导致各种问题,如果不是立即出现,那么会在未来出现(并且随着解决方案变得更加复杂)。

null布局的依赖

我在你的代码中看到的每一个地方setLayout(null);。这会困扰您,尤其是当您尝试在不同平台上运行代码时

Swing 和大多数体面的 UI 框架一样,有一个内置的概念,即组件应该如何以独立于平台的方式布局。

我强烈建议您花一些时间查看在容器中布局组件

查看您的代码,我可以找到使用BorderLayout,和的好地方GridBagLayout,所有这些都将大大降低代码的复杂性,使其更容易更改(如果必须)和维护,并支持不同的平台和渲染管道.GridLayoutCardLayout

使用JLayeredPane_JFrame

getLayeredPane().add(gamepage);...我不确定您认为这会带来什么好处,但这是一个非常不常见的解决方案。这JLayeredPane是向用户显示“弹出”样式信息或在内容窗格上提供“覆盖”信息的好方法,但这就是我。

问题的核心

JPicButton类中,您实现了两种方法..

/**
 * @return the x
 */
public synchronized int getX() {
    return x;
}

/**
 * @return the y
 */
public synchronized int getY() {
    return y;
}

问题是,这两种方法已经被定义JButton并且与按钮应该相对于它的父容器放置的位置相关。覆盖这些方法意味着当您使用 时setLocation,这些值将被忽略。

因此,当我修改您的代码以删除这些方法时,我得到以下结果......

终于摆好了

您尝试管理的“x/y”位置实际上应该由模型管理,GUI 应该只是模型状态的表示。

最后的话

我已经对您的代码状态发表了许多评论,否则我将不专业,因为您正在将自己挖掘到一个永无止境的返工和头疼问题的洞中,这些问题可以通过可用的问题轻松解决API 支持。

但是,我相信您在尝试解决所有问题方面取得了良好的开端,并会鼓励您继续,但要考虑到已经做出的一些观察。


推荐阅读