0

I am taking a class that is teaching Java and we have a problem I can not solve. We need to move two rectangles in opposite directions. I have the code completed that will do this but the problem is I can only get either one or none of the rectangles to appear. I have tried varying solutions, such as adding the rectangles to a JPanel, as well as different layouts with no success.

public class RectTimer {

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setSize(300, 300);
    frame.setTitle("An animated rectangle");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    final RectangleComponent component = new RectangleComponent();
    final RectangleComponent component2 = new RectangleComponent(290,290);
    JPanel container = new JPanel();
    container.add(component);
    container.add(component2);
    frame.add(container);
    frame.setVisible(true);
    class TimerListener implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent arg0) {
        component.moveBy(5, 5);

        }

    }
    class TimerListener2 implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent arg0) {
            component2.moveBy(-5, -5);

        }

    }
    ActionListener l = new TimerListener();
    Timer t = new Timer(100, l);
    t.start();
    ActionListener l2 = new TimerListener2();
    Timer t2 = new Timer(100, l2);
    t2.start();}


public class RectangleComponent extends JComponent{

private Rectangle box;

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

public RectangleComponent(int x, int y){
    box = new Rectangle(x,y,20,30);
}


@Override
public void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g.create();
    g2.draw(box);
    g2.dispose();
}

public void moveBy(int dx, int dy){
    box.translate(dx, dy);
    if(box.getX() > 300 && box.getY() > 300){
        box.setLocation(10, 10);
    }
    if(box.getX() < 0 && box.getY() < 0){
        box.setLocation(290, 290);
    }
    repaint();
}

public void moveTo(int x, int y){
    box.setLocation(x, y);
    repaint();
}}
Brady Shober
  • 67
  • 2
  • 9

2 Answers2

5

but the problem is I can only get either one or none of the rectangles to appear.

That is probably because you are still using the default BorderLayout of the frame and are adding the components to the CENTER. Only the last component added will be displayed.

I just used the OverlayLayout

I would suggest for something like this you don't want to use the OverlayLayout.

Because you are using random motion you just want to add the components to the same panel. You would then use a null layout so you can manually control the location of each component. You will also be responsible for setting the size of the component which would be its preferred size.

Also, you need to override the getPreferredSize() of your component to return the size you want the component to be. The preferred size will be based on your custom painting. So in your case the preferred size would be (20, 30);. The box would always be painted at (0, 0). To move the box you set the location of the box.

camickr
  • 321,443
  • 19
  • 166
  • 288
0

Of course in typical fashion, as soon as I posted this a related question led me to a solution. I just used

container.setLayout(new OverlayLayout(container));

We had not learned about that particular layout in class, so I did not even know to try it. The program now works exactly how I had expected it to.

Brady Shober
  • 67
  • 2
  • 9
  • @gpasch Yes that was why I asked... We have only done very basic GUI in class so of course I did not know. – Brady Shober Apr 17 '16 at 01:23
  • `Yes that was why I asked` - and you got help but haven't even acknowledged the help given? – camickr Apr 17 '16 at 02:59
  • @camickr I found a solution that works for me in a related question, http://stackoverflow.com/questions/15368586/moving-two-balls-in-opposite-direction?rq=1 – Brady Shober Apr 17 '16 at 18:19