Индекс массива Out of Bounds Исключение без дополнительной информации. Нет номера строки, нет класса, только исключение - PullRequest
0 голосов
/ 08 января 2019

Множество ответов об этом исключении, но, честно говоря, я понимаю причину и способы ее устранения, но не могу найти основную причину, поэтому, пожалуйста, прочитайте, прежде чем предположить, что это дубликат. Заранее спасибо.

Как сказано в документации:

https://docs.oracle.com/javase/6/docs/api/java/lang/ArrayIndexOutOfBoundsException.html

ArrayIndexOutOfBoundsException - " Брошенный, чтобы указать, что к массиву обращались с недопустимым индексом. Индекс или отрицателен или больше или равен размеру массива. "

Это довольно очевидно, однако я получаю это исключение без дополнительной информации. Без имени класса, без номера строки, только исключение.

Exception in thread "JavaFX Application Thread" java.lang.ArrayIndexOutOfBoundsException

ArrayIndexOutOfBoundsException

Это просто циклы и циклы, пока я не убью программу.

Я более чем рад начать пытаться показать кусочки кода, чтобы привести полностью проверяемый пример и т. Д. Однако ...

Мой вопрос на данном этапе:

Можно ли как-то убедиться, что все мои исключения будут напечатаны на выходе с соответствующими номерами строк?

Некоторые вещи, которые я уже пробовал:

  • Попробовать ловить подозрительные циклы, присвоения массивов и т. Д. Безрезультатно.

  • Попытка настроить обработку ошибок в приложении (используя принятый здесь ответ: Общая обработка исключений в JavaFX 8 ), но когда я повторил ошибку, я получил еще меньше информации.

Дополнительная информация о выпуске:

  • Массив создан на основе документа PDF. Количество страниц в этом документе подсчитывается, а массиву присваивается количество страниц в виде его длины. Затем устанавливается каждая страница, используя номер страницы - 1 (который начинается с 0 и, например, увеличивается до 200 при наличии 201 страницы.

  • Этот массив затем используется для отображения того же количества панелей, что и страниц на вкладке в области прокрутки. Как только они созданы, эта функциональность больше никогда не запускается.

  • Сначала все отлично работает.

  • При прокрутке вверх и вниз на панели добавляется буферизованное изображение страницы, добавляемое к графическому изображению метки. Все это работает нормально, прокрутка вверх, прокрутка вниз, перетаскивание большого пальца и т. Д.

  • Тем не менее, при увеличении и уменьшении (в основном изменяя размеры панелей, созданных каждым элементом массива), после нескольких (более 15/20) нажатий кнопок для этого, что вызывает те же функции, что и при прокручивая вверх и вниз после изменения размеров панелей, в конце концов я получаю это исключение.

  • Итак, изначально все работает, весь массив создан, в нем есть определенное количество элементов, я вижу, что он работает при прокрутке вверх и вниз, я вижу, что количество страниц и число циклов в компонентах в foreach (например, for(Node n: parentNode.getChildrenUnmodifiable()){}) совпадает с ожидаемым.

  • В этом цикле я специально получаю элементы из массива, используя номер страницы - 1, как он был создан. Это никогда не выходит за пределы длины массива и никогда не равно -1 (так как начинается с 1, поэтому первая итерация равна 0).

  • Перед использованием или назначением массивов .. Я проверяю, что:

if ((array.length > 0) && (array.length == numberOfPagesInDocument) && (counter < numberOfPagesInDocument)) {}

  • Это гарантирует, что в массиве есть элементы, и что длина равна количеству страниц в документе, так как размер массива всегда должен быть равен количеству страниц в документе, и, очевидно, работает до тех пор, пока я не спамю много раз кнопки увеличения или уменьшения.

  • Это единственный массив, который используется в приложении на данный момент, другие уже были созданы, использованы, и там все функции еще не запущены, но я изо всех сил пытаюсь понять, как это может быть вызывая ошибку.

  • Небольшая часть меня чувствует, как на отдельных нитях при вызове увеличения и т. Д. Или прокрутки и т. Д., Что слишком много нитей портят горшок, но это лишь предположение, что я немного цепляюсь за соломинку .

Буду признателен за любую помощь и заранее, и если все будут в растерянности, я постараюсь предоставить дополнительную информацию и примеры кода.

Edit:

У меня проблема с:

Bounds childBounds = child.localToScene(child.getBoundsInLocal());

The task failed with the following exception:
java.lang.ArrayIndexOutOfBoundsException: -1
    at java.util.ArrayList.elementData(ArrayList.java:422)
    at java.util.ArrayList.get(ArrayList.java:435)
    at com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89)
    at com.sun.javafx.collections.VetoableListDecorator.get(VetoableListDecorator.java:306)
    at javafx.scene.Parent.updateCachedBounds(Parent.java:1591)
    at javafx.scene.Parent.recomputeBounds(Parent.java:1535)
    at javafx.scene.Parent.impl_computeGeomBounds(Parent.java:1388)
    at javafx.scene.layout.Region.impl_computeGeomBounds(Region.java:3078)
    at javafx.scene.Node.updateGeomBounds(Node.java:3577)
    at javafx.scene.Node.getGeomBounds(Node.java:3530)
    at javafx.scene.Node.getLocalBounds(Node.java:3478)
    at javafx.scene.Node$MiscProperties$2.computeBounds(Node.java:6472)
    at javafx.scene.Node$LazyBoundsProperty.get(Node.java:9306)
    at javafx.scene.Node$LazyBoundsProperty.get(Node.java:9276)
    at javafx.scene.Node.getBoundsInLocal(Node.java:3156)
    at tdiesfxml.Utility$3.call(Utility.java:252)
    at tdiesfxml.Utility$3.call(Utility.java:235)
    at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.lang.Thread.run(Thread.java:748)

