Java: jednoduchý internetový prohlížeč
Vytvořit v Javě internetový prohlížeč, pouze se základními funkcemi, je opravdu velmi jednoduché. Uděláme si prohlížeč, který zvládne zobrazit zadanou HTML stránku, umožní klikat na odkazy a přecházet tak na další stránky, nebo třeba odesílat formuláře.
Pro vytvoření opravdu jednoduchého webového prohlížeče můžeme využít implementace HyperlinkListener, který umožní pracovat se Hypertextovým obsahem.
Co všechno bude náš prohlížeč umožňovat:
- zadat a přejít na požadovanou URL adresu
- odchytit výjimku při kliknutí na odkaz a přejít na něj
- možnost vrátit se na předchozí stránku (back)
Samozřejmě, při impmenetaci HyperlinkListener, musíme počítat s jistými omezeními, a určitě během tohoto krátkého tutoriálu nevytvoříme plnohodnotný prohlížeč, který bude zvládat javascript, veškeré formátování pomocí CSS zobrazovat správně nebo podporovat Flash.
Námi vytvořený editor bude mít pouze těchto několik základních funkcí, které je samozřejmě možno dle libosti doplnit.
Grafické rozhraní editoru
Ve stručnosti popíšu grafické rozhraní, které bude náš editor obsahovat, a které součásti budou potřeba.
Základem editoru je samozřejmě plocha pro zobrazení obsahu HTML stránky. Pro tyto potřeby využijeme JEditorPane, kterému nastavíme pomocí setContentType hodnotu „text/html“. Tím v něm můžeme zobrazovat HTML kód.
Dále je potřeba vytvořit formulář pro zadání URL adresy a v našem případě ještě dvě tlačítka. Jedno pro přechod na zadanou URL adresu a druhé pro návrat zpět.
Pro zadání URL adresy nám bude stačit obyčejný JTextField.
Jako poslední věc si doplníme GUI o stavový řádek, ve kterém budeme vypisovat základní informace o běhu a načítání stránek.
Bez dalšího zdržování uvedu rovnou celé grafické rozhraní, které je velmi jednoduché. Uvedu jej včetně všech listenerů, jejichž obslužné funkce doplním dále:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
public class WebBrowser extends JFrame implements HyperlinkListener { private static final long serialVersionUID = 1L; //panel pro URL adresu private JTextField urlpanel; //JEditorPane pro zobrazeni stranky private JEditorPane editor; //statovy radek pro informace private JLabel status; //naposled pouzita url adresa private String LastUrl = null; //tlacitko zpet public JButton back = new JButton("Back"); public WebBrowser() { //zakladni nastaveni grafickeho rozhrani - JFrame setTitle("Web Browser"); setSize(600, 300); //close operation setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //vytvoreni menu JMenuBar topmenu = new JMenuBar(); JMenu file = new JMenu("File"); JMenuItem exit = new JMenuItem("Exit"); topmenu.add(file); file.add(exit); this.setJMenuBar(topmenu); exit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { System.exit(1); } }); //horni panel s ovladanim JPanel toppanel = new JPanel(); //textove pole pro URL adresu urlpanel = new JTextField(""); urlpanel.setPreferredSize(new Dimension(20, 20)); urlpanel.setPreferredSize(new Dimension(getSize().width - 200, 20)); back.setEnabled(false); back.addActionListener(new ActionListener(){ public void actionPerformed( ActionEvent arg0 ){ LoadHtmlPage(LastUrl); } }); //tlacitko pro odeslani formulare JButton go = new JButton("Go"); //action listener pro odeslani formualre go.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { //prejde na stranku LoadHtmlPage(urlpanel.getText()); } }); toppanel.add( back ); toppanel.add(urlpanel); toppanel.add(go); add(toppanel); //stavovy radek JPanel statusBar = new JPanel(); //nastaveni defaultniho textu status = new JLabel("Insert URL"); statusBar.add(status); statusBar.setBackground(Color.WHITE); //vytvoreni JEditorPane editor = new JEditorPane(); //content type pro html editor.setContentType("text/html"); //muzete si nastavit true :-) editor.setEditable(false); //vytvoříme hyperlink listener editor.addHyperlinkListener(this); //content pane getContentPane().setLayout(new BorderLayout()); getContentPane().add(toppanel, BorderLayout.NORTH); getContentPane().add(new JScrollPane(editor), BorderLayout.CENTER); this.add(statusBar, BorderLayout.SOUTH); setVisible(true); } } |
Obslužné funkce
Pokud jste si pročetli kód rozhraní, vidíte v něm dvakrát volanou funkci LoadHtmlPage().
Funkce je volána při stisku jednoho ze dvou tlačítek, kdy v prvním případě je volána s proměnnou LastUrl, která značí předchozí URL adresu a podruhé po stisku tlačítka Vpřed, s parametrem obsahu hodnoty textového pole pro URL adresu.
Funkce LoadHtmlPage má jednoduchý úkol. V první řadě zkontroluje hodnotu zadané URL adresy, která do ní vstupuje jako String proměnná. Provede kontrolu na délku, která nesmí být nulová a kontroluje, jestli URL adresa začíná řetězcem http://. V případě že nezačíná, řetězec o tuto hodnotu doplní:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
//funkce zkontroluje zadanou URL adresu //v pripade ze souhlasi, vytvori promennou typu URL a vola funkci pro nacteni public void LoadHtmlPage( String ur) { //nastaveni statusu status.setText("Loading..."); //nastaveni posledni URL adresy this.LastUrl = this.urlpanel.getText().trim(); //aktivace tlacitka zpet back.setEnabled(true); //kontrola, zda existuje URL adresa if (ur.trim().length() == 0) { status.setText("URL is empty"); return; } //kontrola, zda url adresa zacina http:// if (ur.startsWith("http://") == false) { ur = "http://" + ur; } try { //vytvoreni nove URL URL url = new URL(ur); GoToPage(url); } catch (MalformedURLException e) { e.printStackTrace(); } } |
Nakonec funkce vytvoří proměnnou typu URL a volá funkci GoToPage(), která načte požadovanou adresu.
Funkce GoToPage() se stará o načtení stránky, hodnoty ze vstupní proměnné typu URL a její zobrazení v editoru.
Funkce ze všeho nejdřív nastaví kurzor myši na hodnotu WAIT_CURSOR, pokusí se načíst danou URL adresu a nastaví hodnotu titulku a stavového řádku.
Po jejím načtení opět vrací kurzor do původního stravu:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
//funkce nacita obsah URL adresy do promenne editor, do ktere ji zobrazi jako HTML public void GoToPage(URL url) { //zmena kurzoru na Wait setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); try { @SuppressWarnings("unused") URL currentUrl = editor.getPage(); //zobrazeni stranky editor.setPage(url); URL newUrl = editor.getPage(); //nastaveni titulku okna this.setTitle(newUrl.getHost()); //nastaveni url adresy v panelu urlpanel.setText(newUrl.toString()); } catch (Exception e) { //doplneni statusu status.setText("Load Failed"); } finally { //zmena statusu status.setText("Compete..."); //vraceni puvodniho kurzoru setCursor(Cursor.getDefaultCursor()); } } |
Poslední metoda, kterou potřebujeme napsat je samozřejmě hyperlinkUpdate, volaný v konstruktoru, a který zachycuje výjimky při například klikání na webu.
Metoda kontroluje, zda bylo kliknuto levým tlačítkem myši a v případě že ano, volá opět metodu LoadHtmlPage, a přejde na danou URL adresu:
1 2 3 4 5 6 7 8 9 10 |
//funkce volana pomoci Hyperlink Listeneru public void hyperlinkUpdate(HyperlinkEvent event) { //zjistime EventType HyperlinkEvent.EventType eventType = event.getEventType(); //pokud je Activated (klik levym tlacitkem mysi: ) if (eventType == HyperlinkEvent.EventType.ACTIVATED) { //prejdeme na stranku LoadHtmlPage(event.getURL().toString()); } } |
Tím je hotový základ editoru, který umožňuje procházet weby.
Závěrem
Jak bylo uvedeno již v úvodu, cílem nebylo vytvořit plně funkční prohlížeč, ale pouze základ, který umožní procházet webem. V současném stavu by nebyl problém dopsat funkce pro pamatování celé historie, umožnit kromě návratu zpět i posun vpřed, zobrazovat obrázky, které v tomto stavu díky odeslané a nastavené hodnotě ContentType nejdou a podobně.
Zdrojový kód
Nakonec ještě zdrojový kód celého programu
Zdravim, pekny priklad
mam jeden dotaz: nevim proc nefunguje v tomto prohlizeci zobrazovani URL pro Google napr.:
http://www.google.cz/search?q=neco
Shodou okolnosti delam na jinem projektu a mam stejny problem, server hlasi chybu "403 Forbidden"
diky za radu