1 21 24 package org.lobobrowser.html.gui; 25 26 import java.awt.Component ; 27 import java.awt.Container ; 28 import java.awt.Dimension ; 29 import java.awt.Insets ; 30 import java.net.MalformedURLException ; 31 import java.util.ArrayList ; 32 import java.util.StringTokenizer ; 33 34 import javax.swing.*; 35 import java.util.logging.*; 36 37 import org.lobobrowser.html.*; 38 import org.lobobrowser.html.domimpl.*; 39 import org.lobobrowser.html.renderer.NodeRenderer; 40 import org.lobobrowser.html.style.HtmlLength; 41 import org.lobobrowser.util.gui.WrapperLayout; 42 43 48 public class FrameSetPanel extends JComponent implements NodeRenderer { 49 private static final Logger logger = Logger.getLogger(FrameSetPanel.class.getName()); 50 51 public FrameSetPanel() { 52 super(); 53 this.setLayout(WrapperLayout.getInstance()); 54 this.setPreferredSize(new Dimension (600, 400)); 56 } 57 58 private HtmlLength[] getLengths(String spec) { 59 if(spec == null) { 60 return new HtmlLength[] { new HtmlLength("1*") }; 61 } 62 StringTokenizer tok = new StringTokenizer (spec, ","); 63 ArrayList lengths = new ArrayList (); 64 while(tok.hasMoreTokens()) { 65 String token = tok.nextToken().trim(); 66 try { 67 lengths.add(new HtmlLength(token)); 68 } catch(Exception err) { 69 logger.warning("Frame rows or cols value [" + spec + "] is invalid."); 70 } 71 } 72 return (HtmlLength[]) lengths.toArray(HtmlLength.EMPTY_ARRAY); 73 } 74 75 private HTMLElementImpl[] getSubFrames(HTMLElementImpl parent) { 76 NodeImpl[] children = parent.getChildrenArray(); 77 ArrayList subFrames = new ArrayList (); 78 for(int i = 0; i < children.length; i++) { 79 NodeImpl child = children[i]; 80 if(child instanceof HTMLElementImpl) { 81 String nodeName = child.getNodeName(); 82 if("FRAME".equalsIgnoreCase(nodeName) || "FRAMESET".equalsIgnoreCase(nodeName)) { 83 subFrames.add(child); 84 } 85 } 86 } 87 return (HTMLElementImpl[]) subFrames.toArray(new HTMLElementImpl[0]); 88 } 89 90 private HTMLElementImpl rootNode; 91 92 96 public void setRootNode(NodeImpl node) { 97 if(!(node instanceof HTMLElementImpl)) { 99 throw new IllegalArgumentException ("node=" + node); 100 } 101 HTMLElementImpl element = (HTMLElementImpl) node; 102 this.rootNode = element; 103 HtmlRendererContext context = element.getHtmlRendererContext(); 104 this.htmlContext = context; 105 this.domInvalid = true; 106 this.invalidate(); 107 this.validateAll(); 108 this.repaint(); 109 } 110 111 protected void validateAll() { 112 Component toValidate = this; 113 for(;;) { 114 Container parent = toValidate.getParent(); 115 if(parent == null || parent.isValid()) { 116 break; 117 } 118 toValidate = parent; 119 } 120 toValidate.validate(); 121 } 122 123 public final void processDocumentNotifications(DocumentNotification[] notifications) { 124 if(notifications.length > 0) { 126 this.domInvalid = true; 128 this.invalidate(); 129 if(this.isVisible()) { 130 this.validate(); 131 this.repaint(); 132 } 133 } 134 } 135 136 private HtmlRendererContext htmlContext; 137 private Component [] frameComponents; 138 private boolean domInvalid = true; 139 140 public void setBounds(int x, int y, int w, int h) { 141 super.setBounds(x, y, w, h); 142 } 143 144 149 public void doLayout() { 150 if(this.domInvalid) { 151 this.domInvalid = false; 152 this.removeAll(); 153 HtmlRendererContext context = this.htmlContext; 154 if(context != null) { 155 HTMLElementImpl element = (HTMLElementImpl) this.rootNode; 156 String rows = element.getAttribute("rows"); 157 String cols = element.getAttribute("cols"); 158 HtmlLength[] rowLengths = this.getLengths(rows); 159 HtmlLength[] colLengths = this.getLengths(cols); 160 HTMLElementImpl[] subframes = this.getSubFrames(element); 161 Component [] frameComponents = new Component [subframes.length]; 162 this.frameComponents = frameComponents; 163 for(int i = 0; i < subframes.length; i++) { 164 HTMLElementImpl frameElement = subframes[i]; 165 if(frameElement != null && "FRAMESET".equalsIgnoreCase(frameElement.getTagName())) { 166 FrameSetPanel fsp = new FrameSetPanel(); 167 fsp.setRootNode(frameElement); 168 frameComponents[i] = fsp; 169 } 170 else { 171 if(frameElement instanceof FrameNode) { 172 BrowserFrame frame = context.createBrowserFrame(); 173 ((FrameNode) frameElement).setBrowserFrame(frame); 174 String src = frameElement.getAttribute("src"); 175 if(src != null) { 176 java.net.URL url; 177 try { 178 url = frameElement.getFullURL(src); 179 if(url != null) { 180 frame.loadURL(url); 181 } 182 } catch(MalformedURLException mfu) { 183 logger.warning("Frame URI=[" + src + "] is malformed."); 184 } 185 } 186 frameComponents[i] = frame.getComponent(); 187 } 188 else { 189 frameComponents[i] = new JPanel(); 190 } 191 } 192 193 } 194 HtmlLength[] rhl = rowLengths; 195 HtmlLength[] chl = colLengths; 196 Component [] fc = this.frameComponents; 197 if(rhl != null && chl != null && fc != null) { 198 Dimension size = this.getSize(); 199 Insets insets = this.getInsets(); 200 int width = size.width - insets.left - insets.right; 201 int height = size.height - insets.left - insets.right; 202 int[] absColLengths = this.getAbsoluteLengths(chl, width); 203 int[] absRowLengths = this.getAbsoluteLengths(rhl, height); 204 this.add(this.getSplitPane(this.htmlContext, absColLengths, 0, absColLengths.length, absRowLengths, 0, absRowLengths.length, fc)); 205 } 206 } 207 } 208 super.doLayout(); 209 } 210 211 private int[] getAbsoluteLengths(HtmlLength[] htmlLengths, int totalSize) { 212 int[] absLengths = new int[htmlLengths.length]; 213 int totalSizeNonMulti = 0; 214 int sumMulti = 0; 215 for(int i = 0; i < htmlLengths.length; i++) { 216 HtmlLength htmlLength = htmlLengths[i]; 217 int lengthType = htmlLength.getLengthType(); 218 if(lengthType == HtmlLength.PIXELS) { 219 int absLength = htmlLength.getRawValue(); 220 totalSizeNonMulti += absLength; 221 absLengths[i] = absLength; 222 } 223 else if(lengthType == HtmlLength.LENGTH) { 224 int absLength = htmlLength.getLength(totalSize); 225 totalSizeNonMulti += absLength; 226 absLengths[i] = absLength; 227 } 228 else { 229 sumMulti += htmlLength.getRawValue(); 230 } 231 } 232 int remaining = totalSize - totalSizeNonMulti; 233 if(remaining > 0 && sumMulti > 0) { 234 for(int i = 0; i < htmlLengths.length; i++) { 235 HtmlLength htmlLength = htmlLengths[i]; 236 if(htmlLength.getLengthType() == HtmlLength.MULTI_LENGTH) { 237 int absLength = (remaining * htmlLength.getRawValue()) / sumMulti; 238 absLengths[i] = absLength; 239 } 240 } 241 } 242 return absLengths; 243 } 244 245 private Component getSplitPane(HtmlRendererContext context, int[] colLengths, int firstCol, int numCols, int[] rowLengths, int firstRow, int numRows, Component [] frameComponents) { 246 if(numCols == 1) { 247 int frameindex = colLengths.length * firstRow + firstCol; 248 Component topComponent = frameindex < frameComponents.length ? frameComponents[frameindex] : null; 249 if(numRows == 1) { 250 return topComponent; 251 } 252 else { 253 Component bottomComponent = this.getSplitPane(context, colLengths, firstCol, numCols, rowLengths, firstRow + 1, numRows - 1, frameComponents); 254 JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, topComponent, bottomComponent); 255 sp.setDividerLocation(rowLengths[firstRow]); 256 return sp; 257 } 258 } 259 else { 260 Component rightComponent = this.getSplitPane(context, colLengths, firstCol + 1, numCols - 1, rowLengths, firstRow, numRows, frameComponents); 261 Component leftComponent = this.getSplitPane(context, colLengths, firstCol, 1, rowLengths, firstRow, numRows, frameComponents); 262 JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftComponent, rightComponent); 263 sp.setDividerLocation(colLengths[firstCol]); 264 return sp; 265 } 266 } 267 } 268 | Popular Tags |