Java Swing:调整单选按钮的大小

Java Swing:调整单选按钮的大小,java,swing,resize,jradiobutton,uimanager,Java,Swing,Resize,Jradiobutton,Uimanager,我需要在我的应用程序中实现字体大小切换。但当我增大字体大小时,单选按钮的大小保持不变,并且在高分辨率的小屏幕上,我的客户无法轻松点击。有没有一种方法可以通过编程来调整RadioButton的圆形对象的大小,而无需深入L&F并手动重新绘制图标?这很复杂,因为应用程序针对具有不同UI的多个平台,每个平台必须有7个图标 完美的解决方案可能如下所示: 提取本机用户界面图标。 调整它的大小 将已调整大小的图标设置为组件的图标。 如何实施步骤1?可能吗 编辑:这是我到目前为止尝试过的 public clas

我需要在我的应用程序中实现字体大小切换。但当我增大字体大小时,单选按钮的大小保持不变,并且在高分辨率的小屏幕上,我的客户无法轻松点击。有没有一种方法可以通过编程来调整RadioButton的圆形对象的大小,而无需深入L&F并手动重新绘制图标?这很复杂,因为应用程序针对具有不同UI的多个平台,每个平台必须有7个图标

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

提取本机用户界面图标。 调整它的大小 将已调整大小的图标设置为组件的图标。 如何实施步骤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,我试图得到图标图像,但它只返回背景色。 我不明白为什么。 设置各种状态的图标可按预期工作。

对L&F非常敏感,默认情况下,您可以

使用合适的L&F只有Nimbus实现了auto_,但我们谈论的是定制L&F

覆盖UIManager中的键,但与其他L&F相比,这些键可以显示或具有值或缺失

创建自己的JComponent,以覆盖重要的方法和

a将一个def提交给UIManger。适用于整个JVM安装

b添加到所选、所需或部分JComponents中,例如。。。。在可见的GUI中

请注意,我需要在我的应用程序中实现字体大小切换。测试是否需要更改非常重要。我们将讨论字体或字体资源,部分JComponents实现方法的一部分是完全忽略字体和所需字体资源,现在不确定是否也需要更改字体或字体资源

对L&F非常敏感,默认情况下您可以

使用合适的L&F只有Nimbus实现了auto_,但我们谈论的是定制L&F

覆盖UIManager中的键,但与其他L&F相比,这些键可以显示或具有值或缺失

创建自己的JComponent,以覆盖重要的方法和

a将一个def提交给UIManger。适用于整个JVM安装

b添加到所选、所需或部分JComponents中,例如。。。。在可见的GUI中

请注意,我需要在我的应用程序中实现字体大小切换。测试是否需要更改非常重要。我们将讨论字体或字体资源,部分JComponents实现方法的一部分是完全忽略字体和所需字体资源,现在不确定是否也需要更改字体或字体资源

一些L&F(如Nimbus、Aqua)支持大型JComponent.sizeVariant,如和中所述

附录:我必须使用纯天然L&F

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

附录:在没有制定完整的L&F的情况下,可以与单选按钮的母公司JToggleButton合作。如图所示,此类按钮在按钮组中工作良好,并且可以任意装饰,如图所示。

一些L&F,例如Nimbus、Aqua支持大型JComponent.sizeVariant,如和中所述

附录:我必须使用纯天然L&F

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

附录:在没有制定完整的L&F的情况下,可以与单选按钮的母公司JToggleButton合作。如图所示,此类按钮在按钮组中工作良好,并且可以任意装饰,如图所示。

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

我能以稍微不同的方式解决这个问题

我正在使用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));
}
它所做的是从单选按钮的字体度量中获取字体大小。使用这些指标,它根据“外观”中的图标派生出一个新图标,并根据字体高度调整图标大小

我无法解释的一件事是,当我访问同一个属性t时,从UIManager出来的radiobutton图标如何更改为“选定”图标 o获得两个图标

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

