Рисование нескольких J-компонентов в кадр
Я пытаюсь нарисовать несколько автомобильных объектов в одном окне, но кажется, что они перезаписывают друг друга.
Вот мой переопределенный метод paintComponent в классе Car
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(wheelColor);
g2.fill(leftWheel);
g2.fill(rightWheel);
g2.setColor(bodyColor);
g2.fill(body);
g2.fill(cab);
}
И в моем классе зрителя:
JFrame f = new JFrame();
initializeFrame(f);
Car x = new Car(100, 100);
Car y = new Car(300, 300);
f.add(x);
f.add(y);
Хотя координаты кажутся разными, разрисовывается только последний автомобиль.
Какие-либо предложения? Спасибо
2 ответа
То, что вы хотите сделать, это использовать структуру данных Car
объекты и перебирать их в paintComonent
метод. Что-то вроде
List<Car> cars = new ArrayList<>();
....
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Car car : cars) {
car.drawCar(g);
}
}
drawCar
метод будет исходить из вашего Car
учебный класс
public class Car {
int x, y;
public Car(int x, int y) {
this.x = x;
this.y = y;
}
public void drawCar(Graphics g) {
g.setColor(Color.BLACK);
// do everything here as you would in a paintComponent method
}
}
Смотрите больше примеров здесь и здесь, и здесь, и здесь, и здесь, и здесь.
ОБНОВИТЬ
Вот простой пример использования некоторого "Феррари", который я выбрал, также используя некоторую анимацию, но с теми же базовыми пунктами, которые у меня были выше.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class DrawCar extends JPanel{
private static final int D_W = 400;
private static final int D_H = 400;
List<Car> cars;
public DrawCar() {
cars = new ArrayList<>();
cars.add(new Car(100, 300));
cars.add(new Car(200, 100));
Timer timer = new Timer(50, new ActionListener(){
public void actionPerformed(ActionEvent e) {
for (Car car : cars) {
car.move();
repaint();
}
}
});
timer.start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Car car : cars) {
car.drawCar(g);
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(D_W, D_H);
}
public class Car {
private static final int INCREMENT = 5;
int x, y;
public Car(int x, int y) {
this.x = x;
this.y = y;
}
public void drawCar(Graphics g) {
g.setColor(Color.BLUE);
g.fillRect(x, y, 100, 30);
g.setColor(Color.BLACK); // body
g.fillOval(x + 15, y + 20, 15, 15); // wheel
g.fillOval(x + 60, y + 20, 15, 15); // wheel
g.fillRect(x + 15, y - 20, 60, 20); // top
}
public void move() {
if (x == D_W) {
x = 0;
} else {
x += INCREMENT;
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.add(new DrawCar());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
но похоже, что они перезаписывают друг друга.
Менеджер по умолчанию для JFrame - BorderLayout. Таким образом, по умолчанию вы добавляете все свои компоненты в ЦЕНТР BorderLayout. Тем не менее, вы можете добавить в CENTER только один компонент, чтобы отображался только последний автомобиль.
Измените Layout Manager на FlowLayout, чтобы увидеть разницу.
Или, похоже, вы пытаетесь раскрасить Автомобили в случайных положениях, и в этом случае вы должны использовать "нулевую" компоновку. Тогда вы будете нести ответственность за установку размера / расположения каждого из компонентов автомобиля.