Probably a stupid question, but I need the 'colour' variable for an external class, and it can only return something when it's declared in the constructor. However, the colour returned would then never change. Is there a way to return values from the change listener, or anything else that I can do to get the colour every time it changes?

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JLabel;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JSeparator;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class HSBSlider extends JFrame {
  
  // Declare GUI variables
  private JSlider hSlider; // Slider for controlling RGB values
  private JSlider sSlider; // Slider for controlling saturation
  private JSlider bSlider; // Slider for controlling brightness/darkness
  private JPanel colourOutput; // JPanel for showing colour output
  
  // Declare colour variables
  private float hue;
  private float saturation;
  private float brightness;
  private Color colour;
  
  // Panels
  JPanel panel;
  JSlider change;
  
  // Constructor
  public HSBSlider() {
    
    // Window properties
    super( "HSB Slider" ); // Title
    setLayout( new GridLayout(4,1) ); // Layout 4x1 table
    
    // Initialize labels and sliders into GridLayout
    newPanel( "Hue" );
    newPanel( "Saturation" );
    newPanel( "Brightness" );
    
    // Initialize JPanel (for colour output) into GridLayout
    colourOutput = new JPanel();
    add( colourOutput );
    
    colour = new Color( hue, saturation, brightness );
    
    // Register handlers for event handling
    SliderHandler handler = new SliderHandler();
    hSlider.addChangeListener( handler );
    sSlider.addChangeListener( handler );
    bSlider.addChangeListener( handler );
    
  }
  
  private JPanel newPanel( String text ) {
    
    // Create new JPanel
    panel = new JPanel();
    panel.setLayout( new BorderLayout() );
    
    // Initialize label into BorderLayout's north region
    panel.add( new JLabel(text), BorderLayout.NORTH );
    // Initialize slider into BorderLayout's center region
    // Slider set depends on the label text
    if( text.equals("Hue") ) {
      hSlider = newSlider( 0, 360, 180, 60, 5, "Hue adjustment" );
    } else if( text.equals("Saturation") ) {
      sSlider = newSlider( 0, 100, 50, 25, 5, "Saturation adjustment" );
    } else {
      bSlider = newSlider( 0, 100, 50, 25, 5, "Brightness adjustment" );
    }
    // Add a separator to divide components
    panel.add( new JSeparator(), BorderLayout.SOUTH );
    
    // Add the panel to frame
    add( panel );
    
    // Return the new JPanel
    return panel;
    
  }
  
  // Method to return a JSlider with all necessary components available in parameters
  // This will prevent redundancy (eg. setting visibility of tick marks for every slider)
  private JSlider newSlider( int min, int max, int value, int majorTicks, int minorTicks, String tooltip ) {
    
    // Create new JSlider
    JSlider slider = new JSlider(min, max, value);
    
    // Enable tick marks
    slider.setPaintTicks( true );
    slider.setMajorTickSpacing( majorTicks );
    slider.setMinorTickSpacing( minorTicks );
    // Enable labels
    slider.setPaintLabels( true );
    // Set tooltip text
    slider.setToolTipText( tooltip );
    
    // Add the slider to the frame
    panel.add( slider );
    
    // Return the slider
    return slider;
  }
  
  // Accessor for the colour variable
  public Color getColour() {
    return colour;
  }
  
  private class SliderHandler implements ChangeListener {
    public void stateChanged( ChangeEvent event ) {
      
      // Use JSlider to determine the slider with changed values
      change = (JSlider) event.getSource();
      
      // Apply changes accordingly
      if ( change == hSlider ) { // If the slider with changed values is the hue slider,
        hue = change.getValue() / 360.0f; // Get said changed values
        colour = colour.getHSBColor( hue , saturation, brightness ); // Get the HSB colour
        colourOutput.setBackground( colour ); // Set the colour output to the changed HSB colour
      } else if ( change == sSlider ) {
        saturation = change.getValue() / 100.0f;
        colour = colour.getHSBColor( hue , saturation, brightness );
        colourOutput.setBackground( colour );
      } else if ( change == bSlider ) {
        brightness = change.getValue() / 100.0f;
        colour = colour.getHSBColor( hue , saturation, brightness );
        colourOutput.setBackground( colour );
      }
      
    }
  }

}

I don't have time to spell this out right now, but here's the short version.
You need to create your own change Listener - just like the slider defines an interface and allows you to add listeners with that interface, and calls ithem when the slider changes - you do exactly the same thing for your class. Define a ColorChangeListener interface with a ColorChanged(...) method. Add an ArrayList of ColorChangeListeners to your class. Add a addColorChnageListener(...) method. When the color changes, call the ColorChanged method for every element in the ArrayList.

This article has been dead for over six months. Start a new discussion instead.