javaswing jbutton/jlabel:图标不会以其原始大小显示

ktecyv1j  于 2021-06-29  发布在  Java
关注(0)|答案(3)|浏览(292)

我有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 比原作大一点,看起来很难看:

谢谢您!
干杯。

xyhw6mcr

xyhw6mcr1#

这是因为您正在使用windows缩放。将缩放整个组件,包括图标和文本。
您可以使用 Package 图标关闭图标的缩放:

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。

pgccezyw

pgccezyw2#

请看类的构造函数的源代码 ImageIcon 它接受一个字符串参数。它使用类 java.awt.Toolkit 从文件创建图像。这让我觉得它一定在做一些缩放。所以我想用不同的方式来创建图标。 ImageIcon 有另一个构造函数 Image 参数。所以我创造了一个 BufferedImage 然后使用该图像创建 ImageIcon . 这个 BufferedImage 未缩放。
请注意,你的图标文件链接不适用于我,所以我只是下载了一个不同的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);
brqmpdu1

brqmpdu13#

谢谢大家。问题是默认的比例因子(1.25)。因为我想完全独立于dpi控制大小,所以我通过强制缩放因子为1.0来解决问题。
这个答案很有帮助
因此,要么传递到命令行-dsun.java2d.uiscale=1.0,要么通过编程方式将其设置为system.setproperty(“sun.java2d.uiscale”,“1.0”)

相关问题