Java Swing JButton/JLabel : icons are not displayed in their original size

标签 java swing jbutton jlabel imageicon

我有 png 图标并将它们用作 JButton/JLabel 中的图标。
问题是在运行时显示的图像比原始图标大,并且由于这种调整大小,它非常难看。

举个例子:
原始图标(左)及其在 JButton 中的呈现方式(右)

original icon (left) and how it's rendered in the JButton (right)

这个最小示例的源代码很简单:

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

original icons sizes vs icons on 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);
    }
}
  1. 缩放调整会将图标定位在按钮区域的顶部/左侧。

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

  3. 使用默认转换将使图标的缩放因子为 0。

关于Java Swing JButton/JLabel : icons are not displayed in their original size,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64586078/

相关文章:

java - 为什么 fileChannel.read 循环永远不会结束?

java - 在 JSP 页面中动态读取应用程序映射的内容。 - 支柱2.0

java - Enter 键可充当可编辑 JComboBox 上的 Tab

java - 如何将另一个类的组合框的选定索引设置为 0

Java:这种方法线程安全吗?

java - 尝试在 spring 中保留消息属性文件列表时出错

java - 如何读取File并将内容写入JTextArea?

java - 克隆整个 JTree/TreeModel 的最简单方法?

java - 删除 JButton 上的异步更新

java - 我需要更改 JButton 显示的图像