java swing 图标大小,Java swing JButton/JLabel:图标未以其原始大小显示

在Java Swing中,使用PNG图标时遇到了图标在JButton或JLabel上显示过大且失真的问题。原因是Windows的缩放设置导致组件整体被放大。为解决此问题,可以创建一个`NoScalingIcon`类,它包裹原始图标并禁用缩放,通过调整图标的位置使其居中。这样,图标将保持原始大小,避免了显示丑陋的问题。
摘要由CSDN通过智能技术生成

I have png icons and use them as icons in JButton / JLabel.

The problem is that the image displayed at runtime is larger than the original icon, and because of this resizing, it's super ugly.

Here is an example:

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

4bYMe.png

The source code for this minimal example is simply:

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);

}

}

Is this expected? If not, how can I avoid this? I tried many things around forcing the size of the image, the button, etc. but could not get a proper image displayed.

I have tested with icons of various sizes: 16x16, 17x17, 18x18, 19x19, 20x20, and each time the icon displayed on the JButton is a bit larger than the original which makes it look ugly:

MSuEa.png

Thank you!

Cheers.

解决方案

This is because you are using Windows scaling. The entire component is scaled, both the icon and the text.

You could turn the scaling of the Icon off by using a wrapper Icon:

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);

}

}

The scaling adjustment will position the Icon at the top/left of the button area.

The offset adjustment will then attempt to center the Icon in the scaled icon painting area.

Using the default transform will have a scaling factor of 0 for the Icon.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值