问题描述
我有png图标,并将它们用作JButton
/ JLabel
中的图标。
问题在于,在运行时显示的图像大于原始图标,并且由于这种调整大小,因此非常难看。
这里是一个例子:
原始图标(左)及其在JButton
(右)中的呈现方式
此最小示例的源代码很简单:
public class Main {
public static void main(String... args) {
JFrame frame = new JFrame("Test");
frame.setBounds(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);
g2d.setTransform( new AffineTransform() );
icon.paintIcon(c,g2d,scaleX + offsetX,scaleY + offsetY);
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。
查看带有字符串参数的类return
的{{3}}的源代码。它使用类ImageIcon
从文件创建图像。这使我认为它必须进行一些缩放。因此,我想到了以其他方式创建图标。 java.awt.Toolkit
有另一个constructor,它带有一个ImageIcon
参数。因此,我从文件创建了一个Image
,然后使用该图像创建了一个BufferedImage
。 ImageIcon
未缩放。
请注意,您对图标文件的链接对我不起作用,因此我下载了另一个16x16图标。
BufferedImage
,
谢谢大家。 问题是默认缩放因子(为1.25)。 由于我想独立于DPI来完全控制大小,因此我通过将比例因子强制为1.0解决了我的问题。
因此,要么传递至命令行-Dsun.java2d.uiScale = 1.0,要么通过编程方式将其设置为System.setProperty(“ sun.java2d.uiScale”,“ 1.0”)