Results 1 to 14 of 14
Thread: problems with JPanel and JFrame
- 04-07-2009, 11:37 PM #1
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
-
when does the circle method input() ever get called? Does circle need a constructor?
- 04-08-2009, 12:13 AM #3
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:
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)Java Code:public circle() { input(); }
The last thing that you want to do is call repaint() in your actionPerformed method... This will repaint the Frame with your oval...
- 04-08-2009, 03:23 AM #4
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:
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....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(); }
**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 fubarLast edited by v1nsai; 04-08-2009 at 04:12 AM.
C:\DOS > C:\DOS.RUN > RUN.DOS.RUN
-
Heck no. You have to unlearn this. Only a constructor gets executed. Otherwise methods will only get executed if they are called, period.I thought that creating an object of the class would mean that all the methods in the class would be executed, right?
Mark has put in code what I stated in my post.
- 04-08-2009, 03:40 AM #6
Moderator
- Join Date
- Feb 2009
- Location
- New Zealand
- Posts
- 4,561
- Rep Power
- 11
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.)
- 04-08-2009, 04:10 AM #7
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:
When you create:Java Code:public circle() { initComponents(); }
the constructor will be called and it will exicute all the code inside for that constructor... And in our case it will be initComponents()...Java Code:circle oval = new circle();
Post the code that you have and lets take a look...Who Cares... As Long As It Works...
- 04-08-2009, 06:26 AM #8
Senior Member
- Join Date
- Jan 2009
- Posts
- 671
- Rep Power
- 5
...does this
return the text for a JTextfield?Java Code:Double.parseDouble( event.getActionCommand() );
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.
- 04-08-2009, 06:58 AM #9
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
- 04-08-2009, 02:53 PM #10
No Prob... The good thing is that you got your program to work...
You don't want to implement initComponent as a constructor, but you want to call it in the constructor...I still don't understand how you suggest I should implement the initComponent method as a 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:
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 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); } }
So now what will happen is that if the user leaves the text box empty the initial radius will be 200 and not 25...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 ); } }Who Cares... As Long As It Works...
- 04-08-2009, 06:12 PM #11
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
- 04-08-2009, 06:37 PM #12
No prob...
Who Cares... As Long As It Works...
-
Nice little program. Thanks.
- 04-08-2009, 07:49 PM #14
Similar Threads
-
How to add JFrame inside JPanel
By niteshwar.bhardwaj in forum Java 2DReplies: 8Last Post: 12-13-2009, 08:41 PM -
Program using JPanel - problems
By doozer8688 in forum New To JavaReplies: 6Last Post: 11-04-2008, 11:16 PM -
scroll a Jpanel in a JFrame
By nidhirastogi in forum SWT / JFaceReplies: 1Last Post: 09-07-2008, 03:42 AM -
JPanel / layout problems
By Warhorsei in forum AWT / SwingReplies: 4Last Post: 06-04-2008, 05:26 AM -
JPanel Problems
By Riftwalker in forum AWT / SwingReplies: 6Last Post: 10-15-2007, 11:16 PM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks