package bluej.editor.stride;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.IdentityHashMap;
import javafx.collections.ListChangeListener;
import bluej.stride.framedjava.frames.GreenfootFrameUtil;
import bluej.stride.generic.Frame;
import bluej.utility.Debug;
import bluej.utility.Utility;
import nu.xom.Builder;
import nu.xom.Document;
import nu.xom.Element;
import nu.xom.ParsingException;
import threadchecker.OnThread;
import threadchecker.Tag;
| The central storage (one per project) for frame shelf contents. Each GUI FXTabbedWindow
| has its own instance of FrameShelf. This class is the authoritative storage for the GUI
| shelves, and copies any changes in one shelf across to the other editor windows.
|
public class FrameShelfStorage
{
private final IdentityHashMap<FrameShelf, ListChangeListener<Frame>> shelves = new IdentityHashMap<>();
| A <frames>...</frames> XML element with the content of the shelf.
|
private Element contentXML;
private final File shelfFilename;
private boolean updatingShelves = false;
@OnThread(Tag.Any)
public FrameShelfStorage(File projectDir)
{
shelfFilename = new File(projectDir, "shelf.xml");
try
{
Document xml = new Builder().build(shelfFilename);
contentXML = xml.getRootElement();
if (!contentXML.getLocalName().equals("frames"))
{
throw new IOException("XML top-level element not \"frames\" as expected");
}
}
catch (ParsingException | IOException e)
{
contentXML = new Element("frames");
}
}
public void registerShelf(FrameShelf shelfInterface)
{
ListChangeListener<Frame> listener = c -> pullFrom(shelfInterface);
shelves.put(shelfInterface, listener);
shelfInterface.setContent(contentXML);
shelfInterface.getContent().addListener(listener);
}
public void deregisterShelf(FrameShelf shelfInterface)
{
if (shelves.get(shelfInterface) != null)
{
shelfInterface.getContent().removeListener(shelves.remove(shelfInterface));
}
}
private void pullFrom(FrameShelf changed)
{
if (updatingShelves)
{
return;
}
contentXML = GreenfootFrameUtil.getXmlElementForMultipleFrames(changed.getContent());
updatingShelves = true;
shelves.forEach((shelf, listener) -> {
if (shelf != changed)
shelf.setContent(contentXML);
});
save();
updatingShelves = false;
}
private void save()
{
try (FileOutputStream os = new FileOutputStream(shelfFilename)) {
Utility.serialiseCodeTo(contentXML, os);
}
catch (IOException e)
{
Debug.reportError("Cannot save shelf contents", e);
}
}
}
top,
use,
map,
class FrameShelfStorage
. FrameShelfStorage
. registerShelf
. deregisterShelf
. pullFrom
. save
116 neLoCode
+ 4 LoComm