Swing:调整RadioButton的大小

时间:2012-10-18 11:07:21

标签: java swing resize jradiobutton uimanager

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

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

  1. 提取原生UI图标。
  2. 调整大小
  3. 将已调整大小的图标设置为组件的图标。
  4. 如何实施第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)我试图获取图标图像,但它只返回背景颜色。 无法理解为什么。 设置各种状态的图标按预期工作。

3 个答案:

答案 0 :(得分:3)

某些L& Fs(例如 Nimbus Aqua )支持 JComponent.sizeVariant,如{{3}中所述}和Resizing a Component

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

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

附录:如果没有开发完整的L& F,可以使用单选按钮的父级JToggleButton。这些按钮在ButtonGroup中效果很好,如Using Client Properties所示,它们可以任意修饰,如here所述。

答案 1 :(得分:1)

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

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

  • 覆盖UIManager中的键,但与其他L& F

  • 相比,这些键可以(可以呈现或有价值)或缺失
  • 创建自己的(J)组件,以覆盖重要的方法和

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

    b)添加到(J)组分的选定的,期望的或部分的,e.i。 ....在可见的GUI中

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

答案 2 :(得分:1)

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

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

我使用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));
}

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

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

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

同样,我不完全确定UIManager是如何工作的,或者当我们通过设置单个单选按钮的“选定”值来调用同一属性时图标会发生变化的原因,但这是为了获得两者而需要的必要的图标。

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

I might mention that this same methodology works with checkboxes