Java JRadioButton选择不';在Windows LaF中可见之前,不会在GUI上显示
我目前正在处理一个项目,该项目要求当查看的记录被更新时,JRadioButton的状态发生更改 我们已经有一些客户向我们抱怨,当记录发生变化时,如果JRadioButton在屏幕外,它将在屏幕显示之前不会被更新。这种行为似乎是使用Windows外观的结果,因为它在未设置时似乎不会发生 下面的代码示例演示了这一点。 默认选择的JRadioButton是“Cat”,因此通过选择“Dog”JButton,然后将tab更改为“Question”,您可以看到JRadioButton发生了转换Java JRadioButton选择不';在Windows LaF中可见之前,不会在GUI上显示,java,swing,look-and-feel,jradiobutton,Java,Swing,Look And Feel,Jradiobutton,我目前正在处理一个项目,该项目要求当查看的记录被更新时,JRadioButton的状态发生更改 我们已经有一些客户向我们抱怨,当记录发生变化时,如果JRadioButton在屏幕外,它将在屏幕显示之前不会被更新。这种行为似乎是使用Windows外观的结果,因为它在未设置时似乎不会发生 下面的代码示例演示了这一点。 默认选择的JRadioButton是“Cat”,因此通过选择“Dog”JButton,然后将tab更改为“Question”,您可以看到JRadioButton发生了转换 import
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
/**
* Example of JRadioButton not updating until it's parent panel becomes visible.
*/
public class RadioButtonExample extends JPanel implements ActionListener {
public static final String CAT = "Cat";
public static final String DOG = "Dog";
private final JRadioButton radCat;
private final JRadioButton radDog;
private final ButtonGroup grpAnimal;
public RadioButtonExample() {
super(new BorderLayout());
JLabel lblQuestion = new JLabel("Are you a cat or dog person?");
radCat = new JRadioButton(CAT);
radCat.setActionCommand(CAT);
radCat.setSelected(true);
radDog = new JRadioButton(DOG);
radDog.setActionCommand(DOG);
grpAnimal = new ButtonGroup();
grpAnimal.add(radCat);
grpAnimal.add(radDog);
JPanel pnlQuestion = new JPanel(new GridLayout(0, 1));
pnlQuestion.add(lblQuestion);
pnlQuestion.add(radCat);
pnlQuestion.add(radDog);
JButton btnSetCat = new JButton(CAT);
btnSetCat.setActionCommand(CAT);
btnSetCat.addActionListener(this);
JButton btnSetDog = new JButton(DOG);
btnSetDog.setActionCommand(DOG);
btnSetDog.addActionListener(this);
JPanel pnlButtons = new JPanel(new GridLayout(0, 1));
pnlButtons.add(new JLabel("Update your choice of animal"));
pnlButtons.add(btnSetCat);
pnlButtons.add(btnSetDog);
JTabbedPane tabPane = new JTabbedPane();
tabPane.addTab("Buttons", pnlButtons);
tabPane.addTab("Question", pnlQuestion);
add(tabPane, BorderLayout.LINE_START);
setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
}
public void actionPerformed(ActionEvent evt) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
grpAnimal.clearSelection();
if (CAT.equals(evt.getActionCommand())) {
grpAnimal.setSelected(radCat.getModel(), true);
}
else if (DOG.equals(evt.getActionCommand())) {
grpAnimal.setSelected(radDog.getModel(), true);
}
}
});
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("RadioButtonExample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
JComponent newContentPane = new RadioButtonExample();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
// Comment out the line below to run using standard L&F
setLookAndFeel();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void setLookAndFeel() {
try {
// Set Windows L&F
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
}
catch (Exception e) {
// handle exception
}
}
}
有没有办法防止这种行为,甚至加快它的速度,让它对我们的用户不那么明显?您可以通过指定
swing.disablevistaanimation
Java系统属性来禁用动画:
java -Dswing.disablevistaanimation="true" your-cool-application.jar
在com.sun.java.swing.plaf.windows.AnimationController
类中,有一个VISTA\u ANIMATION\u DISABLED
字段,该字段初始化为swing.disablevistaanimation
属性。如果动画被禁用或开始进入动画,此字段确定paintSkin
方法是否调用skin.paintSkinRaw
方法
它可以在使用Java 8(jdk1.8.0_65)的Windows 8.1笔记本电脑上工作,因此它的效果似乎并不局限于Windows Vista。观察:只有选定的组件可见(所有其他选项卡组件都是“隐藏的”(
setVisible(false)
)。这意味着他们不会响应绘画请求,这很好也很有效。但这确实意味着,当他们被显示时,他们必须重新绘制那里的状态,在这种情况下,从已选择到未选择,反之亦然-这似乎是问题所在,解决方案可能有点复杂。我假设这可能是案例,但不确定,因为标准的外观和感觉没有表现出相同的行为…可能是因为Windows“感觉”具有与标准相反的过渡效果。Windows L&F是唯一(我能找到)具有“取消选择”的动画,这实际上是这个问题的一个副作用。因此,当组件变得可见时,单选按钮将从以前的状态渲染到新的状态,但由于Windows L&F中的动画,状态变化非常明显。我正在尝试挖掘Windows L&F代码,以查看是否存在某种标志,但围绕动画的所有功能都是私有的:我一直在做同样的事情,但运气不太好。但在发生更改时抑制动画可能足以满足客户的要求。我接受这一点作为答案,因为这是我们最终让受影响的客户做的事情,因为这看起来好像“我不需要抑制动画”,这将是太大的理由(感谢MadProgrammer在这方面的帮助)。