2015-11-26 2 views
2

В настоящее время я работаю над проектом, который требует изменения состояния JRadioButton при обновлении просматриваемой записи.Выбор JRadioButton не отображается в графическом интерфейсе до тех пор, пока не появится в Windows L & F

У нас было несколько клиентов, которые жалуются нам, что когда запись изменится, если JRadioButton выключен, он не будет обновлен до тех пор, пока не будет показан экран. Такое поведение, похоже, связано с использованием Windows Look & Feel, поскольку, похоже, это не происходит, когда он не установлен.

Приведенный ниже пример кода демонстрирует это. Выбранный по умолчанию JRadioButton является «Cat», поэтому, выбрав «Dog» JButton, а затем изменив вкладку на «Question», вы увидите переход JRadioButton.

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 
     } 
    } 
} 

Есть ли способ предотвратить это поведение или даже ускорить его, чтобы сделать его менее заметным для наших пользователей?

+0

Наблюдение: отображается только выбранный компонент (все остальные компоненты вкладки «скрыты» ('setVisible (false)'). Это означает, что они не будут реагировать на запросы краски, красивы и эффективны. , что, когда они становятся видимыми, они должны перекрашивать там состояние, в этом случае переход от выбранного к невыбранному и наоборот - это, кажется, проблема, решение может быть немного сложным – MadProgrammer

+0

Я предположил, что это может так как стандартный Look and Feel не проявляет такого же поведения ... возможно, потому что «ощущение» Windows имеет эффект перехода, противоположный стандарту. – Kuronai

+0

Windows L & F является единственным (что я могу find), который имеет анимацию «отменить выбор», на самом деле это побочный эффект этой проблемы. Поэтому, когда компонент становится видимым, радиокноты визуализируются от предыдущих состояний там новые состояния, но из-за анимации в Windows L & F, это действительно очевидно из изменения состояния. – MadProgrammer

ответ

0

Вы можете быть в состоянии отключить анимацию, задав свойство swing.disablevistaanimation системы Java:

java -Dswing.disablevistaanimation="true" your-cool-application.jar 

В com.sun.java.swing.plaf.windows.AnimationController классе, есть VISTA_ANIMATION_DISABLED поле, которое инициализируется swing.disablevistaanimation собственности. Это поле определяет, вызывает ли метод paintSkin метод skin.paintSkinRaw, если анимация отключена или же начинает входить в анимацию.

Он работает на моем ноутбуке Windows 8.1 с Java 8 (jdk1.8.0_65), поэтому его эффект, похоже, не ограничивается только Windows Vista.

+0

Я принял это как ответ, так как это привело к тому, что мы заставили затронутых клиентов сделать это, поскольку казалось, что усилия, необходимые для подавления анимаций, будут слишком велики, чтобы оправдать (спасибо MadProgrammer за его помощь в этом). – Kuronai