Search code examples
javalinuxswingsynth

How to resolve this bug where one class if i use it cause other class interfaces to be also infected


My Case:

I have a strange BUG

enter image description here

I need to use 2 class from 1 main class which is as following:

  • 1 main class who drives both class's is YumYumYum

  • 2 other class who are only user interfaces are as below:

    a) MyJSlider the main BUG creator

    b) Volume the second class which just shows a black window with green progress bar on it

Now i have prepared SSCCE in one file, and the demo.xml is also available from here.

Problem:

If i comment out the line private MyJSlider _______BUG__BUG__BUG_______ = new MyJSlider(); it works but when i use that it cause all in trouble. How can i fix it?

import java.awt.*;
import java.net.URL;
import javax.swing.*;
import javax.swing.plaf.synth.SynthLookAndFeel;

public class YumYumYum {
  //
  // Step 1: using 2 class from here
  //
  private MyJSlider _______BUG__BUG__BUG_______ = new MyJSlider();    
  private static JFrame f = new JFrame();    
  public YumYumYum() {
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.setLayout(new FlowLayout());
    f.setPreferredSize(new Dimension(300, 200));         
    f.getContentPane().add(new JButton("Show me as Swing only - Then i am correct"));    
    f.pack();
    f.setVisible(true);    
  }
  public void test() {
    Volume a = new Volume();
    a.up(100);
  }

  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override
      public void run() {
        YumYumYum s = new YumYumYum();
        s.test();
      }
    });
  }

  //
  // Step 2: Creates the problem
  //
  public class MyJSlider extends JSlider {
    public MyJSlider() {     
      try {
        SynthLookAndFeel laf = new SynthLookAndFeel();
        //laf.load(MyJSlider.class.getResourceAsStream("/ui/demo.xml"), MyJSlider.class);      
        laf.load(new URL("file:///var/tmp/demo.xml"));
        UIManager.setLookAndFeel(laf);
      } catch (Exception e) {
        e.printStackTrace();
      }       
      setOrientation(JSlider.VERTICAL);
      //setMinimum(-24);
      setMaximum(12);
      setOpaque(false);
    }
  }

  //
  // Step 3: Does not show its actual user interface when Step 2 is involved
  //
  public class Volume extends JWindow {
    private JPanel panelFirst;
    private JProgressBar a;
    public Volume() {    
      setLayout(new BorderLayout());
      setBounds(10, 40, 350, 60);
      panelFirst = new JPanel();        
      panelFirst.setBackground(Color.BLACK);    
      panelFirst.setLayout(new FlowLayout(FlowLayout.LEFT, 8,5));        
      a = createJP(100); 
      panelFirst.add(a);
      add(panelFirst);
      setVisible(true);
      setAlwaysOnTop(true);
    }

    public JProgressBar createJP(int input) {
      JProgressBar jp = new JProgressBar(JProgressBar.VERTICAL, 0, 100);
      jp.setPreferredSize(new Dimension(15, 50));
      jp.setValue(input);
      jp.setBackground(Color.RED);
      jp.setVisible(true);
      return jp;  
    }
    public void up(int input) {
      a.setForeground(Color.GREEN);
    }
  }

}

Follow up:

  • Tested in Java 6 and Java 7 both same result in Linux

Solution

  • Alternaive work around with this problem is as below:

    enter image description here

    Place this where Synth is not preferable.

      //
      // Step 3: Makeing this work
      //
      public class Volume extends JWindow {
        private JPanel panelFirst;
        private JProgressBar a;
        public Volume() {
          try {
                      // Set cross-platform Java L&F (also called "Metal")
                  UIManager.setLookAndFeel(
                      UIManager.getCrossPlatformLookAndFeelClassName());
              } 
              catch (UnsupportedLookAndFeelException e) {
                // handle exception
              }
              catch (ClassNotFoundException e) {
                // handle exception
              }
              catch (InstantiationException e) {
                // handle exception
              }
              catch (IllegalAccessException e) {
                // handle exception
              }      
          setLayout(new BorderLayout());
          setBounds(40, 40, 350, 60);
          panelFirst = new JPanel();        
          panelFirst.setBackground(Color.BLACK);    
          panelFirst.setLayout(new FlowLayout(FlowLayout.LEFT, 8,5));        
          a = createJP(100); 
          panelFirst.add(a);
          add(panelFirst);
          setVisible(true);
          setAlwaysOnTop(true);
        }
    
        public JProgressBar createJP(int input) {
          JProgressBar jp = new JProgressBar(JProgressBar.VERTICAL, 0, 100);
          jp.setPreferredSize(new Dimension(15, 50));
          jp.setValue(input);
          jp.setBackground(Color.BLACK);
          jp.setVisible(true);
          return jp;  
        }
        public void up(int input) {
          a.setForeground(Color.GREEN);
        }
      }