Хотя это Bounds, поэтому немного озадачен тем, почему это вызывает исключение, которое я получаю.

Я сейчас исследую эту проблему, не знаю, что делать с этими вопросами, поскольку она немного развивается, но я добавлю свои выводы здесь, и если у кого-то есть идея, почему Bounds выдает это исключение, я был бы очень признателен.

1 Ответ

0 голосов
/ 08 января 2019

На основании этой трассировки стека проблема заключается в том, что вы обращаетесь к графическому интерфейсу и / или изменяете его из фонового потока.

java.lang.ArrayIndexOutOfBoundsException: -1
    at java.util.ArrayList.elementData(ArrayList.java:422)
    at java.util.ArrayList.get(ArrayList.java:435)
    at com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89)
    at com.sun.javafx.collections.VetoableListDecorator.get(VetoableListDecorator.java:306)
    at javafx.scene.Parent.updateCachedBounds(Parent.java:1591)
    at javafx.scene.Parent.recomputeBounds(Parent.java:1535)
    at javafx.scene.Parent.impl_computeGeomBounds(Parent.java:1388)
    at javafx.scene.layout.Region.impl_computeGeomBounds(Region.java:3078)
    at javafx.scene.Node.updateGeomBounds(Node.java:3577)
    at javafx.scene.Node.getGeomBounds(Node.java:3530)
    at javafx.scene.Node.getLocalBounds(Node.java:3478)
    at javafx.scene.Node$MiscProperties$2.computeBounds(Node.java:6472)
    at javafx.scene.Node$LazyBoundsProperty.get(Node.java:9306)
    at javafx.scene.Node$LazyBoundsProperty.get(Node.java:9276)
    at javafx.scene.Node.getBoundsInLocal(Node.java:3156)
    at tdiesfxml.Utility$3.call(Utility.java:252)               // HERE
    at tdiesfxml.Utility$3.call(Utility.java:235)               // HERE
    at javafx.concurrent.Task$TaskCallable.call(Task.java:1423) // HERE
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) // HERE
    at java.lang.Thread.run(Thread.java:748)                   

Строки, отмеченные // HERE, указывают, что код является реализацией javafx.concurrent.Task. Внутри call метода этого Task вы вызываете Node.getBoundsLocal, который показывает вам доступ к GUI из класса, предназначенного в основном для фонового выполнения.

JavaFX, как и большинство инструментов UI, является однопоточным. Вы никогда не должны взаимодействовать с живым графом сцены в фоновом потоке; вы должны быть в потоке приложений JavaFX . Если вам нужна информация из пользовательского интерфейса в фоновом потоке, вы можете использовать Platform.runLater с чем-то вроде CompletableFuture (см. этот вопрос ).

...