Синхронизация jPanel's
Я пытаюсь смоделировать рой дронов с помощью Java Swing.
Полет беспилотника как рой, отслеживая ИК-точки.
Каждый класс членов роя расширяет jPanel и переопределяет функцию рисования, роль которой состоит в том, чтобы рисовать ИК-точки на своей панели в соответствии с позицией лидеров.
@Override
public void paint(Graphics g) {
super.paint(g);
for (int x = currX_1 - currIRdim; x < currX_1 + currIRdim; x++) {
for (int y = currY_1 - currIRdim; y < currY_1 + currIRdim; y++) {
g.setColor(Color.RED);
g.drawLine(x, y, x, y);
}
}
for (int x = currX_2 - currIRdim; x < currX_2 + currIRdim; x++) {
for (int y = currY_2 - currIRdim; y < currY_2 + currIRdim; y++) {
g.setColor(Color.RED);
g.drawLine(x, y, x, y);
}
}
}
лидер роя и беспилотник рядом с ним обновляют панели следующих участников при каждом движении
private void updateFollowers(AgentIrPanel[] screensToUpdate, String command) {
int xdiff = screensToUpdate[0].getDiffX();
int dimdiff = screensToUpdate[0].getDiffDim();
switch (behaviour) {
case SWARM_LEADER:
screensToUpdate[0].setCurrX_1(screensToUpdate[0].getCurrX_1() + xdiff);
screensToUpdate[0].setCurrX_2(screensToUpdate[0].getCurrX_2() + xdiff);
screensToUpdate[0].repaintPoints(); // call jpanel.repaint()
screensToUpdate[1].setCurrIRdim(screensToUpdate[1].getCurrIRdim() - dimdiff);
screensToUpdate[1].repaintPoints();
break;
case FOLLOW_LEFT:
screensToUpdate[0].setCurrIRdim(screensToUpdate[0].getCurrIRdim() - dimdiff);
screensToUpdate[0].repaintPoints();
}
}
следующие участники получают на свои панели 2 точки IR и, распознав отличия от предыдущих точек, решают, в каком направлении им следует двигаться
private String secRowReading() {
BufferedImage img = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = img.createGraphics();
this.paint(g2);
if ((new Color(img.getRGB(X_1 - IRdim ,Y_1 - IRdim)).equals(Color.BLACK))
&& (new Color(img.getRGB(X_2 - IRdim ,Y_2 - IRdim)).equals(Color.BLACK))
&& (new Color(img.getRGB(X_1 - IRdim + diffX, Y_1 - IRdim)).equals(Color.RED))
&& (new Color(img.getRGB(X_2 - IRdim + diffX, Y_1 - IRdim)).equals(Color.RED))){
ans = "right";
}else if ((new Color(img.getRGB(X_1 - IRdim ,Y_1 - IRdim)).equals(Color.BLACK))
&& (new Color(img.getRGB(X_2 - IRdim ,Y_2 - IRdim)).equals(Color.BLACK))
&& (new Color(img.getRGB(X_1 - IRdim - diffX, Y_1 - IRdim)).equals(Color.RED))
&& (new Color(img.getRGB(X_2 - IRdim - diffX, Y_1 - IRdim)).equals(Color.RED))){
ans = "left";
}else if ((new Color(img.getRGB(X_1 - IRdim ,Y_1 - IRdim)).equals(Color.BLACK))
&& (new Color(img.getRGB(X_2 - IRdim,Y_2 - IRdim)).equals(Color.BLACK))
&& (new Color(img.getRGB(X_1 - IRdim + diffDim ,Y_1 - IRdim + diffDim)).equals(Color.RED))
&& (new Color(img.getRGB(X_2 - IRdim + diffDim ,Y_2 - IRdim + diffDim)).equals(Color.RED))) {
ans = "front";
}else if ((new Color(img.getRGB(X_1 - IRdim - diffDim,Y_1 - IRdim -diffDim)).equals(Color.RED))
&& (new Color(img.getRGB(X_2 - IRdim - diffDim,Y_2 - IRdim -diffDim)).equals(Color.RED))){
ans = "back";
}else {
ans = "stop";
}
g2.dispose();
return ans;
}
проблема в том, что следующие дроны не справляются с этим чтением вместе, только когда они работают отдельно. Во время полета один из последователей не распознает вовремя изменения, которые применяет к нему лидер, и останавливается, что портит весь полет.
Я пытался отложить чтение каждого последующего дрона с помощью расписания Timer()., Но безуспешно. как синхронизировать это, чтобы работать должным образом?
1 ответ
Каждый класс членов роя расширяет jPanel и переопределяет функцию рисования, роль которой состоит в том, чтобы рисовать ИК-точки на своей панели в соответствии с позицией лидеров.
И вот проблема. Не делай этого. Не заставляйте свои спрайты расширять класс "более тяжелого веса", чем это необходимо, и это без необходимости усложняет вашу программу. Вместо этого ваши спрайты должны быть некомпонентными классами, то есть не расширять какой-либо тип компонента Swing или AWT, а вместо этого рисовать их внутри одного чертежа JPanel, чей метод paintComponent был переопределен, а чей super.paintComponent(g)
был вызван.
Я бы дал класс Swarm public void draw(Graphics2D g2)
метод, создать коллекцию из них, возможно, List<Swarm>
и затем в методе paintComponent выполните итерацию по списку, передавая объект Graphics2D, полученный из JVM, рисуя каждый объект sprite/swarm.
Другие проблемы: не забудьте извлечь поведение и логику ваших объектов Swarm из кода GUI. Логический код должен быть частью модели вашей программы, а не частью представления (GUI), задачей которого является отображение состояния модели и предоставление пользователю возможности взаимодействовать с моделью (через контроллер).