views:

159

answers:

1

I am working on a custom JSlider that has a custom Track Rectangle. I want the ability to set the color of the track rectangle when first declaring the slider.

Here's a snippet of what I have (The classes are in separate files in the same package):

public class NewSlider extends JSlider {

   Color kolor;

public NewSlider (Color k) {

   kolor = k;
   }

public void updateUI() {
    setUI(new NewSliderUI(this, kolor);

    updateLabelUIs();
    }
}

public class NewSliderUI extends BasicSliderUI {

Color sliderColor = Color.BLACK;

public NewSliderUI (JSlider b, Color k) {
   super(b);

   sliderColor = k;
   }

} 

In the above code, "kolor" is initially null and leads to and error when NewSliderUI tries to use it. It appears that the updateUI() method is called before anything else. Then the NewSlider constructor is called. I have tried a variety of things, but because updateUI() appears to run before anything else, nothing I add to the NewSlider class seems to matter.

If I hardcode a Color (ie. setUI(new NewSliderUI(this, Color.BLACK);), then it works, but having a different class for each color seems silly.

Thanks.

+1  A: 

I don't see how kolor could be null unless one of the following are happening:

  1. You're passing a null value to the constructor
  2. You're not instantiating NewSlider in the Swing EDT and are having some strange cache issues
  3. NewSlider is being constructed via reflection/deserialization and kolor is not being set.

Have you tried running this in the debugger with some breakpoints? I'd be curious to ensure that the NewSlider constructor is being called (and before the NewSliderUI constructor).

Edit: I see what you mean below. I forgot that the no args constructor for JSlider was being called implicitly. What about doing the following:

public class NewSlider extends JSlider {

   Color kolor = Color.BLACK;

   public NewSlider (Color k) {    
      kolor = k;
      updateUI();
   }

   public void updateUI() {
      setUI(new NewSliderUI(this, kolor);
      updateLabelUIs();
   }
}

You end up calling updateUI() twice, but the end result should be what you want.

Jason Nichols
I'm pretty sure it's not possibility 1 or 2. I have no idea about possibility 3. I have tried debugging. The NewSlider constructor automatically calls the JSlider constructor (ie super();) before it does anything else. The it jumps back to the NewSlider constructor and properly assigns "kolor". However, until than point, kolor is null.
SharpBarb
Hmm...That may work, I'll try it out when I get a chance. I looked at the JSlider source, and I think I understand what is going on. The NewSlider calls the JSlider constructor before anything else and then the JSlider constructor calls updateUI().
SharpBarb
Yeah, that appears to be what's happening. Let me know how it ends up!
Jason Nichols