📄 sketchframe.java
字号:
// Save the sketch if it is necessary
private void saveOperation() {
if(!sketchChanged)
return;
File file = modelFile;
if(file == null) {
file = showDialog("Save Sketch",
"Save",
"Save the sketch",
's',
new File(files.getCurrentDirectory(), filename));
if(file == null || (file.exists() && // Check for existence
JOptionPane.NO_OPTION == // Overwrite warning
JOptionPane.showConfirmDialog(SketchFrame.this,
file.getName()+" exists. Overwrite?",
"Confirm Save As",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE)))
return; // No selected file
}
saveSketch(file);
}
// Display a custom file save dialog
private File showDialog(String dialogTitle,
String approveButtonText,
String approveButtonTooltip,
char approveButtonMnemonic,
File file) { // Current file - if any
files.setDialogTitle(dialogTitle);
files.setApproveButtonText(approveButtonText);
files.setApproveButtonToolTipText(approveButtonTooltip);
files.setApproveButtonMnemonic(approveButtonMnemonic);
files.setFileSelectionMode(files.FILES_ONLY);
files.rescanCurrentDirectory();
files.setSelectedFile(file);
ExtensionFilter sketchFilter = new ExtensionFilter(".ske",
"Sketch files (*.ske)");
files.addChoosableFileFilter(sketchFilter); // Add the filter
files.setFileFilter(sketchFilter); // and select it
int result = files.showDialog(SketchFrame.this, null); // Show the dialog
return (result == files.APPROVE_OPTION) ? files.getSelectedFile() : null;
}
// Retrieve the pop-up menu
public JPopupMenu getPopup() {
return popup;
}
private JButton addToolBarButton(Action action) {
JButton button = toolBar.add(action); // Add toolbar button
button.setBorder(BorderFactory.createRaisedBevelBorder());// Add button border
return button;
}
// Method to save the current sketch as an XML document
private void saveXMLSketch(File outFile) {
FileOutputStream outputFile = null; // Stores an output stream reference
try {
outputFile = new FileOutputStream(outFile); // Output stream for the file
FileChannel outChannel = outputFile.getChannel(); // Channel for file stream
writeXMLFile(theApp.getModel().createDocument(), outChannel);
} catch(FileNotFoundException e) {
e.printStackTrace(System.err);
JOptionPane.showMessageDialog(SketchFrame.this,
"Sketch file " + outFile.getAbsolutePath() + " not found.",
"File Output Error",
JOptionPane.ERROR_MESSAGE);
return; // Serious error - return
}
}
// Method to write the XML file for the current sketch (helper for saveXMLSketch())
private void writeXMLFile(org.w3c.dom.Document doc, FileChannel channel) {
StringBuffer xmlDoc = new StringBuffer(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
xmlDoc.append(NEWLINE).append(getDoctypeString(doc.getDoctype()));
xmlDoc.append(getDocumentNode(doc.getDocumentElement(), ""));
try {
channel.write(ByteBuffer.wrap(xmlDoc.toString().getBytes("UTF-8")));
} catch(UnsupportedEncodingException e) {
System.out.println(e.getMessage());
} catch(IOException e) {
JOptionPane.showMessageDialog(SketchFrame.this,
"Error writing XML to channel.",
"File Output Error",
JOptionPane.ERROR_MESSAGE);
e.printStackTrace(System.err);
return;
}
}
private String getDoctypeString(org.w3c.dom.DocumentType doctype) {
// Create the opening string for the DOCTYPE declaration with its name
String str = doctype.getName();
StringBuffer doctypeStr = new StringBuffer("<!DOCTYPE ").append(str);
// Check for a system ID
if((str = doctype.getSystemId()) != null)
doctypeStr.append(" SYSTEM ").append(QUOTE).append(str).append(QUOTE);
// Check for a public ID
if((str = doctype.getPublicId()) != null)
doctypeStr.append(" PUBLIC ").append(QUOTE).append(str).append(QUOTE);
// Check for an internal subset
if((str = doctype.getInternalSubset()) != null)
doctypeStr.append('[').append(str).append(']');
return doctypeStr.append(TAG_END).toString(); // Append '>' & return string
}
private String getDocumentNode(Node node, String indent) {
StringBuffer nodeStr = new StringBuffer().append(NEWLINE).append(indent);
String nodeName = node.getNodeName(); // Get name of this node
switch(node.getNodeType()) {
case Node.ELEMENT_NODE:
nodeStr.append(TAG_START);
nodeStr.append(nodeName);
if(node.hasAttributes()) { // If the element has attributes...
org.w3c.dom.NamedNodeMap attrs = node.getAttributes(); // ...get them
for(int i = 0 ; i<attrs.getLength() ; i++) {
org.w3c.dom.Attr attribute = (org.w3c.dom.Attr)attrs.item(i);
// Append " name="value" to the element string
nodeStr.append(' ').append(attribute.getName()).append('=')
.append(QUOTE).append(attribute.getValue()).append(QUOTE);
}
}
if(!node.hasChildNodes()) { // Check for no children for this element
nodeStr.append(EMPTY_TAG_END); // There are none-close as empty element
return nodeStr.toString(); // and return the completed element
} else { // It has children
nodeStr.append(TAG_END); // so close start-tag
NodeList list = node.getChildNodes(); // Get the list of child nodes
assert list.getLength()>0; // There must be at least one
// Append child nodes and their children...
for(int i = 0 ; i<list.getLength() ; i++)
nodeStr.append(getDocumentNode(list.item(i), indent+" "));
}
nodeStr.append(NEWLINE).append(indent).append(END_TAG_START)
.append(nodeName).append(TAG_END);
break;
case Node.TEXT_NODE:
nodeStr.append(replaceQuotes(((org.w3c.dom.Text)node).getData()));
break;
default:
assert false;
}
return nodeStr.toString();
}
public String replaceQuotes(String str) {
StringBuffer buf = new StringBuffer();
for(int i = 0 ; i<str.length() ; i++)
if(str.charAt(i)==QUOTE)
buf.append(QUOTE_ENTITY);
else
buf.append(str.charAt(i));
return buf.toString();
}
// Uses a SAX parser to open an XML sketch file
private void openXMLSketch(File xmlFile) {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser parser = null;
spf.setNamespaceAware(true);
spf.setValidating(true);
try {
parser = spf.newSAXParser();
} catch(SAXException e) {
e.printStackTrace(System.err);
System.exit(1);
} catch(ParserConfigurationException e) {
e.printStackTrace(System.err);
System.exit(1);
}
SAXElementHandler handler = new SAXElementHandler();
try {
parser.parse(xmlFile, handler);
} catch(IOException e) {
e.printStackTrace(System.err);
}
catch(SAXException e) {
e.printStackTrace(System.err);
}
checkForSave();
filename = xmlFile.getName(); // Update the file name
setTitle(frameTitle+xmlFile.getPath()); // Change the window title
sketchChanged = false; // Status is unchanged
}
// Method to create a SketchModel object from an XML Document object
private SketchModel createSketchModel(org.w3c.dom.Document doc) {
SketchModel model = new SketchModel(); // The new model object
// Get the first child of the root node
org.w3c.dom.Node node = doc.getDocumentElement().getFirstChild();
// Starting with the first child, check out each child in turn
while (node != null) {
assert node instanceof org.w3c.dom.Element; // Should all be Elements
String name = ((org.w3c.dom.Element)node).getTagName(); // Get the name
if(name.equals("line")) // Check for a line
model.add(new Element.Line((org.w3c.dom.Element)node));
else if(name.equals("rectangle")) // Check for a rectangle
model.add(new Element.Rectangle((org.w3c.dom.Element)node));
else if(name.equals("circle")) // Check for a circle
model.add(new Element.Circle((org.w3c.dom.Element)node));
else if(name.equals("curve")) // Check for a curve
model.add(new Element.Curve((org.w3c.dom.Element)node));
else if(name.equals("text")) // Check for a text
model.add(new Element.Text((org.w3c.dom.Element)node));
node = node.getNextSibling(); // Next child node
}
return model;
}
// Defines a handler for SAX events when parsing an XML sketch
/*
At the start of a document we create an empty model. Data for Sketcher elements
is recorded in the startElement() callback method and the element is ultimately
created in the endElement() callback and added to the model. The model is inserted
into the Sketcher application in the endDocument() callback method.
*/
class SAXElementHandler extends DefaultHandler {
public void startDocument() {
xmlSketch = new SketchModel(); // Create the new model
}
public void endDocument() {
theApp.insertModel(xmlSketch); // Insert the new model
}
// This method will recognize an XML element and save any attributes it has
// in a form to be used when the sketch element is created in the endElement() method
public void startElement(String uri, String localName, String qname,
Attributes attr) {
// Determine what kind of element we have by comparing localName
// with known element names.
if(localName.equals("line")) {
// Should be one attribute - the angle
angle = Double.parseDouble(attr.getValue("angle"));
elementType = LINE;
} else if(localName.equals("position")) {
position = getPoint(attr, localName);
} else if(localName.equals("endpoint")) {
endPoint = getPoint(attr,localName);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -