JButton需鼠标悬停才显示图片,如何无需悬停直接显示?
我开发的带图片的JButton必须鼠标悬停才能显示图片,且未重写paint方法。请问如何让所有带图JButton无需鼠标悬停即可直接显示?
- 鼠标悬停前状态:

- 鼠标悬停后状态:

JPicButton类代码
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; } }
按钮初始化代码(GamePage类中)
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); } }
解决方案
这个问题其实是Swing默认按钮UI的渲染逻辑导致的——很多系统风格的UI(比如Windows)会延迟按钮图标的绘制,直到鼠标交互(悬停、点击)发生。咱们可以用下面几种方法解决:
方法1:强制触发按钮刷新
在设置完图标后,手动调用组件的刷新方法,确保UI立刻绘制图标。修改JPicButton的构造方法和setPath方法:
// 构造方法中添加 this.setIcon(mc); // 新增两行刷新代码 this.revalidate(); this.repaint(); // setPath方法同样添加 this.setIcon(mc); this.revalidate(); this.repaint();
revalidate()会触发组件布局更新,repaint()则强制组件重新绘制,这样图标就能在初始状态显示出来。
方法2:改成纯图标按钮(去掉默认按钮样式)
如果你的按钮不需要自带的边框、背景样式,只想显示图片,可以禁用这些默认绘制:
在JPicButton的构造方法中添加:
this.setContentAreaFilled(false); // 禁用背景填充 this.setBorderPainted(false); // 禁用边框绘制 this.setFocusPainted(false); // 可选:去掉焦点框,更美观
这样按钮就会直接显示图标,没有默认的按钮视觉效果,初始状态就能看到图片。
方法3:统一所有状态的图标
确保按钮在正常、悬停、按下、禁用等所有状态都使用同一个图标,这样不管UI切换到什么状态,图标都会显示:
this.setIcon(mc); this.setRolloverIcon(mc); this.setPressedIcon(mc); this.setDisabledIcon(mc);
这种方法保留了按钮的默认样式,同时保证图标在任何状态下都可见。
内容的提问来源于stack exchange,提问作者ARJUN
相关产品推荐
相关产品推荐

