bild
Skolan för
elektroteknik
och datavetenskap

Laboration 6 - 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 de 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 de 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. Tabellen ska ha femtio rader och två kolumner, så den får knappast plats i fönstret. Lägg därför in den i ett rullfönster som visar lagom många rader i taget.
JTable table = new JTable(50,2);
JScrollPane lankar = new JScrollPane(table);
eller om man klarar sig utan explicit referens till tabellen:
JScrollPane lankar=new JScrollPane(new JTable(50,2));
Det är ännu viktigare att lägga in webbläsaren (centrumkomponenten) i ett rullfönster 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 eller feature?) men i textfältet ska användaren skriva in önskad webbadress och vid returtryckning anropas fältets ActionListener och programmet försöker hämta in angiven webbsida. Det är lämpligt att låta Netscrape själv vara lyssnare och i sin actionPerformed anropa t.ex. webbreader.showPage(...) och skicka med fältets text.

Webbläsaren

Skriv en klass Webbreader som ärver från JEditorPane och som har en metod t.ex. showPage(webbadress). Egentligen skulle metoden bara behöva innehålla den enda satsen
   setPage(webbadress); // där webbadress är en String
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).

Gör för säkerhets skull också setEditable(false) i klassens konstruktor(er). När klassen är klar kan Netscrape deklarera    Webbreader reader = new Webbreader() (alternativt ge en startadress som konstruktorparameter så att man alltid kan starta på en webbsida).

Innan ni går vidare, kolla att programmet fungerar så här långt genom att titta på några olika webbsidor. Sidan som syns på bilden ovan går bra att titta på i Netscrape. Även vår huvudstudierektors (Viggo Kann) sida går bra att titta på. URL till den är
http://www.nada.kth.se/~viggo.

Surfaren - extrauppgift

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 kan åtgärdas. Det räknas som extrauppgift - så det är inget krav. Om du inte vill göra extrauppgift redan nu, gå vidare till uppgiften Länktabellen nedan!

Två saker måste göras i webbläsaren: gör setEditable(false) (kanske redan gjort), så att inte klickningen tolkas som att du vill börja ändra i texten och lägg till en HyperlinkListener. (något om Hyperlinklisteners kommer att finnas i föreläsningsmaterial och ev. tar vi upp det på en föreläsning, troligen nr 10). Anropet getURL().toString() till en HyperlinkEvent ger en fullständig webbadress som kan skrivas in i adressfältet. Se till att webbläsaren reagarerar på klickningar av länkarna, inte bara på att markören (musen) hålls över länken.

Se till att den klickade länken visas i adressfältet hos Netscrape och att den valda sidan visas som aktuell webbsida. Några små ändringar i Webbreader eller ev. en ny subklass till densamma kan fixa detta. När den nya sidan ska visas kan man ha nytta av att från programmet framkalla en händelse (ActionEvent) genom att anropa textfältets postActionEvent(). Andra lösningar finns förstås!

Länktabellen – ingår i grunduppgiften

I den här deluppgiften ska texterna som syns i tabellen till höger i bildexemplet ovan tas fram.

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älva läsa inströmmen ska ni skapa ett tomt HTMLDocument och låta ett HTMLEditorKit läsa in webbsidan till 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. Den nionde raden i tabellen i bildexemplet ovan kan motsvaras av följande i html-dokumentet:

<A HREF = "http://www.nada.kth.se/~gerd">hustru</A>

Iterera nu genom dokumentet från A-tagg till A-tagg, läs av attributet HREF och skriv ut dess värde. För detta ändamål skapas ett Tag.A-iteratorobjekt och ett HREF-attributobjekt. Iteratorn stegar sig fram i en while-slinga. Skriv ut HREF-attributet inne i slingan.

När det här fungerar, skriv ut den text som står mellan A-taggen och dess sluttagg med hjälp av it.getStartOffset() och it.getEndOffset(). Läs i dokumentationen för HTMLDocument hur man kan få ut en deltext ur dokumentet! Vi går igenom ett liknande exempel (med tagg men inte attribut) på övning 5 eller 6.

Lägg adress och text i en matris

När utskrifterna fungerar så ändra testprogrammet så att det istället för en main-metod med utskrift har en metod som returnerar en String-matris med adresser och texter motsvarande tabellen. Matrisen ska ha en begränsad storlek, t.ex. 50 x 2, oavsett hur många länkar den aktuella webbsidan har. Metoden som returnerar matrisen bör ta webbsidans adress (en String) som parameter. Testa gärna i en main-metod innan den nya metoden används i Netscrape.

Använd matrisen i Netscrape

I Netscrape finns en JTable med 50 x 2 positioner, men från början inget innehåll. Enklaste sättet att ändra på innehållet i en JTable är att byta ut dess modell. Modellen kan skapas från två String-matriser, där den ena är tabellinnehållet och den andra är tabellens rubriker. Här är ett exempel:
table.setModel(new DefaultTableModel(..., header));
Prickarna ska förstås ersättas med skapandet av matrisen enligt ovan. Slå gärna upp dokumentationen av JTable för att få veta mer!

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

Extrauppgift för betygshöjning

Se under rubriken Surfaren ovan!


Copyright © Sidansvarig: Ann Bengtsson <ann@nada.kth.se>
Uppdaterad 2011-05-17