0

I read many other posts regarding this and I learned that the frame is set to BorderLayout by default. I added one shape to the west and one shape to the center of the frame. But still, only one shape comes up on the frame. The shape that comes up on the frame is the one whose location is at center.

Here is the code:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class ShapeMover {

  private static final int FRAME_WIDTH  = 400;
  private static final int FRAME_HEIGHT = 400;
  private static final int SHAPE_WIDTH  = 50;
  private static final int INITIAL_X  = 30;
  private static final int INITIAL_Y  = 100;
  private static final int rec_x = 200;
  private static final int rec_y = 200;
  private static final int rec_height = 30;
  private static final int rec_width = 50;

  private boolean recToggle = true;
  private boolean circleToggle = true;

  private JFrame frame;
  private CircleComponent myShape;
  private RectangleComponent recShape;
  private JButton circle, rectangle;
  private JPanel panel, panel2;

  private void initialSetUp() {
      frame = new JFrame();

    myShape = new CircleComponent(INITIAL_X, INITIAL_Y, SHAPE_WIDTH);
    recShape = new RectangleComponent(rec_x, rec_y,rec_height, rec_width);

    circle = new JButton("Click for circle");
    event c = new event();
    circle.addActionListener(c);

    rectangle = new JButton("Click for rectangle");
    event2 r = new event2();
    rectangle.addActionListener(r);
    panel = new JPanel();
    panel.add(circle);
    panel.add(rectangle);
    frame.add(panel, BorderLayout.NORTH);


    frame.add(myShape, BorderLayout.WEST);
    frame.add(recShape,BorderLayout.CENTER);
    myShape.setVisible(false);
    recShape.setVisible(false);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
    frame.setVisible(true);

  } //method

  public class event implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
        if(circleToggle == true){
            myShape.setVisible(true);
            circleToggle = false;
        }
        else{
            myShape.setVisible(false);
            circleToggle = true;
        }
        }
  }

  public class event2 implements ActionListener{
      @Override
      public void actionPerformed(ActionEvent e){
          if(recToggle == true){
              recShape.setVisible(true);
              recToggle = false;
          }
          else{
              recShape.setVisible(false);
              recToggle = true;
          }
          }
  }


  public static void main(String[] args) {

    ShapeMover sm = new ShapeMover();
    sm.initialSetUp();

  } //main

} //class

I warn you the other code is pretty long. Here is rectangle component:

    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseMotionAdapter;
    import javax.swing.JComponent;

    public class RectangleComponent extends JComponent{
        private CompoundShape shape2;
        private Point mousePoint2;

    public RectangleComponent(int x, int y, int height, int width){
          shape2 = new RectangleShape(x, y, height, width);
          addMouseListener(new MouseAdapter(){
              @Override
              public void mousePressed(MouseEvent event2){
                  mousePoint2 = event2.getPoint();
                  if(!shape2.contains(mousePoint2)){
                      mousePoint2 = null;
                  }
              }
          });

          addMouseMotionListener(new MouseMotionAdapter(){
              @Override
              public void mouseDragged(MouseEvent event2){
                  if(mousePoint2 == null){
                      return;
                  }
                  Point lastMousePoint2 = mousePoint2;
                  mousePoint2 = event2.getPoint();
                  double dx = mousePoint2.getX() - lastMousePoint2.getX();
                  double dy = mousePoint2.getY() - lastMousePoint2.getY();
                  shape2.translate((int) dx, (int) dy);
                  repaint();
              }
          });
    }
    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        //shape.draw(g2);
        shape2.draw(g2);
      } //method
    }

Here is the circle Component:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JComponent;

public class CircleComponent extends JComponent{
    private Circle shape2;
    private Point mousePoint2;

public CircleComponent(int x, int y, int width){
      shape2 = new Circle(x, y, width);
      addMouseListener(new MouseAdapter(){
          @Override
          public void mousePressed(MouseEvent event2){
              mousePoint2 = event2.getPoint();
              if(!shape2.contains(mousePoint2)){
                  mousePoint2 = null;
              }
          }
      });

      addMouseMotionListener(new MouseMotionAdapter(){
          @Override
          public void mouseDragged(MouseEvent event2){
              if(mousePoint2 == null){
                  return;
              }
              Point lastMousePoint2 = mousePoint2;
              mousePoint2 = event2.getPoint();
              double dx = mousePoint2.getX() - lastMousePoint2.getX();
              double dy = mousePoint2.getY() - lastMousePoint2.getY();
              shape2.translate((int) dx, (int) dy);
              repaint();
          }
      });
}
public void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    //shape.draw(g2);
    shape2.draw(g2);
  } //method
}

Here is circle:

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;

public class Circle implements CompoundShape {
    private GeneralPath path = null;
    private int x;
    private int y;
    private final int width;

    public Circle(int x, int y, int width){
        this.x = x;
        this.y = y;
        this.width = width;
    }


    @Override
    public void draw(Graphics2D g2) {
        Ellipse2D.Double c = new Ellipse2D.Double(x,y,width,width);
        g2.setColor(Color.RED);
        g2.fill(c);
        g2.draw(c);

        path = new GeneralPath();
        path.append(c,false);
        g2.draw(path);
    }

