Java swing JButton/JLabel:图标不会以其原始大小显示

Java swing JButton/JLabel:图标不会以其原始大小显示,java,swing,jbutton,jlabel,imageicon,Java,Swing,Jbutton,Jlabel,Imageicon,我有png图标,并将它们用作JButton/JLabel 问题是,运行时显示的图像比原始图标大,并且由于这种调整大小,它非常难看 下面是一个例子: 原始图标(左)及其在JButton(右)中的呈现方式 此最小示例的源代码如下: public class Main { public static void main(String... args) { JFrame frame = new JFrame("Test"); frame.

我有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
上显示的图标都比原来的大一点,这使它看起来很难看:

谢谢大家!


干杯。

查看带有字符串参数的类的源代码。它使用class
java.awt.Toolkit
从文件创建图像。这让我觉得它一定在做一些缩放。所以我想用不同的方式创建图标
ImageIcon
有另一个采用
Image
参数的图标。因此,我从文件中创建了一个
buffereImage
,然后使用该图像创建了一个
ImageIcon
buffereImage
未缩放

请注意,您指向图标文件的链接不适用于我,因此我只下载了一个不同的16x16图标

java.awt.image.BufferedImage img=javax.imageio.imageio.read(新的java.io.File(“cellphon.png”);
javax.swing.Icon-ico=newjavax.swing.ImageIcon(img);
javax.swing.JButton按钮=新的javax.swing.JButton(“测试”,ico);

这是因为您正在使用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

  • 谢谢大家。 问题在于默认的比例因子(1.25)。 由于我想完全独立于DPI控制大小,我通过强制比例因子为1.0解决了我的问题

    因此,要么传递到命令行

    -Dsun.java2d.uiScale=1.0, 
    
    或者以编程方式设置它

    System.setProperty("sun.java2d.uiScale", "1.0")
    

    你有没有可能发一个链接到
    icon.png
    ,这样我就可以复制你声称看到的东西?你有没有试过自己缩放图像?谢谢Abra。任何图标都会发生同样的情况。使用以下URL中的图标尝试了相同的代码:ImageIcon icon=new ImageIcon(new URL(“);出现了相同的问题:图标稍大且外观丑陋。感谢Maloomeister:是的,我尝试了。图标是16x16,我实际上希望它以16x16的原始大小显示。我尝试将其大小调整为16x16(尽管不需要),图标仍然显示得稍大一些。