【问题标题】:Java Swing: Button only displays Icon upon Mouse-OverJava Swing:按钮仅在鼠标悬停时显示图标
【发布时间】:2021-04-09 15:26:40
【问题描述】:

我有 Swing 应用程序,我想在 JButton 上显示一个图标。 Windows 缩放图标并使其非常难看时遇到了一些问题。我能够通过使用 here 描述的 Icon-Wrapper 类来解决这个问题。

使用包装类解决了我遇到的缩放问题,但导致了一个新问题:该图标仅在我将鼠标悬停在按钮上时才会显示,如下所示:

这是一个最小的例子:

import javax.swing.*;
import java.awt.*;
import java.net.MalformedURLException;
import java.net.URL;

public class Ui {
    private static JFrame frame;
    private static JButton button1;
    private static JButton button2;
    private static JMenuBar jMenuBar;


    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            try {
                createGui();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
        });
    }

    private static void createGui() throws MalformedURLException {
        frame = new JFrame("Test");

        button1 = new JButton();
        button2 = new JButton();
        jMenuBar = new JMenuBar();


        Icon icon = new NoScalingIcon(new ImageIcon(new URL("https://i.stack.imgur.com/wgKeq.png")));
        button1.setIcon(icon);
        button2.setIcon(icon);

        jMenuBar.add(button1);
        jMenuBar.add(button2);
        frame.setJMenuBar(jMenuBar);
        frame.pack();
        frame.setVisible(true);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    }
}

图标包装类:

import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;

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

        g2d.setTransform(new AffineTransform());

        icon.paintIcon(c, g2d, scaleX + offsetX, scaleY + offsetY);

        g2d.dispose();
    }
}

这个问题的原因可能是什么?

【问题讨论】:

  • 您可能只需要在修复图标后调用 repaint() 即可。
  • @ControlAltDel 好的,我尝试调用框架上的 repaint() 和主文件最后一行下方的按钮(所以在 frame.setExtendedState(JFrame.MAXIMIZED_BOTH); 下),但这并没有改变任何事物。我认为这就是您所说的“调用 repaint()”

标签: java swing icons


【解决方案1】:

我想我找到了解决办法。

下面的代码不是创建一个全新的AffineTransform,而是将一个新的缩放变换与现有比例的倒数合并,因此比例因子设置回1:

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

【讨论】:

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