1

我需要在我的应用程序中实现字体大小切换。但是当我增加字体的大小时,RadioButtons 保持相同的大小并且在具有高分辨率的小屏幕上,我的客户无法轻松点击它。有没有办法以编程方式调整 RadioButton 的圆形物体的大小,而无需深入研究 L&F 并手动重新绘制图标(这很复杂,因为应用程序针对具有不同 UI 的多个平台,并且每个平台都必须有 7 个图标)。

完美的解决方案可能如下所示:

  1. 提取原生 UI 图标。
  2. 调整大小
  3. 将调整大小的图标设置为组件的图标。

如何实施第 1 步?可能吗?

编辑:这是我迄今为止尝试过的

public class IconImageSaver extends JFrame{

    public IconImageSaver() {

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setBounds(0,0,100,100);
        setVisible(true);

        JRadioButton rad1 = new JRadioButton();
        rad1.setBounds(10,10,40,40);
        add(rad1);

        Icon icon = UIManager.getIcon("RadioButton.icon");//(1) trying to get icon

        int w = icon.getIconWidth(),h = icon.getIconHeight();
        Image i = rad1.createImage(w, h);
        Image i2 = rad1.createImage(w,h);
        Graphics g = i.getGraphics();
        Graphics g2 = i2.getGraphics();


        g.setColor(Color.CYAN);
        g.fillRect(0, 0, w, h);
        rad1.setIcon(new ImageIcon(i));//setting icons
        g2.setColor(Color.RED);
        g2.fillRect(0, 0, w, h);
        rad1.setPressedIcon(new ImageIcon(i2));//setting icons
    }

    public static void main(String[] args) {
        new IconImageSaver();
    }

}

在位置 (1) 我试图获取图标图像,但它只返回背景颜色。无法理解为什么。为各种状态设置图标按预期工作。

4

3 回答 3

3

一些 L&F(例如NimbusAqua)支持 JComponent.sizeVariant的,如调整组件大小使用客户端属性中所述。

附录:我必须使用纯原生 L&F

a 的呈现JRadioButton由其关联的ButtonUI委托决定。本地 L&F 提供的委托内部通常无法访问,并且依赖于主机平台 API。您必须使用用户选择的 L&F 的可用功能或提供您自己的功能。如果您能解释更多有关潜在问题的信息,可能有助于提出更好的替代方案。

附录:在没有开发完整的 L&F 的情况下,可能可以使用单选按钮的父级,JToggleButton. 这样的按钮在 a 中效果很好,如此ButtonGroup所示,并且可以任意装饰,如此所述。

于 2012-10-18T17:14:10.687 回答
1

重要提示:这仅在默认的“金属”外观和感觉下进行了测试。我不保证这适用于任何其他外观和感觉。此外,我也不完全确定它是如何工作的,因为它确实有点像 hack。

我能够以不同的方式解决这个问题。

我正在使用 UIManager 默认值全局缩放我的字体,所以我希望我的单选按钮与字体一起缩放。

我发现我可以通过从 UIManager 中提取单选按钮的图标、缓冲它们、重新调整它们的大小,然后从缓冲图标的图形中派生一个新图标来做到这一点。

我最终得到了这个功能:

public static void scaleRadioButtonIcon(JRadioButton rb){
    boolean previousState = rb.isSelected();
    rb.setSelected(false);
    FontMetrics boxFontMetrics =  rb.getFontMetrics(rb.getFont());
    Icon radioIcon = UIManager.getIcon("RadioButton.icon");
    BufferedImage radioImage = new BufferedImage(
        radioIcon.getIconWidth(), radioIcon.getIconHeight(),BufferedImage.TYPE_INT_ARGB
    );
    Graphics graphics = radioImage.createGraphics();
    try{
        radioIcon.paintIcon(rb, graphics, 0, 0);
    }finally{
        graphics.dispose();
    }
    ImageIcon newRadioImage = new ImageIcon(radioImage);
    Image finalRadioImage = newRadioImage.getImage().getScaledInstance(
        boxFontMetrics.getHeight(), boxFontMetrics.getHeight(), Image.SCALE_SMOOTH
    );

    rb.setSelected(true);
    Icon selectedRadioIcon = UIManager.getIcon("RadioButton.icon");
    BufferedImage selectedRadioImage = new BufferedImage(
            selectedRadioIcon.getIconWidth(), selectedRadioIcon.getIconHeight(),BufferedImage.TYPE_INT_ARGB
    );
    Graphics selectedGraphics = selectedRadioImage.createGraphics();
    try{
        selectedRadioIcon.paintIcon(rb, selectedGraphics, 0, 0);
    }finally{
        selectedGraphics.dispose();
    }
    ImageIcon newSelectedRadioImage = new ImageIcon(selectedRadioImage);
    Image selectedFinalRadioImage = newSelectedRadioImage.getImage().getScaledInstance(
        boxFontMetrics.getHeight(), boxFontMetrics.getHeight(), Image.SCALE_SMOOTH
    );
    rb.setSelected(previousState);
    rb.setIcon(new ImageIcon(finalRadioImage));
    rb.setSelectedIcon(new ImageIcon(selectedFinalRadioImage));
}

它的作用是从单选按钮的字体度量中获取字体的大小。使用这些指标,它会根据在“外观”中找到的图标派生一个新图标,并将其调整为字体高度。

我无法解释的一件事是,当我访问相同的属性以获取两个图标时,来自 UIManager 的单选按钮的图标如何更改为“选定”图标。

我首先保存控件的状态,以便在最后恢复它。这样做是因为为了正确设置图标,当您第一次从 UIManager 请求图标时需要取消选中状态,然后在第二次请求图标时需要检查状态以获得“已选中” ' 图标。

同样,我不完全确定 UIManager 是如何工作的,或者当我们仅通过设置单个单选按钮的 'selected' 值来调用相同的属性时为什么图标会发生变化,但这是获得两个必要图标所必需的。

如果您不想使用字体来调整控件的大小,您可以轻松地将高度和宽度作为参数传递,并在设置缓冲图像大小时使用它们而不是字体的高度。

我可能会提到,同样的方法也适用于复选框

于 2014-11-18T13:09:32.483 回答
1

非常L&F sensitive,默认你可以

  • 使用正确的 L&F(只有 Nimbus 实现了 auto_whatever)但我们谈论的是自定义 L&F

  • 覆盖 UIManager 中的键,但与另一个 L&F 相比,这些键可以(呈现或带有值)或缺失

  • 创建自己的(J)组件,覆盖重要的方法和

    a) 放入 UIManger(一个默认对整个 JVM 实例有效)

    b) 在可见 GUI 中添加到 (J)Components, ei .... 的选定、期望或部分

  • 注意 ( I need to implement font size switching in my app) 非常重要的是测试是否需要更改(我们将讨论)字体或 FontUIResources,部分 (J)Components 的已实现方法的一部分完全忽略 Font 和所需的 FontUIResources,现在不确定是否是副反之亦然

于 2012-10-18T11:18:04.243 回答