UPDATE: добавлен таймер на основе визуализации для отображения строк по одному в конце этого ответа.
Во-первых, я рекомендую @Overriding paintComponent()
вместо paint()
.
Во-вторых, чтобы нарисовать Polygon
, заполните Polygon
, вы буквально просто складываете команды, так как контекст Graphics
будет нарисовать на заказ.
for(int j = 0; j < polygons.size(); j++) {
ArrayList<Integer> listX = new ArrayList<>();
ArrayList<Integer> listY = new ArrayList<>();
for (int p = 0; p < polygons.get(j).size(); p++) {
listX.add(polygons.get(j).get(p).x);
listY.add(polygons.get(j).get(p).y);
}
// this may need slight conversion depending on parameters required
g.drawPolygon(convertIntegers(listX), convertIntegers(listY), polygons.get(j).size());
g.fillPolygon(convertIntegers(listX), convertIntegers(listY), polygons.get(j).size());
}
Если переопределить paintComponent()
для выбранного объекта (я обычно использую JPanel
для пользовательских живописи) все, что вам тогда нужно сделать, это перекрасить вызов(), чтобы обновить представление (не то, что вы должны нуждаться в данном случае) ,
Напомним, переопределить paintComponent()
на JPanel
, стек вашего drawPolygon
/fillPolygon
вызовы и если вы хотите, чтобы контролировать, когда отображается ваш многоугольник, обрабатывать, что путем добавления/удаления JPanel
по мере необходимости из вашего приложения. Или установите флаг boolean
, указывающий «toBeDrawn» или нет, и измените свой код paintComponent
так, чтобы он рисовал только полигоны, если для этого параметра установлено значение true.
ОБНОВЛЕНИЕ: Пример работоспособный класс ниже продемонстрировал Таймер на основе drawLine()
функциональности.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Test extends JPanel {
private static final long serialVersionUID = 1L;
private Timer lineTimer;
private Polygon toBeFilled;
private ArrayList<Point[]> inactiveLines;
private ArrayList<Point[]> activeLines;
private boolean toBeDrawn = false;
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
frame.getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
Test test = new Test();
frame.add(test);
frame.pack();
frame.setVisible(true);
test.getLineTimer().start();
}
public Test() {
super();
setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
setPreferredSize(new Dimension(480, 340));
setBackground(Color.BLACK);
int midpointX = getPreferredSize().width/2;
int midpointY = getPreferredSize().height/2;
int lineWidth = 20;
// let's make a square
toBeFilled = new Polygon();
// let's centre this square nicely
toBeFilled.addPoint(midpointX - (lineWidth/2), midpointY - (lineWidth/2)); // top-left
toBeFilled.addPoint(midpointX + (lineWidth/2), midpointY - (lineWidth/2)); // top-right
toBeFilled.addPoint(midpointX + (lineWidth/2), midpointY + (lineWidth/2)); // bottom-right
toBeFilled.addPoint(midpointX - (lineWidth/2), midpointY + (lineWidth/2)); // bottom-left
inactiveLines = new ArrayList<Point[]>();
activeLines = new ArrayList<Point[]>();
for(int n = 0; n < 4; n++) {
Point[] points = new Point[2];
if(n < 3) {
points[0] = new Point(toBeFilled.xpoints[n], toBeFilled.ypoints[n]);
points[1] = new Point(toBeFilled.xpoints[n + 1], toBeFilled.ypoints[n + 1]);
} else {
// loop back to the first point in the array
points[0] = new Point(toBeFilled.xpoints[n], toBeFilled.ypoints[n]);
points[1] = new Point(toBeFilled.xpoints[0], toBeFilled.ypoints[0]);
}
inactiveLines.add(points);
}
ActionListener lineAction = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(inactiveLines.get(inactiveLines.size() - 1) != null) {
int count = 0;
for(Point[] pArray : inactiveLines) {
if(pArray != null) {
activeLines.add(new Point[] { pArray[0], pArray[1] });
inactiveLines.set(count, null);
repaint();
break;
}
count++;
}
} else {
// we've exhausted the line array, so now it's time to fill it
toBeDrawn = true;
lineTimer.stop();
repaint();
}
}
};
lineTimer = new Timer(1000, lineAction);
}
@Override
public void paintComponent(Graphics g) {
// useful for animation
Toolkit.getDefaultToolkit().sync();
super.paintComponent(g);
if(toBeDrawn) {
doFillPainting(g);
} else {
doLinePainting(g);
}
}
private void doFillPainting(Graphics g) {
// Graphics2D is more advanced than the older Graphics API, and more reliable
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.WHITE);
if(toBeFilled != null) {
g2d.fillPolygon(toBeFilled);
}
}
private void doLinePainting(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.WHITE);
for(Point[] activeLine : activeLines) {
g2d.drawLine(activeLine[0].x, activeLine[0].y, activeLine[1].x, activeLine[1].y);
}
}
public Timer getLineTimer() {
return lineTimer;
}
public void setLineTimer(Timer lineTimer) {
this.lineTimer = lineTimer;
}
public Polygon getToBeFilled() {
return toBeFilled;
}
public void setToBeFilled(Polygon toBeFilled) {
this.toBeFilled = toBeFilled;
}
public boolean isToBeDrawn() {
return toBeDrawn;
}
public void setToBeDrawn(boolean toBeDrawn) {
this.toBeDrawn = toBeDrawn;
}
}
спасибо, но я хочу нарисовать многоугольник построчно, а не все сразу. – user5274714
Итак, перед логикой 'fillPolygon()' поставить логику 'drawLine()' в том же цикле. Любой набор заказов на тиражирование выполняется в том порядке, в котором они написаны (и это не дорогостоящие операции, поэтому не должно быть задержки). – Gorbles
Обновлен мой ответ! :) – Gorbles