KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > lobobrowser > html > gui > FrameSetPanel


1 /*
2     GNU LESSER GENERAL PUBLIC LICENSE
3     Copyright (C) 2006 The Lobo Project
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13     Lesser General Public License for more details.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19     Contact info: xamjadmin@users.sourceforge.net
20 */

21 /*
22  * Created on Jan 29, 2006
23  */

24 package org.lobobrowser.html.gui;
25
26 import java.awt.Component JavaDoc;
27 import java.awt.Container JavaDoc;
28 import java.awt.Dimension JavaDoc;
29 import java.awt.Insets JavaDoc;
30 import java.net.MalformedURLException JavaDoc;
31 import java.util.ArrayList JavaDoc;
32 import java.util.StringTokenizer JavaDoc;
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 /**
44  * A Swing panel used to render a FRAMESET.
45  * @see HtmlPanel
46  * @see HtmlBlockPanel
47  */

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         //TODO: This should be a temporary preferred size
55
this.setPreferredSize(new Dimension JavaDoc(600, 400));
56     }
57
58     private HtmlLength[] getLengths(String JavaDoc spec) {
59         if(spec == null) {
60             return new HtmlLength[] { new HtmlLength("1*") };
61         }
62         StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(spec, ",");
63         ArrayList JavaDoc lengths = new ArrayList JavaDoc();
64         while(tok.hasMoreTokens()) {
65             String JavaDoc token = tok.nextToken().trim();
66             try {
67                 lengths.add(new HtmlLength(token));
68             } catch(Exception JavaDoc 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 JavaDoc subFrames = new ArrayList JavaDoc();
78         for(int i = 0; i < children.length; i++) {
79             NodeImpl child = children[i];
80             if(child instanceof HTMLElementImpl) {
81                 String JavaDoc 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     /**
93      * Sets the FRAMESET node and invalidates the component
94      * so it can be rendered immediately in the GUI thread.
95      */

96     public void setRootNode(NodeImpl node) {
97         // Method expected to be called in the GUI thread.
98
if(!(node instanceof HTMLElementImpl)) {
99             throw new IllegalArgumentException JavaDoc("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 JavaDoc toValidate = this;
113         for(;;) {
114             Container JavaDoc 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         // Called in the GUI thread.
125
if(notifications.length > 0) {
126             // Not very efficient, but it will do.
127
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 JavaDoc[] 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     /**
145      * This method is invoked by AWT in the GUI thread
146      * to lay out the component. This implementation
147      * is an override.
148      */

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 JavaDoc rows = element.getAttribute("rows");
157                 String JavaDoc cols = element.getAttribute("cols");
158                 HtmlLength[] rowLengths = this.getLengths(rows);
159                 HtmlLength[] colLengths = this.getLengths(cols);
160                 HTMLElementImpl[] subframes = this.getSubFrames(element);
161                 Component JavaDoc[] frameComponents = new Component JavaDoc[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 JavaDoc src = frameElement.getAttribute("src");
175                             if(src != null) {
176                                 java.net.URL JavaDoc url;
177                                 try {
178                                     url = frameElement.getFullURL(src);
179                                     if(url != null) {
180                                         frame.loadURL(url);
181                                     }
182                                 } catch(MalformedURLException JavaDoc 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 JavaDoc[] fc = this.frameComponents;
197                 if(rhl != null && chl != null && fc != null) {
198                     Dimension JavaDoc size = this.getSize();
199                     Insets JavaDoc 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 JavaDoc getSplitPane(HtmlRendererContext context, int[] colLengths, int firstCol, int numCols, int[] rowLengths, int firstRow, int numRows, Component JavaDoc[] frameComponents) {
246         if(numCols == 1) {
247             int frameindex = colLengths.length * firstRow + firstCol;
248             Component JavaDoc topComponent = frameindex < frameComponents.length ? frameComponents[frameindex] : null;
249             if(numRows == 1) {
250                 return topComponent;
251             }
252             else {
253                 Component JavaDoc 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 JavaDoc rightComponent = this.getSplitPane(context, colLengths, firstCol + 1, numCols - 1, rowLengths, firstRow, numRows, frameComponents);
261             Component JavaDoc 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