当前位置: 首页 > 知识库问答 >
问题:

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

苏墨竹
2023-03-14

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

非常感谢。

干杯

共有3个答案

吴修洁
2023-03-14

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

请注意,您到图标文件的链接对我不起作用,所以我只是下载了一个不同的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);
楚和悌
2023-03-14

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

这个回答很有帮助

所以,要么转到命令行

-Dsun.java2d.uiScale=1.0, 

或者通过编程进行设置

System.setProperty("sun.java2d.uiScale", "1.0")
夏侯承恩
2023-03-14

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

  •  类似资料:
    • 我试图通过反复更改上的图标来创建一个动画(旋转文本)。问题是这些图像的大小不相同,当它们大于第一个图像的大小时,它们就会被裁剪。 解决这一问题的一种方法是为设置PreferredSize以便所有图像都适合--但我想一定有一种方法可以直接调整包含的的大小? 在下面的代码中,我还尝试将全部删除,创建一个新的jlabel,然后添加新的jlabel,但效果是一样的。 整个面板将在一个applet中使用。

    • 问题内容: 我正在尝试从目录加载图像并将其作为图标放置在中。但是,当图像尺寸很大时,就不能完全放入标签中。我尝试调整图像的大小以适合标签,但无法正常工作。我可以知道我要去哪里了吗? 问题答案: BufferedImage img = ImageIO.read(…); Image scaled = img.getScaledInstance(500, 500, Image.SCALE_SMOOTH)

    • 问题内容: 我正在尝试使图片适合JLabel。我希望将图片尺寸减小到更适合我的Swing JPanel。 我尝试使用setPreferredSize,但是它不起作用。 我想知道是否有一种简单的方法?我应该为此缩放图像吗? 问题答案: 大纲 这是要遵循的步骤。 将图片读取为BufferedImage。 将BufferedImage的大小调整为另一个JLabel大小的BufferedImage。 从调

    • 我正在尝试使图片适合JLabel。我希望将图片尺寸缩小到更适合我的Swing JPanel的尺寸。 我尝试使用setPreferredSize,但它不起作用。 我在想有没有一个简单的方法来做这件事?我应该为此缩放图像吗?

    • 就像我们可以调整的大小一样,我想在一个框架上显示一个图像。我希望它是可调整的,所以当我调整大小时,图像应该调整大小。

    • 问题内容: 我在不知道相应图像的宽度/高度的情况下将标签放入文档中: 我想使用CSS将图像缩放到其“本机”大小(基础图像的大小)的一半。我不知道该怎么做。 使用将相对于包含块而不是图像的大小。 我无法调整为特定的像素宽度,因为我不知道图像的尺寸。 由于我只需要支持WebKit,因此我尝试使用转换: 这样可以很好地调整图像,但不会调整图像元素本身的大小。 @Radagaisus建议使用Javascr