【问题标题】:Java swing JButton/JLabel: icons are not displayed in their original sizeJava swing JButton/JLabel:图标未按原始大小显示
【发布时间】:2021-02-11 14:23:26
【问题描述】:

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

谢谢!

干杯。

【问题讨论】:

  • 您是否可以发布指向icon.png 的链接,以便我可以尝试重现您声称看到的内容?
  • 你试过像shown in this answer一样自己缩放图像吗?
  • 谢谢阿布拉。绝对任何图标都会发生同样的情况。使用以下 URL 中的图标尝试了相同的代码: ImageIcon icon = new ImageIcon(new URL("cdn4.iconfinder.com/data/icons/6x16-free-application-icons/16/…)); 发生了同样的问题:图标稍大且丑陋。
  • 谢谢 Maloomeister:是的,我试过了。该图标是 16x16,我实际上希望它以 16x16 的原始大小显示。我尝试将大小调整为 16x16(尽管它不应该是必需的),但图标仍然显示得稍大。

标签: java swing jbutton jlabel imageicon


【解决方案1】:

这是因为您使用的是 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);
    }
}
  1. 缩放调整会将图标定位在按钮区域的顶部/左侧。

  2. 然后,偏移调整将尝试使图标在缩放后的图标绘制区域居中。

  3. 使用默认变换时,图标的缩放系数将为 0。

【讨论】:

    【解决方案2】:

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

    This answer was helpful

    所以,要么传递到命令行

    -Dsun.java2d.uiScale=1.0, 
    

    或以编程方式设置

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

    【讨论】:

      【解决方案3】:

      查看类ImageIconconstructor 的源代码,它采用字符串参数。它使用类java.awt.Toolkit 从文件中创建图像。这让我觉得它必须做一些缩放。所以我想以不同的方式创建图标。 ImageIcon 有另一个 constructor 接受 Image 参数。所以我从文件中创建了一个BufferedImage,然后使用该图像创建了一个ImageIconBufferedImage 未缩放。

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

      java.awt.image.BufferedImage img = javax.imageio.ImageIO.read(new java.io.File("cellphon.png"));
      javax.swing.Icon ico = new javax.swing.ImageIcon(img);
      javax.swing.JButton button = new javax.swing.JButton("Test", ico);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-04
        • 1970-01-01
        • 1970-01-01
        • 2013-01-16
        • 2017-06-06
        相关资源
        最近更新 更多