Nada

Laboration 5 - Netscrape

I kursens sista labb ska du skriva en förbättrad version av Netscape, som inte bara surfar utan också tabellerar alla länkar på sidan. Så här kan det se ut. Labb 6

Tre av dom häftigaste swingkomponenterna kommer att användas, nämligen JEditorPane, JScrollPane och JTable. En huvudroll har swingklassen HTML som hanterar och tolkar webbdokument.

Du kommer troligen att behöva importera dom här klasserna.

   import java.io.*                                  ;
   import java.awt.*                                 ;
   import java.awt.event.*                           ;
   import java.net.*                                 ;
   import javax.swing.*                              ;
   import javax.swing.event.*                        ;
   import javax.swing.text.html.*                    ;
   import javax.swing.text.*                         ;

Det grafiska gränssnittet

När man ska skriva ett stort program är det ofta lämpligt att börja med en prototyp, dvs ett program som ser ut som den färdiga produkten med saknar funktionalitet. I det här fallet ska prototypen visa en JFrame med tre komponenter: I norr finns ett textfält, i centrum en JEditorPane och i öster en JTable, alla tomma. Det är meningen att tabellen ska ha femtio rader och två kolumner, så den får knappast plats i fönstret. Därför ska du lägga in den i ett rullfönster som visar lagom många rader i taget.
   JScrollPane länkar=new JScrollPane(new JTable(50,2));
Det är förresten bäst att också lägga in webbläsaren (centrumkomponenten) i ett rullfönster också eftersom hela webbsidan inte kommer att få plats. Kör programmet och kolla att det går att skriva text i alla tre komponenterna. När det gäller webbsidan och länktabellen är det en oavsiktlig finess (bug or feature?) men i textfältet ska användaren skriva in önskad webbadress och vid returtryckning anropas fältets ActionListener. Det är lämpligt att låta Netscrape själv vara lyssnare och i sin actionPerformed anropa webbläsare.visaSida(...) och skicka med fältets text.

Webbläsaren

Du ska nu skriva en klass Webbläsare som är arvtagare till JEditorPane och som har en metod visaSida(webbadress). Egentligen skulle metoden bara behöva innehålla den enda satsen
   setPage(new URL(webbadress));
men kompilatorn kräver try-catch för att ta hand om fallet att adressen inte existerar eller inte är kontaktbar. Då ska användaren få ett felmeddelande och till det ska du använda en dialogruta. (Ett bättre namn vore monologruta eftersom det enda användaren kan göra är att klicka på OK...) Komponenten heter JOptionPane och du får själv kolla hur anropet ska se ut (tips: den första parametern ska vara this).

När klassen är klar kan Netscrape deklarera Webbläsare webbläsare = new Webbläsare().

Surfaren

När du provkör ditt webbläsarprogram kommer du till din förtrytelse att märka att man inte kan klicka på länkarna i webbsidan. Det spelar nu ingen roll för det program som du vill skapa, men det kan mycket lätt åtgärdas. Det räknas som extrauppgift - det är inget krav. Två saker måste göras i din webbläsare: du ska göra setEditable(false), så att inte klickningen tolkas som att du vill börja ändra i texten och du ska lägga till en HyperlinkListener. Hur en sådan ser ut framgår av föreläsning 7. Anropet getURL().toString() till en HyperlinkEvent ger en fullständig webbadress som kan skrivas in i adressfältet.

Skriv alltså en klass Surfare som är arvtagare till din Webbläsare, som i konstruktorn tar emot adressfältet som parameter och sparar det i en privat variabel och som har en lämplig lyssnarmetod. Det räcker inte att skriva in en ny adress i fältet, man måste posta en händelse genom att anropa fältets postActionEvent(). När klassen är klar kan Netscrape deklarera Webbläsare webbläsare = new Surfare(adressfält).

Länktabellen

Låt Netscrape vila ett tag och skriv ett nytt program som skriver ut alla länkar i en webbsida. Det kan heta Webbkoll och tills vidare bara bestå av en main-metod. Man skriver ut en webbsida så här.
   String webbsida="http://www.nada.kth.se/~henrik"                  ;
   InputStream in=new URL(webbsida).openConnection().getInputStream();   
   InputStreamReader reader= new InputStreamReader(in)               ;
   while(reader.ready()) System.out.print((char)reader.read())       ;
Kompilatorn kräver try-catch eftersom uppkopplingen kan misslyckas. I stället för att själv läsa inströmmen ska du skapa ett tomt HTMLDocument och låta ett HTMLEditorKit läsa in webbsidan i det med
   doc.putProperty("IgnoreCharsetDirective", Boolean.TRUE)           ;
   new HTMLEditorKit().read(reader,doc,0)                            ;
(Utan den första satsen får man ChangedCharSetException på alla svenska sidor som ordentligt anger teckenuppsättningen iso-8859-1.) En HTML-sida innehåller taggar av olika slag och den tagg som används vid länkar heter A och har ett attribut HREF vars värde är länkens webbadress. Du ska nu iterera dej genom dokumentet från A-tagg till A-tagg, avläsa attributet HREF och skriva ut dess värde. För detta ändamål skapar du ett Tag.A-iteratorobjekt och ett HREF-attributobjekt. Sedan får iteratorn stega sej fram i en while-slinga. Skriv ut HREF-attributet inne i slingan.

När det här fungerar ska du också skriva ut den text som står mellan A-taggen och dess sluttagg med hjälp av it.getStartOffset() och it.getEndOffset().

I stället för att skriva ut länkar och länktext ska nu Webbkoll lägga in dom i en JTable, som Netscrape får tag i med anropet

   länkar=new JScrollPane(Webbkoll.länktabell(adressfält.getText()))  ;
Dina satser ska alltså flyttas från metoden main till metoden länktabell. Först i metoden kan du deklarera en String-matris med format 50 x 2 och i den lägger du in länkar och länktexter. När du kommer ut ur while-slingan tillverkar du en JTable av denna matris och en rubrikvektor med två komponenter, sätter bakgrunden till någon trevlig färg och returnerar tabellen.

Medan du testar kan det vara bra att ha en main-metod i Webbkoll som anropar länktabell, stoppar in tabellen i en JFrame och visar upp den. När det fungerar kan du vara säker på att också Netscrape visar upp tabellen. Problemet är att bli av med den gamla länktabellen innan man adderar en ny. Ett sätt är att först anropa remove(länkar), sedan skapa en ny JScrollPane länkar och till slut addera den i öster som förut.

Och sedan kan du ge dej ut och smurfa bland länkarna för att fira att sista pruttlabben är klar.



Smurfigt smurfat av ................................... smurfar.............................. den .................


Sidansvarig: <karlm@nada.kth.se>
Senast ändrad 20 mar 2005
Tekniskt stöd: <webmaster@nada.kth.se>