3

I have this custom JSlider, which will be used in many other forms/windows. But when i use MyJSlider it shows the following style:

enter image description here

Expected output was:

enter image description here

YumYumYum.java:

import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

public class YumYumYum {

  private JFrame f = new JFrame();

  public YumYumYum() {

    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    MyJSlider slider = new MyJSlider();
    JPanel p = new JPanel();
    p.add(slider);    

    f.getContentPane().add(p);
    f.setSize(320, 240);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }

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

MyJSlider.java:

import javax.swing.*;
import javax.swing.plaf.synth.SynthLookAndFeel;

public class MyJSlider extends JSlider {

  public MyJSlider() {    
    try {
      SynthLookAndFeel laf = new SynthLookAndFeel();
      laf.load(MyJSlider.class.getResourceAsStream("/demo.xml"), MyJSlider.class);
      UIManager.setLookAndFeel(laf);
    } catch (Exception e) {
      e.printStackTrace();
    } 
    setOrientation(JSlider.VERTICAL);
    setMinimum(-24);
    setMaximum(12);
    setVisible(true); 
  }

}

demo.xml:

<synth>
    <style id="backingStyle">
        <opaque value="TRUE"/>
        <font name="Dialog" size="12"/>
        <state>
            <color value="WHITE" type="BACKGROUND"/>
            <color value="BLACK" type="FOREGROUND"/>
        </state>
    </style>
    <bind style="backingStyle" type="region" key=".*"/>

    <style id="SliderTrackStyle">
        <opaque value="TRUE"/>
        <state>
            <color type="BACKGROUND" value="ORANGE"/>
        </state>
    </style>
    <bind style="SliderTrackStyle" type="region" key="SliderTrack" />

    <style id="SliderThumbStyle">
        <opaque value="TRUE"/>
        <state>
            <color type="BACKGROUND" value="RED"/>
        </state>
        <state value="PRESSED">
            <color type="BACKGROUND" value="GREEN"/>
        </state>

    </style>
    <bind style="SliderThumbStyle" type="region" key="SliderThumb" />
</synth>

Follow up:

final MyJSlider veryFirst= new MyJSlider(); // Hide first one: Style is not showing
final MyJSlider vSlider0 = new MyJSlider(); // Style - starts
final MyJSlider vSlider1 = new MyJSlider();
final MyJSlider vSlider2 = new MyJSlider();
final MyJSlider vSlider3 = new MyJSlider();    
final MyJSlider vSlider4 = new MyJSlider();    
final MyJSlider vSlider5 = new MyJSlider();  
final MyJSlider vSlider6 = new MyJSlider();
final MyJSlider vSlider7 = new MyJSlider();    
final MyJSlider vSlider8 = new MyJSlider(); 
final MyJSlider vSlider9 = new MyJSlider(); // Style - continue....

// JPanel
MyJSliderPanel eqPanel = new MyJSliderPanel();     
// Hide the first one always. As it does not shows the Style
eqPanel.add(veryFirst);    

vSlider0.addChangeListener(new ChangeListener() {
  @Override
  public void stateChanged(ChangeEvent ce) {
    eq();
  }
});
eqPanel.add(vSlider0);

vSlider1.addChangeListener(new ChangeListener() {
  @Override
  public void stateChanged(ChangeEvent ce) {
    eq();
  }
});
eqPanel.add(vSlider1);

vSlider2.addChangeListener(new ChangeListener() {
  @Override
  public void stateChanged(ChangeEvent ce) {
    eq();
  }
});
eqPanel.add(vSlider2);

vSlider3.addChangeListener(new ChangeListener() {
  @Override
  public void stateChanged(ChangeEvent ce) {
    eq();
  }
});
eqPanel.add(vSlider3);

vSlider4.addChangeListener(new ChangeListener() {
  @Override
  public void stateChanged(ChangeEvent ce) {
    eq();
  }
});
eqPanel.add(vSlider4);

vSlider5.addChangeListener(new ChangeListener() {
  @Override
  public void stateChanged(ChangeEvent ce) {
    eq();
  }
});
eqPanel.add(vSlider5);

vSlider6.addChangeListener(new ChangeListener() {
  @Override
  public void stateChanged(ChangeEvent ce) {
    eq();
  }
});
eqPanel.add(vSlider6);

vSlider7.addChangeListener(new ChangeListener() {
  @Override
  public void stateChanged(ChangeEvent ce) {
    eq();
  }
});
eqPanel.add(vSlider7);

vSlider8.addChangeListener(new ChangeListener() {
  @Override
  public void stateChanged(ChangeEvent ce) {
    eq();
  }
});
eqPanel.add(vSlider8);

vSlider9.addChangeListener(new ChangeListener() {
  @Override
  public void stateChanged(ChangeEvent ce) {
    eq();
  }
});
eqPanel.add(vSlider9);
eqPanel.setSize(100, 100);

1 Answers1

4

You need to set the look and feel before creating any GUI components.. E.g: You are calling:

UIManager.setLookAndFeel(laf);

....to late.


Example (using your demo.xml):

public class Test {

    public static void main(String[] args) {

        try {
            SynthLookAndFeel laf = new SynthLookAndFeel();
            laf.load(Test.class.getResourceAsStream("demo.xml"), Test.class);
            UIManager.setLookAndFeel(laf);
        } catch (Exception e) {
            e.printStackTrace();
        }

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.add(new JSlider() {{
            setOrientation(JSlider.VERTICAL);
            setMinimum(-24);
            setMaximum(12);
            setVisible(true);
        }});
        f.setSize(320, 240);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

Outputs the correct screenshot.

dacwe
  • 43,066
  • 12
  • 116
  • 140
  • If i call that in my YumYumYum.java then it applies to all UI like i have other style JButton, JTextArea, JLabel ect..., Where i do not wanted to apply same UI style of that JSlider. –  Jun 13 '12 at 07:35
  • `p.add(new JButton("hello it also applies on this"));` - when i add this on this, then it also apply that JSlider style in my JButton, which i wanted to avoid. –  Jun 13 '12 at 07:37
  • 1
    You cannot apply it for only a part of the GUI. You need to specify a layout that works for all components (or at least the ones you use). – dacwe Jun 13 '12 at 07:43
  • Thank. I just did it. (But i have to apply a tricks. Like the first JSlider can be added and has to be setVisible(false) because the first one does not apply Style, but very first to second, It applies well.) –  Jun 13 '12 at 08:10
  • No no no, you don't need any tricks. Call only `setLookAndFeel` once and do it before *any* GUI calls (just like my example). – dacwe Jun 13 '12 at 20:02