public void movingElements() { //gets the new filler height to compare int newFillerHeight = getFiller().getHeight(); //chapter contains an array of pages I need to deal with here Chapter chapter = getChapter(); //element removed/shrunk //compares the oldFillerHeight which contains the height of the filler //prior to this particular resizing else if (newFillerHeight >= oldFillerHeight) { //fetches the next and previous page of this page (getPage() //returns page we are dealing with) Page previousPage = chapter.getPreviousPage(getPage()); Page nextPage = chapter.getNextPage(getPage()); //here is where it gets tricky //I didn't want to check if first (few) element(s) can be //moved to previous page (which can happen if the first, large //element followed by several small ones is removed) (CHECK A) AND //if any elements on the next page can be moved to this one //(CHECK B). What I did instead was to always do the CHECK A. //if this is the first page of the chapter, I cannot perform the //CHECK A if (previousPage == null) { //I have to invoke this method on the next page, if it //exists. If it doesn't, then this is the only page of //the chapter and I have nothing to do here. if (nextPage != null) { //this is explained bellow this method nextPage.dummy.setVisible(true); } } //if previous page exists, we preform CHECK A else { Element mover = getElement(1); //I have to check if the first element on this page fits //onto the free space of the previous one //-2 is required to prevent infinite loops if (mover.getHeight() < previousPage.getFiller().getHeight()-2) { //I move the element removeElement(mover); previousPage.addElement(mover, previousPage.getElementCount()+1); //This is a flag that tells that an object was //moved, you'll se why I need it soon enough chapter.setMoved(true); } //If I can't move the object, I have move onto the next //page (if it exists) and repeat the process. I also //check for isMoved flag because maybe nothing was moved //on the previous page and there is no need to keep the //this chain of execution going else if ((nextPage != null) && (chapter.isMoved())) { //sets isMoved flag to false so the above code //would work chapter.setMoved(false); nextPage.dummy.setVisible(true); } } } //saves the new filer height for further use oldFillerHeight = newFillerHeight; } dummy = new JPanel(); dummy.setVisible(false); dummy.addComponentListener(new ComponentAdapter() { @Override public void componentShown(ComponentEvent arg0) { dummy.setVisible(false); movingElements(); } }); filler.addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent arg0) { if (!getChapter().isChaining()) { getChapter().setChaining(true); movingElements(); } oldFillerHeight = getFiller().getHeight(); } }); dummy.addComponentListener(new ComponentAdapter() { @Override public void componentShown(ComponentEvent arg0) { dummy.setVisible(false); movingElements(); } }); public void movingElements() { int newFillerHeight = getFiller().getHeight(); Document document = getDocument(); Chapter chapter = getChapter(); //element added/enlarged if (newFillerHeight == 0) { Page nextPage = chapter.getNextPage(getPage()); if (nextPage == null) { nextPage = new Page(); chapter.addPage(nextPage, chapter.getPageIndex(getPage())+1); } Element mover = getPage().getElement(getPage().getElementCount()); removeElement(mover); nextPage.addElement(mover, 1); getPage().dummy.setVisible(true); } //element removed/shrunk else if (newFillerHeight >= oldFillerHeight) { Page previousPage = chapter.getPreviousPage(getPage()); Page nextPage = chapter.getNextPage(getPage()); if (previousPage == null) { if (nextPage != null) { nextPage.dummy.setVisible(true); } else { //chain end chapter.setChaining(false); } } else { Element mover = getElement(1); if (mover.getHeight() < previousPage.getFiller().getHeight()-2) //-2 is required to prevent infinite loops { removeElement(mover); previousPage.addElement(mover, previousPage.getElementCount()+1); chapter.setMoved(true); getPage().dummy.setVisible(true); } else if ((nextPage != null) && (chapter.isMoved())) { nextPage.dummy.setVisible(true); } else { //chain end chapter.setChaining(false); } } } else { //chain end chapter.setChaining(false); } } private AtomicBoolean chaining= new AtomicBoolean(false); public boolean isChaining() { return chaining.get(); } public void setChaining(boolean chaining) { this.chaining.set(chaining); }