    @Override
    public void translate(int dx, int dy) {
        // TODO Auto-generated method stub
        x = x + dx;
        y = y + dy;

    }

    @Override
    public boolean contains(Point point) {
        // TODO Auto-generated method stub

        if(path == null){
            return false;
        }
        return path.contains(point);
    }

}

Here is rectangle shape:

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;

public class RectangleShape implements CompoundShape {
    private GeneralPath path = null;
    private int x;
    private int y;
    private final int width;
    private final int height;

    public RectangleShape(int x, int y, int width, int height){
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }


    @Override
    public void draw(Graphics2D g2) {
        Rectangle r = new Rectangle(x,y,width,height);
        g2.setColor(Color.BLUE);
        g2.fill(r);
        g2.draw(r);

        path = new GeneralPath();
        path.append(r,false);
        g2.draw(path);
    }

    @Override
    public void translate(int dx, int dy) {
        // TODO Auto-generated method stub
        x = x + dx;
        y = y + dy;

    }

    @Override
    public boolean contains(Point point) {
        // TODO Auto-generated method stub

        if(path == null){
            return false;
        }
        return path.contains(point);
    }

}

Here is compound shape:

import java.awt.Graphics2D;
import java.awt.Point;

public interface CompoundShape {

  void draw(Graphics2D g2);
  void translate(int dx, int dy);
  boolean contains(Point point);

} //interface
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 1
    You're going to need to provide `CircleComponent` and `RectangleComponent` before we can make more suggestions... – MadProgrammer Nov 18 '14 at 07:00
  • *"added one shape to the west and one shape to the center of the frame"* Why not draw both objects at different locations of the **same** container? I'd store them in a collection such as an `ArrayList`, then iterate the collection in the paint (component) method and draw or fill each one. – Andrew Thompson Nov 18 '14 at 07:03
  • *"The shape that comes up on the frame is the one whose location is at center."* But the immediate problem can be fixed by `@Override public Dimension getPreferredSize() { ..` of the shape components. – Andrew Thompson Nov 18 '14 at 07:05
  • 2
    For better help sooner, post an **[MCVE](http://stackoverflow.com/help/mcve)** (Minimal Complete Verifiable Example) rather than classes spread over 6 source code files. – Andrew Thompson Nov 18 '14 at 07:10
  • The main class is ShapeMover.java. The other classes are there for references as MadProgrammer asked for. I feel like its got something to do with the layout manager of my frame – user3754524 Nov 18 '14 at 07:13
  • *"..I feel like its got something to do with the layout manager of my frame"* Yes, that's a contributing factor, to which I told you the fix in my 2nd comment. – Andrew Thompson Nov 18 '14 at 09:04
  • They both are in different locations. I am not really sure what you mean by iterating via ArrayList. Could you elaborate? – user3754524 Nov 18 '14 at 14:54
  • Tip: Add @MadProgrammer (or whoever, the `@` is important) to notify the person of a new comment. – Andrew Thompson Nov 19 '14 at 00:51
  • @AndrewThompson I asked my teacher and he kind of said something about the array list as well. I have to store the object in some array list and call it in repaint? Can you elaborate more on this? I googled it and I read that the shapes must be stored in an array list so both of them can be displayed. But I am still a little confused? An example would be nice =) – user3754524 Nov 19 '14 at 02:36

1 Answers1

1

Examples of iterating an ArrayList<Shape> can be seen in:

Of course, those examples are painting to an image, but once there is a Graphics (or Graphics2D as I prefer to work with) the principle is much the same. Copy/pasted from one example:

ArrayList<Shape> regions = separateShapeIntoRegions(imageShapeArea);
// ..
for (Shape region : regions) {
    // ..
    g.fill(region);
    // ..
}
Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • I am still confused to be honest. I do not understand why my code would only paint one shape at a time. What exactly is stopping it from paining two at a time? – user3754524 Nov 20 '14 at 05:55
  • Like I wrote yesterday, you'll get better help if you post an MCVE. A less subtle way to put that is "I'll give it a moment's more notice the very minute you post an MCVE (and I hear about it). Note that you can turn that code seen above into an MCVE relatively simply. Change all the `public class` to just `class`. Then copy/paste the source (after the imports) of every class with no `main(String[])` into the end of the source with a `main`. Then resolve the imports. (For brevity sake, I used package imports in most of the MCVEs I post. Preparing an MCVE is an important skill. .. – Andrew Thompson Nov 20 '14 at 07:00
  • Thanks. I will try to learn it once I get time. I have been super busy with other coursework. Have a huge project for object oriented programming as well. Sucks being a college student =( – user3754524 Nov 23 '14 at 02:31
  • *"Have a huge project for object oriented programming as well."* It will take **longer** to complete unless you know how to make an MCVE.. For my part, I'll *look more closely* at this problem once there is an MCVE and **not before.** Otherwise I'm wasting ***my*** time, which is valuable to me. – Andrew Thompson Nov 23 '14 at 03:28