我有 png 图标并将它们用作 JButton
/JLabel
中的图标。
问题是在运行时显示的图像比原始图标大,并且由于这种调整大小,它非常难看。
举个例子:
原始图标(左)及其在 JButton
中的呈现方式(右)
这个最小示例的源代码很简单:
public class Main {
public static void main(String... args) {
JFrame frame = new JFrame("Test");
frame.setBounds(0, 0, 120, 80);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new FlowLayout());
ImageIcon icon = new ImageIcon("icon.png");
frame.getContentPane().add(new JButton("Test", icon));
frame.setVisible(true);
}
}
这是预期的吗?如果没有,我怎样才能避免这种情况?我尝试了很多关于强制图像大小、按钮等的方法,但无法显示正确的图像。
我测试过各种尺寸的图标:16x16、17x17、18x18、19x19、20x20,每次 JButton
上显示的图标都比原来的大一点,看起来很难看:
谢谢!
干杯。
最佳答案
这是因为您使用的是 Windows 缩放。缩放整个组件,包括图标和文本。
您可以使用包装图标关闭图标的缩放:
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();
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI()
{
JButton button = new JButton( "Button" );
NoScalingIcon icon = new NoScalingIcon( new ImageIcon("box.jpg") );
button.setIcon( icon );
JPanel panel = new JPanel( );
panel.add( button );
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(panel);
f.setSize(200, 200);
f.setLocationRelativeTo( null );
f.setVisible(true);
}
}
缩放调整会将图标定位在按钮区域的顶部/左侧。
然后偏移调整将尝试使图标在缩放的图标绘制区域居中。
使用默认转换将使图标的缩放因子为 0。
关于Java Swing JButton/JLabel : icons are not displayed in their original size,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64586078/