Слушатели и валидация / перекраска
Так что у меня есть эта проблема. У меня есть программа, которая создает и загружает файлы.
Когда я загружаю файл в свою программу, я полагаюсь на слушателя компонента, который сообщает мне, когда конкретный компонент "заполнен", а затем перемещает все компоненты в соответствии с этим.
Я добавляю каждый компонент сверху, а затем регистрирую слушателя, когда родительский компонент "заполняется", и перемещает нижний компонент в новый родительский элемент, который он также создает. Думайте об этом, как о добавлении новой строки текста в начале документа MSWord со страничной страницей.
Этот слушатель также полагается на настройку графического интерфейса - если все в памяти не отображается на экране, он захватывает неправильные высоты компонентов (обычно равные 0) и использует их в своих вычислениях, которые затем оказываются неверными, и все портится.
Вот схема этой части моей программы:
(все происходит на JPanel в JFrame)
trigger opening method:
{
repeat this x (lets say e.g. 100) times:
{
trigger addComponent method
{
add component
{
adding component triggers the component listner 8if there is no more room in parent)
{
move all of the components one place down, move the ones out of bounds to next "page"
repaint and revalidate whole JFrame (inside listener)
}
}
repaint and revalidate whole JFrame (part of addComponent method)
}
repaint and revalidate whole JFrame(part of opening methid, after component addition)
}
repaint and revalidate whole JFrame (as a part of opening method, final repaint/validate)
}
Причиной этого может быть перерисовка / проверка в том, что метод addComponent, так же как и слушатель, имеет другие функции и вызывается в других местах, где это единственное (оптимальное) место для перерисовки / проверки.
Проблема в том, что JFrame не перерисовывается до самого последнего (последнего) вызова проверки / перерисовки в методе opeoning. Я попытался добавить Thread.sleep(1000) в несколько мест в коде (после проверки / перекраски), чтобы доказать это.
Кроме того, насколько я знаю, когда компонентный прослушиватель запускается, он останавливается на строке, которая его инициировала, затем выполняет сам, а затем продолжает с этой строки, верно?
Как это исправить? Как заставить мою программу перерисовывать / проверять после добавления каждого нового компонента и еще раз после того, как слушатель сделал свою работу?
Ответьте на первые два комментария: во-первых, Thread.sleep(1000) предназначался только для диагностики проблемы. Прямо перед тем, как метод Thread.sleep(1000) был перерисован / валидирован, поэтому я подумал, что если я приостановлю программу сразу после вызова reapint(), то после каждой паузы будет перекрашиваться графический интерфейс, и я буду видеть добавленный новый элемент, который не был дело.
Во-вторых, что касается длительных вычислений, эти вычисления не такие длинные (выполнение этого с 20 компонентами дает мгновенные результаты, но не те, которые желательны). Кроме того, эти вычисления требуют удаления и добавления компонентов в GUI довольно часто (каждые 10-20 строк), поэтому включение SwingWorker в это практически невозможно и не требуется.
В-третьих, я думаю, что вы пропустили весь смысл. Длительность выполнения здесь не является реальной проблемой и не зависает в графическом интерфейсе (что на самом деле не происходит, в любом случае, недостаточно долго, чтобы его можно было заметить). Проблема в том, что repaint/validate вызывался в цикле всего 3-4 раза для каждого компонента (приблизительно 60-80 раз, если я открываю файл с 20 компонентами), и единственный раз, когда я видел его выполнение, это когда последний раз, когда он был вызван, после цикла...
Я даже поместил метод System.out.println("что-то") прямо перед и сразу после перерисовки / проверки. Он напечатал "что-то" дважды, но перекрасить / проверить никогда не происходило.
1 ответ
Я вижу любую проблему с
add
/remov
е /modify
Компоненты в контейнере (JFrame
->JPanel
е)зависит, если контейнер (
JPanel
еи) находится вJScrollPane
зависит, если вам нужно позвонить
pack()
послеadd
/remov
е /modify
JComponent
s в контейнере, а затем изменить размерJFram
е (например) на экране