无聊之作,只是从布局文件中提取出定义了android:id属性的控件名称,方便在编写class文件的时候能够跟layout文件保持一致。
原理很简单,直接上代码:
1、swing主界面代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.zhyy.layoutparser; 2 3 import javax.swing.*; 4 import java.awt.*; 5 import java.awt.datatransfer.Clipboard; 6 import java.awt.datatransfer.StringSelection; 7 import java.awt.event.ActionEvent; 8 import java.awt.event.ActionListener; 9 import java.awt.event.WindowAdapter; 10 import java.awt.event.WindowEvent; 11 import java.io.File; 12 import java.util.*; 13 14 /** 15 * Created by Administrator on 2014/7/30. 16 */ 17 public class Main implements ActionListener{ 18 private static int FRM_WIDTH = 400; 19 private static int FRM_HEIGHT = 400; 20 private JFrame jFrame; 21 private JButton btnFile; 22 private ButtonGroup rgTab; 23 private JRadioButton rbDefault; 24 private JRadioButton rbAA; 25 private DropDragTextArea textArea; 26 private JButton btnCopy; 27 private JButton btnCopyAll; 28 29 private static File srcFile; 30 public Main() { 31 32 jFrame = new JFrame("MyLayoutParser"); 33 Container container = jFrame.getContentPane(); 34 35 btnFile = new JButton("OpenFile"); 36 btnFile.addActionListener(this); 37 38 rbAA = new JRadioButton("AA"); 39 rbDefault = new JRadioButton("Default"); 40 rbAA.setSelected(true); 41 rgTab = new ButtonGroup(); 42 rgTab.add(rbAA); 43 rgTab.add(rbDefault); 44 45 JLabel label1 = new JLabel("Process type:"); 46 JPanel panel1 = new JPanel(new FlowLayout()); 47 panel1.add(label1); 48 panel1.add(rbAA); 49 panel1.add(rbDefault); 50 panel1.add(btnFile); 51 52 textArea = new DropDragTextArea(); 53 textArea.setGetDropFileListener(new DropDragTextArea.GetDropFileListener() { 54 @Override 55 public void getDropFile(File file) { 56 if (file == null || file.isDirectory() || !file.getName().endsWith(".xml")) { 57 JOptionPane.showMessageDialog(jFrame, "only support xml file!"); 58 return; 59 } 60 printResult(file); 61 } 62 }); 63 textArea.setLineWrap(true); 64 JScrollPane pane2 = new JScrollPane(textArea); 65 66 btnCopy = new JButton("Copy"); 67 btnCopy.addActionListener(this); 68 69 btnCopyAll = new JButton("Copy All"); 70 btnCopyAll.addActionListener(this); 71 JPanel panel2 = new JPanel(new FlowLayout()); 72 panel2.add(btnCopy); 73 panel2.add(btnCopyAll); 74 75 container.add(panel1, BorderLayout.NORTH); 76 container.add(pane2, BorderLayout.CENTER); 77 container.add(panel2, BorderLayout.SOUTH); 78 79 invokeFrm(jFrame); 80 81 } 82 public static void main(String args[]) { 83 84 new Main(); 85 } 86 87 public static void invokeFrm(final JFrame jFrame) { 88 SwingUtilities.invokeLater(new Runnable() { 89 @Override 90 public void run() { 91 Toolkit toolkit = Toolkit.getDefaultToolkit(); 92 Dimension dimension = toolkit.getScreenSize(); 93 jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 94 //显示在屏幕中间 95 jFrame.setLocation((dimension.width - FRM_WIDTH) / 2, (dimension.height - FRM_HEIGHT) / 2); 96 jFrame.setSize(FRM_WIDTH, FRM_HEIGHT); 97 jFrame.setMinimumSize(new Dimension(FRM_WIDTH, FRM_HEIGHT)); 98 jFrame.addWindowListener(new WindowAdapter() { 99 @Override 100 public void windowClosed(WindowEvent e) { 101 System.exit(0); 102 } 103 }); 104 jFrame.setVisible(true); 105 } 106 }); 107 } 108 109 @Override 110 public void actionPerformed(ActionEvent e) { 111 if (btnFile == e.getSource()) { 112 textArea.setText(""); 113 String directory = "d:" + File.separator; 114 if (srcFile != null) { 115 directory = srcFile.getParentFile().getAbsolutePath(); 116 } 117 JFileChooser fileChooser = new JFileChooser(directory); 118 // fileChooser.addChoosableFileFilter(new FileTypeFilter("xml")); 119 fileChooser.setFileFilter(new FileTypeFilter("xml")); 120 int result = fileChooser.showOpenDialog(jFrame); 121 if (JFileChooser.APPROVE_OPTION == result) { 122 srcFile= fileChooser.getSelectedFile(); 123 // JOptionPane.showMessageDialog(jFrame, srcFile.getName()); 124 } 125 if (JFileChooser.CANCEL_OPTION == result) { 126 srcFile = null; 127 } 128 printResult(srcFile); 129 } else { 130 Clipboard board = Toolkit.getDefaultToolkit().getSystemClipboard(); 131 if (btnCopy == e.getSource()) { 132 board.setContents(new StringSelection(textArea.getSelectedText()), null); 133 } 134 if (btnCopyAll == e.getSource()) { 135 board.setContents(new StringSelection(textArea.getText()), null); 136 } 137 } 138 } 139 140 private void printResult(File file) { 141 if (file == null) { 142 return; 143 } 144 XmlUtil xmlUtil = new XmlUtil(); 145 if (rbAA.isSelected()) { 146 xmlUtil.setOutType(XmlUtil.AA_TYPE); 147 } else { 148 xmlUtil.setOutType(XmlUtil.NORMAL_TYPE); 149 } 150 java.util.List<String> result = xmlUtil.readXmlFile(file); 151 if (xmlUtil.getOutType() == XmlUtil.NORMAL_TYPE) { 152 for (String s: result) { 153 textArea.append(s.substring(0, s.indexOf("=") - 1) + ";\n"); 154 } 155 textArea.append("\n\n"); 156 for (String s : result) { 157 textArea.append(s.substring(s.indexOf(" ")) + "\n"); 158 } 159 160 } else { 161 for (String s : result) { 162 textArea.append(s + "\n"); 163 } 164 } 165 } 166 }
2、可以捕获拖拽事件JTextArea
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.zhyy.layoutparser; 2 3 import javax.swing.*; 4 import java.awt.datatransfer.DataFlavor; 5 import java.awt.datatransfer.Transferable; 6 import java.awt.datatransfer.UnsupportedFlavorException; 7 import java.awt.dnd.*; 8 import java.io.File; 9 import java.io.IOException; 10 import java.util.List; 11 12 /** 13 * Created by Administrator on 2014/8/2. 14 */ 15 public class DropDragTextArea extends JTextArea implements DropTargetListener { 16 private DropTarget dropTarget; 17 private GetDropFileListener getDropFileListener; 18 public void setGetDropFileListener(GetDropFileListener listener) { 19 this.getDropFileListener = listener; 20 } 21 22 public DropDragTextArea() { 23 dropTarget = new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this, true); 24 } 25 @Override 26 public void dragEnter(DropTargetDragEvent dtde) { 27 DataFlavor flavor[] = dtde.getCurrentDataFlavors(); 28 //是文件 29 if (flavor[0].isFlavorJavaFileListType()) { 30 Transferable transferable = dtde.getTransferable(); 31 try { 32 Object object = transferable.getTransferData(DataFlavor.javaFileListFlavor); 33 List<File> files = (List<File>) object; 34 if (files.size() > 0) { 35 getDropFileListener.getDropFile(files.get(0)); 36 } 37 } catch (UnsupportedFlavorException e) { 38 e.printStackTrace(); 39 } catch (IOException e) { 40 e.printStackTrace(); 41 } 42 } 43 } 44 45 @Override 46 public void dragOver(DropTargetDragEvent dtde) { 47 48 } 49 50 @Override 51 public void dropActionChanged(DropTargetDragEvent dtde) { 52 53 } 54 55 @Override 56 public void dragExit(DropTargetEvent dte) { 57 58 } 59 60 @Override 61 public void drop(DropTargetDropEvent dtde) { 62 63 } 64 65 public interface GetDropFileListener{ 66 public void getDropFile(File file); 67 } 68 }
3、xml处理类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.zhyy.layoutparser; 2 3 import org.w3c.dom.Document; 4 import org.w3c.dom.Element; 5 import org.w3c.dom.Node; 6 import org.w3c.dom.NodeList; 7 import org.xml.sax.SAXException; 8 9 import javax.xml.parsers.DocumentBuilder; 10 import javax.xml.parsers.DocumentBuilderFactory; 11 import javax.xml.parsers.ParserConfigurationException; 12 import javax.xml.transform.Transformer; 13 import javax.xml.transform.TransformerConfigurationException; 14 import javax.xml.transform.TransformerException; 15 import javax.xml.transform.TransformerFactory; 16 import javax.xml.transform.dom.DOMSource; 17 import javax.xml.transform.stream.StreamResult; 18 import java.io.File; 19 import java.io.FileOutputStream; 20 import java.io.IOException; 21 import java.util.ArrayList; 22 import java.util.List; 23 24 /** 25 * Created by Administrator on 2014/7/17. 26 */ 27 public class XmlUtil { 28 29 public static int NORMAL_TYPE = 1; 30 public static int AA_TYPE = 2;//android annotations 31 32 private int outType = 1; 33 public void setOutType(int type) { 34 outType = type; 35 } 36 public int getOutType() { 37 return outType; 38 } 39 40 private List<String> result; 41 42 public XmlUtil() { 43 result = new ArrayList<String>(); 44 } 45 46 public List<String> readXmlFile(File path) { 47 try { 48 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 49 DocumentBuilder builder = factory.newDocumentBuilder(); 50 Document document = builder.parse(path); 51 Element element = document.getDocumentElement(); 52 String attr = getAttributeOfName(element, "android:id"); 53 if (attr != null) { 54 result.add(attr); 55 } 56 NodeList nodeList = element.getChildNodes(); 57 searchSubNodes(nodeList); 58 } catch (ParserConfigurationException e) { 59 e.printStackTrace(); 60 } catch (SAXException e) { 61 e.printStackTrace(); 62 } catch (IOException e) { 63 e.printStackTrace(); 64 } 65 return result; 66 } 67 68 private void searchSubNodes(NodeList nodeList) { 69 for (int i = 0; i < nodeList.getLength(); i++) { 70 Node node = nodeList.item(i); 71 if (node.getNodeType() == Node.ELEMENT_NODE) { 72 String att = getAttributeOfName((Element) node, "android:id"); 73 if (att != null) { 74 result.add(att); 75 } 76 } 77 NodeList list = node.getChildNodes(); 78 searchSubNodes(list); 79 } 80 } 81 82 public void writeXmlVal(String fpath, String valPath, String val) { 83 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); 84 try { 85 DocumentBuilder builder = builderFactory.newDocumentBuilder(); 86 Document document = builder.parse(fpath); 87 Element root = document.getDocumentElement(); 88 String[] valPaths = valPath.split("/", -1); 89 int i = 0; 90 if (root.getNodeName().equals(valPaths[0])) { 91 i = 1; 92 } 93 for (;i < valPaths.length; i++) { 94 Element element = null; 95 NodeList nodeList = root.getChildNodes(); 96 for (int j = 0;j<nodeList.getLength(); j++) { 97 Node node = nodeList.item(j); 98 if (node.getNodeType() == Node.ELEMENT_NODE) { 99 if (node.getNodeName().equals(valPaths[i])) { 100 element = (Element) node; 101 } 102 } 103 } 104 if (element == null) { 105 element = document.createElement(valPaths[i]); 106 root.appendChild(element); 107 } 108 root = element; 109 if (i == (valPaths.length - 1)) { 110 element.setAttribute("android:id", val); 111 } 112 } 113 Transformer t = TransformerFactory.newInstance().newTransformer(); 114 t.setOutputProperty("indent", "yes"); 115 t.transform(new DOMSource(document), new StreamResult(new FileOutputStream(fpath))); 116 } catch (ParserConfigurationException e) { 117 e.printStackTrace(); 118 } catch (SAXException e) { 119 e.printStackTrace(); 120 } catch (IOException e) { 121 e.printStackTrace(); 122 } catch (TransformerConfigurationException e) { 123 e.printStackTrace(); 124 } catch (TransformerException e) { 125 e.printStackTrace(); 126 } 127 } 128 129 private String getAttributeOfName(Element node, String name) { 130 String attr = node.getAttribute(name); 131 if (attr.isEmpty()) { 132 return null; 133 } 134 if (AA_TYPE == getOutType()) { 135 return "@ViewById\n" + node.getNodeName() + " " + attr.substring(attr.indexOf("/") + 1) + ";"; 136 } 137 if (NORMAL_TYPE == getOutType()) { 138 return node.getNodeName() + " " + attr.substring(attr.indexOf("/") + 1) + " = (" + node.getNodeName() + ") findViewById(R.id." + attr.substring(attr.indexOf("/") + 1) + ");"; 139 } 140 return null; 141 } 142 143 public static void main(String args[]) { 144 XmlUtil xmlUtil = new XmlUtil(); 145 // xmlUtil.setOutType(AA_TYPE); 146 // xmlUtil.readXmlFile("d:\\test.xml"); 147 xmlUtil.writeXmlVal("d:\\test.xml", "LinearLayout/LinearLayout/TextView", "@+id/tv"); 148 } 149 }
4、文件选择器的过滤类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.zhyy.layoutparser; 2 3 import javax.swing.filechooser.FileFilter; 4 import java.io.File; 5 6 /** 7 * Created by Administrator on 2014/7/30. 8 */ 9 public class FileTypeFilter extends FileFilter{ 10 private String exten = ""; 11 12 public FileTypeFilter(String exten) { 13 this.exten = exten; 14 } 15 16 @Override 17 public boolean accept(File f) { 18 if (f.isDirectory()) { 19 return true; 20 } 21 String name = f.getName(); 22 String ex = name.substring(name.lastIndexOf(".") + 1, name.length()); 23 return ex.equals(exten); 24 } 25 26 @Override 27 public String getDescription() { 28 return "*." + exten; 29 } 30 }
体验一下github:
此代码的github地址:https://github.com/Zhaoyy/MyLayoutParser