如何解决Java Swing:按钮仅在鼠标悬停时显示图标
我有 Swing 应用程序,我想在其中在 JButton 上显示一个图标。我在 Windows 缩放图标并使其变得非常丑陋时遇到了一些问题。我能够通过使用 here 中描述的 Icon-Wrapper 类来解决该问题。
使用包装类解决了我遇到的缩放问题,但导致了一个新问题:图标仅在我将鼠标悬停在按钮上时才会显示,如下所示:
这是一个最小的例子:
import javax.swing.*;
import java.awt.*;
import java.net.MalformedURLException;
import java.net.URL;
public class Ui {
private static JFrame frame;
private static JButton button1;
private static JButton button2;
private static JMenuBar jMenuBar;
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
createGui();
} catch (MalformedURLException e) {
e.printStackTrace();
}
});
}
private static void createGui() throws MalformedURLException {
frame = new JFrame("Test");
button1 = new JButton();
button2 = new JButton();
jMenuBar = new JMenuBar();
Icon icon = new NoScalingIcon(new ImageIcon(new URL("https://i.stack.imgur.com/wgKeq.png")));
button1.setIcon(icon);
button2.setIcon(icon);
jMenuBar.add(button1);
jMenuBar.add(button2);
frame.setJMenuBar(jMenuBar);
frame.pack();
frame.setVisible(true);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
}
}
图标包装类:
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
public class NoScalingIcon implements Icon {
private Icon icon;
public NoScalingIcon(Icon icon) {
this.icon = icon;
}
public int getIconWidth() {
return icon.getIconWidth();
}
public int getIconHeight() {
return icon.getIconHeight();
}
public void paintIcon(Component c,Graphics g,int x,int y) {
Graphics2D g2d = (Graphics2D) g.create();
AffineTransform at = g2d.getTransform();
int scaleX = (int) (x * at.getScaleX());
int scaleY = (int) (y * at.getScaleY());
int offsetX = (int) (icon.getIconWidth() * (at.getScaleX() - 1) / 2);
int offsetY = (int) (icon.getIconHeight() * (at.getScaleY() - 1) / 2);
g2d.setTransform(new AffineTransform());
icon.paintIcon(c,g2d,scaleX + offsetX,scaleY + offsetY);
g2d.dispose();
}
}
此问题的原因可能是什么?
解决方法
我想我找到了解决方案。
下面的代码不是创建一个全新的 AffineTransform
,而是将一个新的缩放变换与现有缩放的逆合并,因此缩放因子设置回 1:
import java.awt.*;
import java.awt.geom.AffineTransform;
import javax.swing.*;
public class NoScalingIcon implements Icon
{
private Icon icon;
public NoScalingIcon(Icon icon)
{
this.icon = icon;
}
public int getIconWidth()
{
return icon.getIconWidth();
}
public int getIconHeight()
{
return icon.getIconHeight();
}
public void paintIcon(Component c,Graphics g,int x,int y)
{
Graphics2D g2d = (Graphics2D)g.create();
AffineTransform at = g2d.getTransform();
int scaleX = (int)(x * at.getScaleX());
int scaleY = (int)(y * at.getScaleY());
int offsetX = (int)(icon.getIconWidth() * (at.getScaleX() - 1) / 2);
int offsetY = (int)(icon.getIconHeight() * (at.getScaleY() - 1) / 2);
int locationX = scaleX + offsetX;
int locationY = scaleY + offsetY;
AffineTransform scaled = AffineTransform.getScaleInstance(1.0 / at.getScaleX(),1.0 / at.getScaleY());
at.concatenate( scaled );
g2d.setTransform( at );
icon.paintIcon(c,g2d,locationX,locationY);
g2d.dispose();
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。