0

I'm very new to programming and I've been having a few issues with something I'm working on. I'm trying to create multiple squares that can both move using the "Translate" method that I made. However, only the most recently added component is visible, and I cannot figure out how to add more than one.

package linerendertest;

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

class Square extends JComponent {
    
    public int[] xPoints = new int[4];
    public int[] yPoints = new int[4];
    
    Square (int width, int length){
    
        xPoints[0] = 0;
        xPoints[1] = 0;
        xPoints[2] = width;
        xPoints[3] = width;
        
        yPoints[0] = 0;
        yPoints[1] = length;
        yPoints[2] = length;
        yPoints[3] = 0;
        
    }

    @Override
    public void paint(Graphics g){
        
        g.setColor(Color.MAGENTA);
        //g.drawPolygon(xPoints, yPoints, 4);
        g.fillPolygon(xPoints, yPoints, 4);
    
    }
    
    public void translate (int xTranslate, int yTranslate){
    
        xPoints[0] += xTranslate;
        xPoints[1] += xTranslate;
        xPoints[2] += xTranslate;
        xPoints[3] += xTranslate;
        yPoints[0] += yTranslate;
        yPoints[1] += yTranslate;
        yPoints[2] += yTranslate;
        yPoints[3] += yTranslate;
    
    }

}

public class LineRenderTest {
    
    public static final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    public static final int centerX = screenSize.width / 2;
    public static final int centerY = screenSize.height / 2;

    public static void main(String[] args) throws InterruptedException {
        
        Square square = new Square(250, 250);
        Square paddle = new Square(50, 200);
        
        JFrame frame = new JFrame();
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setBackground(Color.black);
        frame.add(square);
        frame.add(paddle);
        
        frame.setVisible(true);
        
        int xVelocity = 0;
        int yVelocity = 1;
        square.translate(250, 0);
        
        while (true) {
            
            square.translate(xVelocity, yVelocity);
            frame.repaint();
            Thread.sleep(5);
            
            if(square.yPoints[1] == screenSize.height || square.yPoints[0] == 0){
            
                yVelocity = -yVelocity;   
                
            }
            
            if(square.xPoints[2] == screenSize.width || square.xPoints[0] == 0){
            
                xVelocity = -xVelocity;
                
            }
            
        }
        
    }

}

I have tried using BorderLayout.PAGE_START and others similar, but these all place the squares off-screen, and they disappear whenever they are moved. I have also tried adding the squares to a JPanel first, but this just makes all elements non-visible.

Sorry if some of the terminology I used was not correct. Any other tips would be appreciated!

  • 1
    Re-think the problem: 1. You should draw within one single class that extends JPanel, a DrawingPanel, so to speak, and you draw the squares or other sprites within this JPanel's paintComponent method. 2. The Square class should *not* extend JComponent but should be a logical class, not a GUI component. It should hold information about a single square's size, location and color. It can have a `public void draw(Graphics2D g)` method that allows it to draw itself, and that is called in the DrawingPanel's paintComponent method, and can have a translate method.... – Hovercraft Full Of Eels Dec 05 '22 at 23:12
  • 1
    Then give the drawing jpanel a collection of these squares, say an arraylist of however many you need, and translate them in some event, perhaps a Swing Timer, after translation call `repaint()` on the JPanel and draw them by iterating through the collection in the paintComponent method, similar to the answer in the duplicate. – Hovercraft Full Of Eels Dec 05 '22 at 23:13
  • Duplidate answers uses Threads to update the state of the ball animation which could potentially cause problems since the state of a Swing component should only be updated on the Event Dispatch Thread (EDT). Check out: https://stackoverflow.com/a/54028681/131872 which uses a Swing Timer to update the ball location on the EDT. – camickr Dec 06 '22 at 02:27

0 Answers0