我需要在我的应用中实现字体大小切换。但是当我增加字体的大小时,RadioButtons保持相同的尺寸,并且在高分辨率的小屏幕上,我的客户根本无法轻易击中它。有没有办法以编程方式调整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)我试图获取图标图像,但它只返回背景颜色。 无法理解为什么。 设置各种状态的图标按预期工作。
答案 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