同样,我也不完全清楚UIManager是如何工作的,或者当我们仅仅通过设置一个单选按钮的“selected”值来调用同一属性时,为什么图标会改变,但这是获得两个必要图标所必需的

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

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

我能以稍微不同的方式解决这个问题

我正在使用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出来的radiobutton图标如何更改为“选定”图标

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

同样,我也不完全清楚UIManager是如何工作的,或者当我们仅仅通过设置一个单选按钮的“selected”值来调用同一属性时,为什么图标会改变,但这是获得两个必要图标所必需的

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



你必须从哪里从本地资源中提取图标。如果我理解正确,RadioButton的图像属于操作系统资源。在此处使用自定义绘制实现您自己的RadioButton。重写paintComponent方法以按照您的需要绘制图标。这是解决方案,但我从何处获取本机图标?从AWT而不是Swing。AWT绘制本机小部件。您必须从何处从本机资源中提取图标。如果我理解正确,RadioButton的图像属于操作系统资源。在此处使用自定义绘制实现您自己的RadioButton。重写paintComponent方法以按照您的需要绘制图标。这是解决方案,但我从何处获取本机图标?从AWT而不是Swing。AWT绘制本机小部件。我的客户不会喜欢使用非本机L&F。这就是为什么我不能更改L&F,使应用程序在不同的操作系统中具有相同的外观。所以我们谈论的是完全本地的L&F,带有一些控件的修改图标。我的客户不会喜欢使用非本地的L&F。这就是为什么我不能更改L&F,使应用程序在不同的操作系统中具有相同的外观。所以我们谈论的是一些控件的带有修改图标的完全本地L&F。这是真的,但正如我在对mKorbel回答的评论中所说的,我必须使用纯本地L&F,即Sun的实现。引用提供的链接:Nimbus是目前唯一支持尺寸变体的Sun外观和感觉。Windows L&F不支持这一点。同意,恕我直言,没有办法将图标添加到UIManager中是使用了paintIcon,但用paintIcon覆盖JCheckBox或将自己的UI委托给UIManager从未尝试过,不知道是否可能,但对于Nimbus可能有用这并没有解决我的问题,但问题提出后已经有一段时间了,所以我认为没有解决办法。我接受了一个最高票数的答案。我在上面概述了一个不那么繁重的方法;很抱歉,我错过了您问题的更新。这是真的,但正如我在对mKorbel回答的评论中所说,我必须使用纯本地L&F,即Sun的实现。引用提供的链接:Nimbus是目前唯一支持尺寸变体的Sun外观和感觉。Windows L&F不支持这一点。同意并确认,没有办法将图标添加到UIManager,而是使用paintIcon覆盖JCheckBox,或者将自己的UI委托给UIManager n
曾经尝试过,不知道是否可能,但对于Nimbus可能有用这并没有解决我的问题,但问题提出已经有一段时间了,所以我认为没有解决办法。我接受了一个最高票数的答案。我在上面概述了一个不那么繁重的方法;很抱歉,我错过了您问题的更新。我尝试了此代码,它为我所做的只是将单选按钮圆圈更改为浅红色正方形,并减小显示的字体大小……很抱歉,它不适用于您。最初我没有提到我使用的是默认的swing L&F,我从未用任何其他L&F测试过它。几乎这段代码都在生产应用程序中,并且与金属外观一起工作。我在MacOSX上试用过,可能是因为。。。我没有选择其他明确的L&F,但我尝试了此代码,它为我所做的只是将单选按钮圆圈更改为浅红色正方形,并减小显示的字体大小……很抱歉,它对您不起作用。最初我没有提到我使用的是默认的swing L&F,我从未用任何其他L&F测试过它。几乎这段代码都在生产应用程序中,并且与金属外观一起工作。我在MacOSX上试用过,可能是因为。。。但我没有选择其他明确的L&F