3

I am a beginner, starting a simple project on GUI. The RectangleComponent should draw a Rectangle on the form with a button click. A rectangle won't draw with the following code, but if I put the same 2 lines of code outside the listener, it certainly works. I would appreciate any help.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class EllipseRectViewer {
/**
* @param args
*/
public static void main(String[] args) 
{
  final JFrame frame = new JFrame();

  final int FRAME_WIDTH  = 400;
  final int FRAME_HEIGHT = 400;
  frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
  frame.setTitle("Rectangle and Ellipse Draw");
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  frame.setLayout(new BorderLayout());

  JPanel panel = new JPanel();
  frame.add(panel, BorderLayout.NORTH);

  class RectangleDrawListener implements ActionListener
  {
    public void actionPerformed(ActionEvent event)
    {   
        RectangleComponent r2 = new RectangleComponent();
        frame.add(r2);
     }    
   }
   JButton rectButton = new JButton("Rectangle");
   ActionListener rectDrawListener = new RectangleDrawListener();
   rectButton.addActionListener(rectDrawListener);
   panel.add(rectButton);

    frame.setVisible(true);
  }
}

import java.awt.Rectangle;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;

public class RectangleComponent extends JComponent
{
  Rectangle rect;

  public RectangleComponent()
  {
    rect  = new Rectangle(20, 20, 30, 30);
  }

  public void paintComponent(Graphics g)
  {
    Graphics2D g2 = (Graphics2D) g;
    g2.draw(rect);
  } 
}

Thank you.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Homo homilis
  • 59
  • 1
  • 7

4 Answers4

4

After adding the RectangleComponent to the frame, either revalidate the newly added component or the frame's root pane:

public void actionPerformed(ActionEvent event) {   
    RectangleComponent r2 = new RectangleComponent();
    frame.add(r2);
    // Option 1
    r2.revalidate();
    // Option 2
    frame.getRootPane().revalidate();
}

Note1: the frame itself can't be revalidated (upto JDK 1.6)
Note2: the frame itself can be revalidated (JDK 1.7+)

Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
  • Please May you tell me briefly, as to Why frame itself cannot be revalidated ? I tried frame.revalidate() and it's working too. I am not sure, but is it some difference in the JDK 7 or previous versions. No doubt previously we use to do many things with getRootPane(). – nIcE cOw Feb 14 '12 at 07:33
  • Ahhh, looks like, we can revalidate a `JFrame` with JRE7! [This is new](http://docs.oracle.com/javase/7/docs/api/java/awt/Component.html#revalidate%28%29). For all previous versions: use rootPane or revalidate the child component. – Andreas Dolk Feb 14 '12 at 07:46
  • I am simply using a notepad with JDK 7, and it is working flawless [Component.revalidate()](http://docs.oracle.com/javase/7/docs/api/java/awt/Component.html#revalidate()). Thankyou for the info, my bad I left JDK previous version soon, I shouldn't have done that, JDK 7 is not yet into the groove seems like, so just clearing my head with many questions. +1 though for the nice info :-) Regards – nIcE cOw Feb 14 '12 at 07:49
3

i think you need to revalidate() the frame.

frame.revalidate();

put it like this:

public void actionPerformed(ActionEvent event)
{   
    RectangleComponent r2 = new RectangleComponent();
    frame.add(r2);
    frame.revalidate();
 }    
kleopatra
  • 51,061
  • 28
  • 99
  • 211
gprathour
  • 14,813
  • 5
  • 66
  • 90
  • no ... JFrame is-not a JComponent - but since jdk7 a Component supports revalidate (thanks @AndreasD for the info), so removed the downvote – kleopatra Feb 14 '12 at 08:22
1

Try to use LineBorder. Create a JPanel with LineBorder and add the JButton to the JPanel.

StanislavL
  • 56,971
  • 9
  • 68
  • 98
1

rect = new Rectangle(20, 20, 30, 30);

A second problem is that your component doesn't have a preferred size. Your component displays in a simple frame because you add the comonent to the center of a BorderLayout so the preferred size of the component is ignored. However, this won't work if you try to use the component when using other layout managers.

You should also override the getPreferredSize() method to return the preferred size of your component at a minimum you need to use:

return new Dimension(50, 50);

to accomodate the size and location of the painted rectangle.

camickr
  • 321,443
  • 19
  • 166
  • 288