Я работаю над исполняемым Java-апплетом, который имеет функцию заливки, очень похожую на метод заливки в таких программах рисования, как Microsoft Paint.
Вот как работает мой метод заполнения:
Апплет получает цвет, на который пользователь нажал, используя .getRGB
Апплет создает двумерный логический массив всех пикселей в окне со значением "true", если этот пиксель имеет тот же цвет, что и цвет, по которому щелкнули, или "false", если нет. Смысл этого шага состоит в том, чтобы исключить метод .getRGB
из рекурсивного метода для предотвращения этой ошибки.
Апплет рекурсивно ищет двумерный массив логических значений, на котором щелкнул пользователь, и записывает каждую смежную точку, которая является «истинной» в ArrayList. Затем метод изменяет каждую записанную точку на false и продолжает.
Апплет закрашивает каждую точку, сохраненную в ArrayList
, в выбранный пользователем цвет.
Все вышеперечисленные шаги работают ОТЛИЧНО, если пользователь щелкает в пределах небольшой области, где их цвет изменился всего на несколько тысяч пикселей. Однако если пользователь выбирает большую область (например, около 360 000 / размер окна апплета), апплет переходит в рекурсивную стадию и затем выводит эту ошибку:
Exception in thread "AWT-EventQueue-1" java.lang.StackOverflowError
at java.util.ArrayList.add(ArrayList.java:351)
at paint.recursiveSearch(paint.java:185)
at paint.recursiveSearch(paint.java:190)
at paint.recursiveSearch(paint.java:190)
at paint.recursiveSearch(paint.java:190)
at paint.recursiveSearch(paint.java:190)
at paint.recursiveSearch(paint.java:190)
at paint.recursiveSearch(paint.java:190)
(continues for a few pages)
Вот мой рекурсивный код:
public void recursiveSearch(boolean [][] list, Point p){
if(isValid(p)){
if(list[(int)p.y][(int)p.x]){
fillPoints.add(p);
list[(int)p.y][(int)p.x] = false;
recursiveSearch(list, new Point(p.x-1,p.y));//Checks to the left
recursiveSearch(list, new Point(p.x,p.y-1));//Checks above
recursiveSearch(list, new Point(p.x+1,p.y));//Checks to the right
recursiveSearch(list, new Point(p.x,p.y+1));//Checks below
}
}
}
Можно ли как-то обойти такую ошибку? Я знаю, что цикл никогда не будет продолжаться вечно, просто это может занять много времени.