Search code examples
javaswingpaintcomponentjslider

Why isn't my JSlider Displaying in my java GUI?


I'm really frustrated because The GUI displays but no JSlider! Okay, so the GUI is suppose to display a circle, JTextfield (that updates when the slider is moved). The textfield is suppose to display radius, diameter, etc.. and update it automatically when the slider is moved. The circle is also suppose to increase in size or decrease once the slider is moved. Here's my code. No errors, runs fine, and compiles. It's probably my coordinates that's off.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import javafx.stage.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Circle1 extends JFrame 
{

   private final CircleCanvas theCanvas;

   private final JTextArea display; 

   public Circle1()

   {

      super( "Circle1" );

      theCanvas = new CircleCanvas();

      display = new JTextArea( 4, 30 );



      display.setText( "The Radius: " + theCanvas.getRadius() + "\nThe Diameter: " + theCanvas.getDiameter() + "\nThe Area: " + theCanvas.getArea() +

                              "\nThe Circumference: " + theCanvas.getCircumference() );



      getContentPane().add( theCanvas, BorderLayout.CENTER );

      getContentPane().add( display, BorderLayout.SOUTH );

      setSize( 200, 200 );
      setVisible(true);

   }



   public static void main( String args[] )

   {

      Circle1 app = new Circle1();


      app.addWindowListener(

         new WindowAdapter() 
         {

            public void WindowClosing( WindowEvent e )

            {

            }
         }
      );
   }

    void setDiameter(int value) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

} 

class CircleCanvas extends JPanel 
{

   private final int radius; 

   public CircleCanvas()

   {

      radius = ( int )( 1 + Math.random() * 100 );

      setSize (100, 100);

   }

   @Override
   public void paintComponent( Graphics g )

           {  g.drawOval( 0, 0, radius, radius );  }



   public int getDiameter()  
            {  return ( 2 * radius );  }



   public int getCircumference()

           {  return ( int )( 2 * Math.PI * radius );  }



   public int getArea()

           {  return ( int )( radius * radius * Math.PI );  }



   public int getRadius()  
            {  return radius;  }

}

class SliderFrame extends JFrame
{
      private JSlider diameterJSlider;
      private Circle1 myPanel;

      public SliderFrame()
      {

        super("HW2");

        myPanel = new Circle1();


        diameterJSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 300, 10);
        diameterJSlider.setMajorTickSpacing(10);
        diameterJSlider.setPaintTicks(true);
        diameterJSlider.addChangeListener(new ChangeListener()
        {
        public void stateChanged(ChangeEvent e)
        {
          myPanel.setDiameter(diameterJSlider.getValue());
        }
      }
    );
        add(diameterJSlider, BorderLayout.NORTH);
        add(myPanel, BorderLayout.CENTER);
     }
  }

Solution

  • Circle1 is a window, it can't be added to another window, so your SliderFrame is already doing something wrong, this is why it's generally discouraged to extend directly from a top level container like JFrame and instead, you should start with something like JPanel

    So, you could start with something like...

    public class Circle1 extends JPanel {
    
        private final CircleCanvas theCanvas;
    
        private final JTextArea display;
    
        public Circle1() {
    
            setLayout(new BorderLayout());
    
            theCanvas = new CircleCanvas();
    
            display = new JTextArea(4, 30);
    
            display.setText("The Radius: " + theCanvas.getRadius() + "\nThe Diameter: " + theCanvas.getDiameter() + "\nThe Area: " + theCanvas.getArea()
                            + "\nThe Circumference: " + theCanvas.getCircumference());
    
            add(theCanvas, BorderLayout.CENTER);
            add(display, BorderLayout.SOUTH);
    
        }
    
        void setDiameter(int value) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
    
        class CircleCanvas extends JPanel {
    
            private final int radius;
    
            public CircleCanvas() {
    
                radius = (int) (1 + Math.random() * 100);
    
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(100, 100);
            }
    
            @Override
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawOval(0, 0, radius, radius);
            }
    
            public int getDiameter() {
                return (2 * radius);
            }
    
            public int getCircumference() {
                return (int) (2 * Math.PI * radius);
            }
    
            public int getArea() {
                return (int) (radius * radius * Math.PI);
            }
    
            public int getRadius() {
                return radius;
            }
    
        }
    }
    

    Which you could then use something like...

    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                ex.printStackTrace();
            }
    
            JFrame frame = new JFrame("Testing");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new Circle1());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    });
    

    to show.

    Then you could change your SliderFrame to something more like...

    public class SliderPane extends JPanel {
    
        private JSlider diameterJSlider;
        private Circle1 myPanel;
    
        public SliderPane() {
    
            setLayout(new BorderLayout());
            
            myPanel = new Circle1();
    
            diameterJSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 300, 10);
            diameterJSlider.setMajorTickSpacing(10);
            diameterJSlider.setPaintTicks(true);
            diameterJSlider.addChangeListener(new ChangeListener() {
                public void stateChanged(ChangeEvent e) {
                    myPanel.setDiameter(diameterJSlider.getValue());
                }
            }
            );
            add(diameterJSlider, BorderLayout.NORTH);
            add(myPanel, BorderLayout.CENTER);
        }
    }
    

    And use something like...

    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                ex.printStackTrace();
            }
    
            JFrame frame = new JFrame("Testing");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new SliderPane());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    });
    

    to show it.

    Slider

    Runnable example

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JSlider;
    import javax.swing.JTextArea;
    import javax.swing.SwingConstants;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    // Change these two lines to switch between the panels
                    //frame.add(new Circle1());
                    frame.add(new SliderPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class Circle1 extends JPanel {
    
            private final CircleCanvas theCanvas;
    
            private final JTextArea display;
    
            public Circle1() {
    
                setLayout(new BorderLayout());
    
                theCanvas = new CircleCanvas();
    
                display = new JTextArea(4, 30);
    
                display.setText("The Radius: " + theCanvas.getRadius() + "\nThe Diameter: " + theCanvas.getDiameter() + "\nThe Area: " + theCanvas.getArea()
                                + "\nThe Circumference: " + theCanvas.getCircumference());
    
                add(theCanvas, BorderLayout.CENTER);
                add(display, BorderLayout.SOUTH);
    
            }
    
            void setDiameter(int value) {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }
    
            class CircleCanvas extends JPanel {
    
                private final int radius;
    
                public CircleCanvas() {
    
                    radius = (int) (1 + Math.random() * 100);
    
                }
    
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(100, 100);
                }
    
                @Override
                public void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    g.drawOval(0, 0, radius, radius);
                }
    
                public int getDiameter() {
                    return (2 * radius);
                }
    
                public int getCircumference() {
                    return (int) (2 * Math.PI * radius);
                }
    
                public int getArea() {
                    return (int) (radius * radius * Math.PI);
                }
    
                public int getRadius() {
                    return radius;
                }
    
            }
        }
    
        public class SliderPane extends JPanel {
    
            private JSlider diameterJSlider;
            private Circle1 myPanel;
    
            public SliderPane() {
    
                setLayout(new BorderLayout());
    
                myPanel = new Circle1();
    
                diameterJSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 300, 10);
                diameterJSlider.setMajorTickSpacing(10);
                diameterJSlider.setPaintTicks(true);
                diameterJSlider.addChangeListener(new ChangeListener() {
                    public void stateChanged(ChangeEvent e) {
                        myPanel.setDiameter(diameterJSlider.getValue());
                    }
                }
                );
                add(diameterJSlider, BorderLayout.NORTH);
                add(myPanel, BorderLayout.CENTER);
            }
        }
    
    }