bild
Skolan för
elektroteknik
och datavetenskap

Laboration 6 - En enkel webbläsare

Mål

  • Att bli förtrogen med ytterligare några avancerade swing-komponenter:
    JEditorPane, JScrollPane, JTable och HTML.
  • Att kunna läsa dokumentation om de avancerade komponenterna och hämta den information man behöver, t.ex. alla länkar från en webbsida.

Uppgift

Skriv en enkel webläsare som bara klarar html-kod men förutom att den visar en webbsida så ska den tabellera alla länkar som webbsidan har. Så här kan det se ut.

Labb 6

Tre häftiga swingkomponenterna kommer att användas, nämligen JEditorPane, JScrollPane och JTable. En viktig roll 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 links = new JScrollPane(table);
Det är ännu viktigare att lägga in webbläsaren (centrumkomponenten) i ett rullfönster eftersom hela webbsidan vanligen 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?) som vi inte vill ha. I textfältet ska användaren kunna skriva in önskad webbadress och vid tryck på retur/ENTER ska önskad webbsida visas i vår JEditorPane. Därför behövs en lyssnare kopplad till textfältet.

Webbläsaren

Skriv en klass Webreader som ärver från JEditorPane. Se till att det inte går att skriva i detta fönster (metoden setEditable). Ge klassen en metod t.ex. showPage(webaddr). Läs dokumentationen om JEditorPane för att se hur man får den att visa en webbsida. Om den valda webbsidan inte går att visa, ge ett felmeddelande i form av en dialogruta. Använd JOptionPane! Tag reda på själv hur man gör (API:n eller övningsanteckningar).

Använd nu Webreader i huvudklassen istället för JEditorPane.

Se till att text inskriven i fältet högst upp tolkas som en URL och att motsvarande webbsida visas i fönstret när man trycker ENTER!

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 hyfsat bra att titta på. Här är URL:er till några andra CSC-medarbetares webbsidor. Dessa webbsidor ser OK ut i vår enkla webbläsare:

http://www.nada.kth.se/~orjan
http://www.nada.kth.se/~ala
http://www.nada.kth.se/~viggo
http://www.nada.kth.se/~vahid
http://www.nada.kth.se/~johanh
http://www.nada.kth.se/~ann

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 webbläsaren vila ett tag och skriv ett nytt program som skriver ut alla länkar från en webbsida. Programmet kan till att börja med bestå av bara en main-metod som skriver ut rätt information i terminalfönstret. När det fungerar, ändra så att informationen istället ges i en matris. Mer instruktioner nedan!

Hitta i webbsidan

Man skriver ut en webbsida tecken för tecken så här.
   String webpage="http://www.nada.kth.se/~henrik";
   InputStream in=new URL(webpage).openConnection().getInputStream();   
   InputStreamReader reader= new InputStreamReader(in);
   while(reader.ready()) 
      System.out.print((char)reader.read());
try-catch måste läggas till eftersom uppkopplingen (andra raden ovan) kan misslyckas. I stället för att läsa inströmmen och skriva ut den i terminalfönstret, skapa ett tomt HTMLDocument (doc) och låt ett HTMLEditorKit läsa in webbsidan till dokumentet 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. Skriv ut HREF-attributet inne i slingan. Läs dokumentationen för klassen HTML och dess inre klasser!

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 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 två kolumner och begränsat antal rader, t.ex. 50 st. Om det finns fler än 50 länkar struntar man alltså i de sista. Metoden som skapar matrisen bör ta webbsidans adress (en String) som parameter. Testa separat i en main-metod innan den nya metoden används i huvudprogrammet.

Använd matrisen i huvudprogrammet

I huvudprogrammet 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-arrayer, 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 ersättas med skapandet av länkmatrisen. Slå upp dokumentationen av JTable och läs där om ni behöver veta mer!

Redovisning

  • Visa att man kan gå till "snälla" webbsidor genom att skriva in adressen i textfältet och trycka ENTER.
  • En felaktig URL ska ge en ruta med felmeddelande. Ingen uppdatering av sida eller länkar ska då göras. Felmeddelanden i bakgrunden accepteras inte, inte heller att programmet avslutas.
  • Om en webbsida har fler än 50 länkar ska bara de 50 första visas. Något Exception som ArrayIndexOutOfBounds eller liknande får inte genereras.
  • Visa UML-klassdiagram med klassnamn och de metoder ni skrivit själva (inklusive omdefinierade metoder).

 

Extrauppgift för betygshöjning - klickbara länkar

Webbläsarprogrammet vi har gjort reagerar inte på att man klickar på länkarna i webbsidan. Extrauppgiften är att göra länkarna klickbara och se till att den nya webbsidan visas i fönstret.

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. Lägg också till till en HyperlinkListener. Anropet getURL().toString() till en HyperlinkEvent ger en fullständig webbadress som kan skrivas in i adressfältet. Läs dokumentationen om Hyperlink... och ta reda på vad som behövs!

Krav

  • Webbläsaren ska reagarera på klickningar av länkarna, inte bara på att markören (musen) hålls över länken.

  • Den klickade länken ska visas i adressfältet hos webbläsaren och den valda sidan ska visas som aktuell webbsida. Några tillägg i Webreader 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().


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