Results 1 to 14 of 14
  1. #1
    v1nsai's Avatar
    v1nsai is offline Member
    Join Date
    Mar 2009
    Posts
    28
    Rep Power
    0

    Default problems with JPanel and JFrame

    I seem to be doing something wrong, because my code compiles but all I get is a blank box, I've been going around in circles trying to figure out what I'm doing wrong.

    This is a program that accepts a value from the user and uses it as the radius to draw a circle, in addition to displaying varius stats about the circle that is being shown.

    Any help greatly appreciated.

    Java Code:
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.JLabel;
    import java.awt.Color;
    import java.awt.Graphics;
    import javax.swing.SwingConstants;
    
    public class circle extends JPanel
    {
        public double radius;
        public double diameter;
        public double circum;
        public double area;
        public int diam;
        public JTextField input;
        public JLabel display;
        
        public void input()
        {        
            //input dialog box sits at top of screen
            input = new JTextField( 20 );
            input.setText( "Please input radius" );
            input.selectAll();
            add( input );
            
            //JLabel displays dimensions of drawn circle
            display = new JLabel( "circumference = " + circum +
                                  "radius = " + radius +
                                  "diameter = " + diameter +
                                  "area = " + area, SwingConstants.BOTTOM );
            
            //a listener for input
            input.addActionListener(
                new ActionListener()
                {
                    public void actionPerformed( ActionEvent event )
                    {
                        if( event.getSource() == input ) 
                        {
                            radius = Double.parseDouble( event.getActionCommand() );
                            diameter = radius*2;
                            circum = radius*3.14159*2;
                            area = 3.14159*(Math.pow( radius, 2 ));
                            diam = (int)diameter;
                        }
                    }
                }
            );
        }
        public void paintComponent( Graphics g )
        {
            super.paintComponent( g );
            
            g.setColor( Color.BLUE );
            g.fillOval( 50, 50, diam, diam );
        }
    }
    Java Code:
    import javax.swing.JFrame;
    
    public class circleFrame
    {
        public static void main( String args[] )
        {
            JFrame frame = new JFrame( "All you wanted to know about a circle" );
            frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
            
            circle oval = new circle();
            frame.add( oval );
            frame.setSize( 750, 750 );
            frame.setVisible( true );
        }
    }
    C:\DOS > C:\DOS.RUN > RUN.DOS.RUN

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    when does the circle method input() ever get called? Does circle need a constructor?

  3. #3
    markw8500's Avatar
    markw8500 is offline Senior Member
    Join Date
    Jul 2008
    Location
    Pennsylvania, USA
    Posts
    136
    Rep Power
    0

    Default

    There are a couple of different things that you always want to remember to do that will cause that type of behavior... The one that you will need to do is set the Layout Manager... If you extend JPanel and forget to set the Layout Manager you will always end up with a blank frame...

    The second thing that you need to do is to call input()... It seems like you wanted input() to be your constructor, but you really want to use:
    Java Code:
        public circle() {
    
          input();
        }
    Notice that I called input() in the constructor... This is not necessarily bad practice... A more standard practice is instead of input() you want to call your method initComponents()... (Initiate Components)

    The last thing that you want to do is call repaint() in your actionPerformed method... This will repaint the Frame with your oval...

  4. #4
    v1nsai's Avatar
    v1nsai is offline Member
    Join Date
    Mar 2009
    Posts
    28
    Rep Power
    0

    Default

    Okay, I was using the word input a little excessively so I changed the method to the name initComponent() and now only the JTextField is called input. I also set a layout manager and made a call to repaint in actionPerformed, but I'm not sure if I did it right:

    Java Code:
    public void actionPerformed( ActionEvent event )
                    {
                        if( event.getSource() == input ) 
                        {
                            radius = Double.parseDouble( event.getActionCommand() );
                            diameter = radius*2;
                            circum = radius*3.14159*2;
                            area = 3.14159*(Math.pow( radius, 2 ));
                            diam = (int)diameter;
                            repaint();
                        }
    I'm not sure what you mean by calling input, I tried adding "oval.initComponent()" in class circleFrame but it caused an exception. I thought that creating an object of the class would mean that all the methods in the class would be executed, I'm not sure what you mean by using input as a constructor....

    **edit: figured it out and got it running, I realized how stupid I sounded and that I did need to call oval.initComponent() but that there was an exception being created because of me. I was declaring SwingConstants incorrectly in the label which caused the compiler to crash. I've got everything running now, thanks for the help mark and fubar
    Last edited by v1nsai; 04-08-2009 at 05:12 AM.
    C:\DOS > C:\DOS.RUN > RUN.DOS.RUN

  5. #5
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    I thought that creating an object of the class would mean that all the methods in the class would be executed, right?
    Heck no. You have to unlearn this. Only a constructor gets executed. Otherwise methods will only get executed if they are called, period.

    Mark has put in code what I stated in my post.

  6. #6
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default

    Quote Originally Posted by markw8500 View Post
    If you extend JPanel and forget to set the Layout Manager you will always end up with a blank frame...
    I really don't think this is true.

    See the JFrame API docs for a discussion of how, by default, JFrame forwards setLayout() calls to the content pane (and how this pane will have a BorderLayout if no other is set.)

  7. #7
    markw8500's Avatar
    markw8500 is offline Senior Member
    Join Date
    Jul 2008
    Location
    Pennsylvania, USA
    Posts
    136
    Rep Power
    0

    Default

    pbrockway2: I see what you are saying, but in my experience I have never gotten that to work...

    v1nsai: Fubarable is correct... Methods only get called if you call them... You always want your program to do what you want it to do, WHEN you want it to do it... Google "Java Constructors" to get all the details on constructors... But for now you want to call your initComponents() in your constructor like so:

    Java Code:
        public circle() {
    
          initComponents();
        }
    When you create:
    Java Code:
    circle oval = new circle();
    the constructor will be called and it will exicute all the code inside for that constructor... And in our case it will be initComponents()...

    Post the code that you have and lets take a look...
    Who Cares... As Long As It Works...

  8. #8
    toadaly is offline Senior Member
    Join Date
    Jan 2009
    Posts
    671
    Rep Power
    6

    Default

    ...does this

    Java Code:
    Double.parseDouble( event.getActionCommand() );
    return the text for a JTextfield?

    Regardless, the real problem is that you are trying to draw directly onto the JPanel, which is filled with your JTextField, so it's always going to get overpainted and you'll never see the oval.

    I suggest creating a new component (by extending JComponent), and drawing your oval there instead.

  9. #9
    v1nsai's Avatar
    v1nsai is offline Member
    Join Date
    Mar 2009
    Posts
    28
    Rep Power
    0

    Default

    I get what your saying about the constructors mark, I realized about halfway into the semester that the book I'm learning from just sucks (online course) so I've been half learning from the book and half from google, I'm still missing bits and pieces of things hehe. I still don't understand how you suggest I should implement the initComponent method as a constructor, I simply called it after I created an object of class circle. Would you maybe edit my code to show me what you mean please?

    Java Code:
    public class circle extends JPanel
    {
        public double radius;
        public double diameter;
        public double circum;
        public double area;
        public int diam;
        public int center;
        public JTextField input;
        public JLabel display;
        
        public void initComponent()
        {
            setLayout( new FlowLayout() );
            
            this.setBackground( Color.BLACK );
            
            //input dialog box sits at top of screen
            input = new JTextField( 20 );
            input.setText( "Please input radius" );
            input.selectAll();
            add( input );
            
            //JLabel displays dimensions of drawn circle
            display = new JLabel( "<html>circumference = " + circum +
                                  "<br>radius = " + radius +
                                  "<br>diameter = " + diameter +
                                  "<br>area = " + area + "</html>" );
            display.setForeground( Color.white );
            add( display );                                     
            
            //a listener for input
            input.addActionListener(
                new ActionListener()
                {
                    public void actionPerformed( ActionEvent event )
                    {
                        if( event.getSource() == input ) 
                        {
                            //set variables according to input from JTextField
                            radius = Double.parseDouble( event.getActionCommand() );
                            diameter = radius*2;
                            circum = radius*3.14159*2;
                            area = 3.14159*(Math.pow( radius, 2 ));
                            
                            diam = (int)diameter;//creates a usable int for paintComponent
                            
                            //sets JLabel display
                            display.setText( "<html>circumference = " + circum +
                                  "<br>radius = " + radius +
                                  "<br>diameter = " + diameter +
                                  "<br>area = " + area + "</html>" );
                                  
                            //sets the draw offset so circle is centered
                            center = 350 - diam/2;
                            repaint();
                        }
                    }
                }
            );
        }
        public void paintComponent( Graphics g )
        {
            super.paintComponent( g );
            
            g.setColor( Color.blue );
            g.fillOval( center, center, diam, diam );
        }
    }
    Java Code:
    public class circleFrame
    {
        public static void main( String args[] )
        {
            JFrame frame = new JFrame( "All you wanted to know about a circle" );
            frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
            
            circle oval = new circle();
            oval.initComponent();
            
            frame.add( oval );
            frame.setSize( 750, 750 );
            frame.setVisible( true );
        }
    }
    C:\DOS > C:\DOS.RUN > RUN.DOS.RUN

  10. #10
    markw8500's Avatar
    markw8500 is offline Senior Member
    Join Date
    Jul 2008
    Location
    Pennsylvania, USA
    Posts
    136
    Rep Power
    0

    Default

    No Prob... The good thing is that you got your program to work...

    I still don't understand how you suggest I should implement the initComponent method as a constructor
    You don't want to implement initComponent as a constructor, but you want to call it in the constructor...

    Java Code:
    public class circle extends JPanel {
    
        private double radius;
        private double diameter;
        private double circum;
        private double area;
        private int diam;
        private JTextField input;
        private JLabel display;
    
        public circle() {
    
          initComponents();
        }
    
    
    
    
        private void initComponents() {
            //input dialog box sits at top of screen
            input = new JTextField(20);
            input.setText("Please input radius");
            input.selectAll();
            
            
            setLayout( new FlowLayout() );
    
            
            add(input);
    
            //JLabel displays dimensions of drawn circle
            display = new JLabel("circumference = " + circum +
                    "radius = " + radius +
                    "diameter = " + diameter +
                    "area = " + area);
    
            //a listener for input
            input.addActionListener(
                    new ActionListener() {
    
                        public void actionPerformed(ActionEvent event) {
                            if (event.getSource() == input) {
                                radius = Double.parseDouble(event.getActionCommand());
                                diameter = radius * 2;
                                circum = radius * 3.14159 * 2;
                                area = 3.14159 * (Math.pow(radius, 2));
                                diam = (int) diameter;
    
                                System.out.println(event.getActionCommand());
                                repaint();
                            }
                        }
                    });
        }
    
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
    
            g.drawOval(200, 200, 200, 200);
            g.setColor(Color.BLUE);
            g.fillOval(200, 200, diam, diam);
            
        }
    }

    Java Code:
    public class Main {
    
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            // TODO code application logic here
    
            JFrame frame = new JFrame( "All you wanted to know about a circle" );
            frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    
            circle oval = new circle();
            
            frame.add( oval );
            frame.setSize( 750, 750 );
            frame.setVisible( true );
    
    
        }
    
    }

    Whenever you create your object circle oval = new circle();... circle() is your constructor... This will call everything inside... Which in our case it is initComponents()...

    So if you wanted to set an initial radius of your oval in case the user leaves the text box empty you could add this constructor:


    Java Code:
         public circle(double radius) {
     
          this.radius=radius;
    
          initComponents();
        }

    and down in your actionPerformed method you would do:


    Java Code:
            input.addActionListener(
                    new ActionListener() {
    
                        public void actionPerformed(ActionEvent event) {
                        
                            String s=""; 
     
                            if (event.getSource() == input) {
                                //set variables according to input from JTextField
    
                                if (!event.getActionCommand().isEmpty()) {
                                    radius = Double.parseDouble(event.getActionCommand());
                                    s="";
    
                                } else {
    
    
                                    s = "Although you did not enter a radius I did one for you...<br>";
    
                                }
    
    
                                //sets JLabel display
                                display.setText("<html>"+s+"circumference = " + circum +
                                        "<br>radius = " + radius +
                                        "<br>diameter = " + diameter +
                                        "<br>area = " + area + "</html>");
    
    
                                diameter = radius * 2;
                                circum = radius * 3.14159 * 2;
                                area = 3.14159 * (Math.pow(radius, 2));
    
                                diam = (int) diameter;//creates a usable int for paintComponent
    
    
    
                                //sets the draw offset so circle is centered
                                center = 350 - diam / 2;
                                repaint();
                            }
                        }
                    });

    You can add as many constructors as you want as long as they are all different... I think they call it overloading the constructor... Not sure though...

    So now your code will look like:


    Java Code:
    public class Circle2 extends JPanel {
    
        private double radius;
        private double diameter;
        private double circum;
        private double area;
        private int diam;
        private int center;
        private JTextField input;
        private JLabel display;
        private String s;
    
        public Circle2() {
    
            intiComponents();
        }
    
        public Circle2(double radius) {
    
            this.radius = radius;
            intiComponents();
    
        }
    
        public void intiComponents() {
            setLayout(new FlowLayout());
    
            this.setBackground(Color.BLACK);
    
            //input dialog box sits at top of screen
            input = new JTextField(20);
            input.setText("Please input radius");
            input.selectAll();
            add(input);
    
            //JLabel displays dimensions of drawn circle
            display = new JLabel("<html>circumference = " + circum +
                    "<br>radius = " + radius +
                    "<br>diameter = " + diameter +
                    "<br>area = " + area + "</html>");
            display.setForeground(Color.white);
            add(display);
    
            //a listener for input
            input.addActionListener(
                    new ActionListener() {
    
                        public void actionPerformed(ActionEvent event) {
                            if (event.getSource() == input) {
                                //set variables according to input from JTextField
    
                                if (!event.getActionCommand().isEmpty()) {
                                    radius = Double.parseDouble(event.getActionCommand());
                                    s = "";
    
                                } else {
    
    
                                    s = "Although you did not enter a radius I did one for you...<br>";
    
                                }
    
    
                                //sets JLabel display
                                display.setText("<html>" + s + "circumference = " + circum +
                                        "<br>radius = " + radius +
                                        "<br>diameter = " + diameter +
                                        "<br>area = " + area + "</html>");
    
    
                                diameter = radius * 2;
                                circum = radius * 3.14159 * 2;
                                area = 3.14159 * (Math.pow(radius, 2));
    
                                diam = (int) diameter;//creates a usable int for paintComponent
    
    
    
                                //sets the draw offset so circle is centered
                                center = 350 - diam / 2;
                                repaint();
                            }
                        }
                    });
        }
    
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
    
            g.setColor(Color.blue);
            g.fillOval(center, center, diam, diam);
        }
    }
    Another good practice is staying away from making your variables public... Unless you intentionally want other classes to access them... Notice that I also made initComponents private... The reason that I was told is that if there are two or three people working on a project, one of the other people might accidentally change a variable that is not supposed to be changed... Like so:

    Java Code:
    public static void main(String[] args) {
            // TODO code application logic here
    
            JFrame frame = new JFrame( "All you wanted to know about a circle" );
            frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    
            Circle2 oval = new Circle2(25);
            oval.radius=200;
            
            frame.add( oval );
            frame.setSize( 750, 750 );
            frame.setVisible( true );
    
    
        }
    
    }
    So now what will happen is that if the user leaves the text box empty the initial radius will be 200 and not 25...
    Who Cares... As Long As It Works...

  11. #11
    v1nsai's Avatar
    v1nsai is offline Member
    Join Date
    Mar 2009
    Posts
    28
    Rep Power
    0

    Default

    cool, I had no idea you could call constructors like that, my stupid book definitely never mentioned that. Thanks a bunch :)
    C:\DOS > C:\DOS.RUN > RUN.DOS.RUN

  12. #12
    markw8500's Avatar
    markw8500 is offline Senior Member
    Join Date
    Jul 2008
    Location
    Pennsylvania, USA
    Posts
    136
    Rep Power
    0

    Default

    No prob...
    Who Cares... As Long As It Works...

  13. #13
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Nice little program. Thanks.

  14. #14
    markw8500's Avatar
    markw8500 is offline Senior Member
    Join Date
    Jul 2008
    Location
    Pennsylvania, USA
    Posts
    136
    Rep Power
    0

Similar Threads

  1. How to add JFrame inside JPanel
    By niteshwar.bhardwaj in forum Java 2D
    Replies: 8
    Last Post: 12-13-2009, 09:41 PM
  2. Program using JPanel - problems
    By doozer8688 in forum New To Java
    Replies: 6
    Last Post: 11-05-2008, 12:16 AM
  3. scroll a Jpanel in a JFrame
    By nidhirastogi in forum SWT / JFace
    Replies: 1
    Last Post: 09-07-2008, 04:42 AM
  4. JPanel / layout problems
    By Warhorsei in forum AWT / Swing
    Replies: 4
    Last Post: 06-04-2008, 06:26 AM
  5. JPanel Problems
    By Riftwalker in forum AWT / Swing
    Replies: 6
    Last Post: 10-16-2007, 12:16 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •