javagraphicssliderchangelistener

Can't get change listener to work with slider


I was supposed to make a screen saver application that draws a certain amount of random lines every five seconds, and we were supposed to include a UI to allow the user to input the amount of lines they want drawn. I figured a slider would be easiest but I can't get the slider to change the value of the lines variable that is used in the loop that draws the lines. The value is stuck at 250 no matter where i put the slider

public class Q4  extends JComponent  implements ActionListener, ChangeListener{
private Random rand=new Random();
private Timer time=new Timer(5000,this);
private int lines;
JSlider line=new JSlider(0,500);;
public Q4(){
    JFrame frame=new JFrame();
    frame.setSize(1080,720);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
    frame.add(this);
    JSlider line=new JSlider(0,500);
    line.addChangeListener(this);
    line.setMajorTickSpacing(50);
    line.setMinorTickSpacing(25);
    line.setPaintTicks(true);
    line.setPaintLabels(true);
    frame.add(line, BorderLayout.NORTH);
}

@Override 
public void paintComponent(Graphics g) {
    time.start();
    int x=0;
    while(x<lines) {
        int x1=rand.nextInt(getWidth())+1;
        int y1=rand.nextInt(getHeight())+1;
        int x2=rand.nextInt(getWidth())+1;
        int y2=rand.nextInt(getHeight())+1;
        g.drawLine(x1, y1, x2, y2);
        x++;
    }
    System.out.println(lines);
}

@Override
public void actionPerformed(ActionEvent e) {
    repaint();      
}
@Override
public void stateChanged(ChangeEvent e) {
        lines=line.getValue();  
}

Solution

  • private int lines;
    JSlider line=new JSlider(0,500);;
    public Q4(){
        ...
        JSlider line=new JSlider(0,500);
    

    The problem is you have two sliders, once instance variable and one local variable. You add the listener to the local variable, but your listener can only access the instance variable.

    Get rid of the local variable.

    Other problems:

    1. Don't start a Timer in a painting method. A painting method is for painting only. The Timer should be started in the constructor

    2. The setVisible( true ) should be invoked AFTER all the components have been added to the panel

    3. Your class should NOT be create the frame. Your custom component is a stand alone component and creating the frame in the constructor has nothing to do with your component. The frame should be create in the public static void main() method that you use to test the code.