drawing simple rectangles on a Jframe in java

2020-02-06 07:34发布

问题:

I am extending JFrame like this:

public GameFrame() {
    this.setBounds(30, 30, 500, 500);
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    initializeSquares();
}

private void initializeSquares(){
    for(int i = 0; i < 5; i++){
        this.getContentPane().add(new Square(i*10, i*10, 100, 100));
    }
    this.setVisible(true);
}

However, only one square is being drawn on the screen, does anybody know why?

also My Square class looks like this:

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

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawRect(x, y, width, height);
}

回答1:

The JFrame's contentPane uses BorderLayout by default. When you add a Square to it, it gets added by default BorderLayout.CENTER and covers up any previously added Squares. You will want to read up on all the layout managers available to Swing GUI's.

For e.g., start here: Laying Out Components within a Container

But having said this, I would do things differently. I would create just one JPanel and make it able to paint multiple squares. For example something like so:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;

public class GameFrame extends JFrame {
   public GameFrame() {
      super("Game Frame");
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      Squares squares = new Squares();
      getContentPane().add(squares);
      for (int i = 0; i < 15; i++) {
         squares.addSquare(i * 10, i * 10, 100, 100);
      }

      pack();
      setLocationRelativeTo(null);
      setVisible(true);

   }

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

}

class Squares extends JPanel {
   private static final int PREF_W = 500;
   private static final int PREF_H = PREF_W;
   private List<Rectangle> squares = new ArrayList<Rectangle>();

   public void addSquare(int x, int y, int width, int height) {
      Rectangle rect = new Rectangle(x, y, width, height);
      squares.add(rect);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      for (Rectangle rect : squares) {
         g2.draw(rect);
      }
   }

}


回答2:

Fo absolute positioning, call setLayout(null). Then the icons will be drawed at the position returned by their getLocation() method, so you might want to call the setLocation() first.



回答3:

Even I was having an issue while displaying multiple rectangles on a jframe with absolute layout i.e layout set to null.

JFrame frame = new JFrame("hello");
frame.setLayout(null);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.getContentPane().setBackground(Color.red);
frame.getContentPane().add(new Square(10,10,100,100));//My rectangle class is similar to the Square mentioned in the question and it extends JComponent.

Still I was getting issues as the rectangle was not displayed.Unless you explicitly set the bounds on the Square(JComponent) ,it will not work.Even though the Square has the location passed in the constructor ,setbounds only fixed the issue.So the below fixed the issue and this issue is for an absolute layout jframe.

Square square = new Square(10,10,100,100);
square.setBounds(10,10,100,100);
frame.getContentPane().add(square);