I have the following code as taken from the book I read from:

import java.awt.*;
   import javax.swing.*;
/** Frame1 is a frame with a label and a button */
   public class Frame1 extends JFrame
   { /** Constructor Frame1 creates a frame with a label and button */
      public Frame1()
      { JLabel label = new JLabel("Press This:");
         JButton button = new JButton("OK");
         Container c = getContentPane();
         c.setLayout(new FlowLayout());
         c.add(button);
         c.add(label);
         setTitle("Example1");
         setSize(300, 260);
         setVisible(true);
      }
   	
   	
      public void paint(Graphics g)
      { g.setColor(Color.red);
         g.fillRect(0, 0, 100, 100);
      }
      public static void main(String[] args)
      { new Frame1(); }
   }

I expect it to show a red area in the shape of a box on the top left corner of the frame, and the label and button next to it. However, what happens is this: it either shows everything except the red area, or it shows nothing but the frame and it's borders, leaving my jGRASP seeable through the frame area.

I had the same exact problem working with JPanel (this time we're working with JFrame). What solved the problem is puting the getContentPane() in the same position it is now relative to other methods inside the constructor method. However, that's not helping me this time.

Anyone knows what's going on?

P.S. The problem only started after I added to the code the method paint.

Recommended Answers

All 13 Replies

Just use the JPanel to paint. Use the JFrame for interface. Don't cram it all into a JFrame just because you can only extend that class. Extend the JFrame, but create a JPanel and paint on it.

You have overidden paint(Graphics g) but this is not a recommended practice. paint(Graphics g) also has responsibility for painting child objects etc, and this can all get lost when you override it.
The recommended practice is to override paintComponent(Graphics g) instead. You override it in exactly the same way, but now you're not interfering with the painting of child objects, frames etc.

http://java.sun.com/products/jfc/tsc/articles/painting/#callbacks

alright, thank you all for taking the effort to answer. however, I am not understand what's going on. the following code is the best I could do based on your recommendations:

import javax.swing.*;
import java.awt.*;

public class Ok1 extends JPanel{

public Ok1(){
JFrame c = new JFrame();
c.getContentPane().add(this);
c.getContentPane();
c.setLayout(new FlowLayout());
JButton button = new JButton("Gagi");
c.add(button);
c.setSize(500, 500);
c.setTitle("Ok1");
c.setVisible(true);
}

public void paintComponent(Graphics g){
g.setColor(Color.red);
g.fillRect(0, 0, 500, 500);
}

public static void main(String[] args){
new Ok1();
}

}

I know I have c.getContentPane() and c.getContentPane().add(this) on the same class and that that might cause any problems, but I tried other variations, removing each one, andleaving the other... to no avail. I can't seem to be able to produce a red background using paint and put on top of it a button. (I know I can use c.setBackground(Color.red) to reach that effect, but I am curious to do it this way. Reason: there are myltiple panes in Java, I want to see how I manipulate different level panes in the same class, and I want to see where the book's mistake is - remember that I tookd the initial code from a book.)

thank you for your efforts.

I think the contantpane stuff is irrelevant - before Java 1.5 you had to add things to the contentpane, but since then you just add them to the JFrame.

You add the Ok1 panel to the frame, then you add the button, so these will be one after the other, not one on top of the other. I don't see why you were advised to put a panel in the frame anyway.

If you go right back to the very first version you posted and just change paint to paintComponent that should work (or at least get very close to working)

Actually, JFrame extends Frame from awt, not JComponent from swing. So I don't think paintComponent will work on the frame. It will probably work on a JPanel though.

I think you're right kramred, but JPanel won't help in displaying buttons. I want to display both buttons and a paintComponent. how do I go about doing this? anyone?

You can certainly put a JButton on a JPanel. Why are you saying JPanel won't help in displaying buttons?

pardon me, it does display buttons but it treats paintComponent method as a component of the same order as buttons displaying it next to the button in a 10by10 pixel square instead of say filling a full window rect.

please take a look at this code and tell me what am I doing wrong. it displays the button but not the paintComponent component.

import javax.swing.*;
   import java.awt.*;

   public class Nc extends JPanel {
   
      public Nc(){
		JFrame y = new JFrame();
         y.getContentPane().add(this);
         y.setLayout(new FlowLayout());
         JButton button = new JButton("OK");
         y.add(button);
         y.setSize(800, 1000);
         y.setVisible(true);
      
      }
   
   public void paintComponent(Graphics g){
	g.setColor(Color.white);
	g.fillRect(0, 0, 800, 1000);
	
	}
      public static void main(String[] args){
         new Nc();
      }
   }

Wrong. JFrame has paintComponent. Just add your buttons to the JFrame,and override paintComponent.

I made a few changes to your code. Try this.

public Nc(){
      JFrame y = new JFrame();
      y.getContentPane().add(this);
      y.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      JButton button = new JButton("OK");
      add(button);
      setSize(800, 1000);
      y.add(this);
      y.setSize(800, 1000);
      y.setVisible(true);
   }

my idea is to draw a rectangle that shall act as a car and move downwards. then, I want to draw an oval that acts as a hurdle and moves from right to left (that is towards the car). this all creates the impression that we have a car traveling along some road. I am trying to build me a game which ends once the car hits any hurdle or the ground. the car shall only move up and down(I want a button to make the car move upwards). i know how to do every thing except that I don't know how to add the button inside my window. I can't seem to make both the button and paintComponent show. a button alone won't do me anygood!

kramerd, I think that code you just gave me worked fine. It filled a white rectangle on the paintComponent and displayed a button. I assume this will also alow me to use a repaint() inside paintComponent and work properly. thank you very much.
I would also like to add that seems like the order of the methods you wrote is of importance. I switched the order and it failed to work. I am marking this thread solved! thanks again!
update: it is not necessarily the order that has any role. instead, removal of setLayout(new FlowLayout()) seems to have been the solution.

Create a class Car that extends JComponent and a class Hurdle that extends JComponent. Each component has a paintComponent method that draws itself. In other words, Car draws itself as a rectangle and Hurdle draws itself as an oval. A third class extends JFrame. In that class you construct the car and the hurdle objects and add them to the frame. You can add the button too, but there are different ways to do that depending on where you want the button to appear. For example, to make the button appear at the bottom of the window, add a BorderLayout layout manager to the frame and add the button to the SOUTH part of the window. If you use this approach, you have to create a JPanel, add your car and hurdle to the panel and then add the panel to the CENTER part of the window.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.