Programování

Vytvářejte uživatelská rozhraní na straně klienta v HTML, část 1

Tento měsíc se na chvíli vracím k programování. Potřebuji si odpočinout od podivnosti diskuze Talkback ve sloupci z minulého měsíce. Mám v úmyslu psát více o problémech s teorií v budoucnu, ale ne na příštích pár měsíců.

Musím učinit jedno vysvětlení ze sloupce z minulého měsíce. Mnoho lidí interpretovalo moje komentáře k uživatelským rozhraním jako obhajující těžké objekty s miliardami metod vykreslování. To jsem nemyslel. Existuje mnoho životaschopných způsobů, jak vytvořit uživatelská rozhraní (UI), aniž byste odhalili podrobnosti implementace. Vzory Gang čtyř stavitelů a návštěvníků okamžitě přijdou na mysl. Jednoduchý Nakresli se() metoda samozřejmě nemůže fungovat na ničem jiném než na nejjednodušších objektech a mít 50 drawYourselfInThisFormat () a drawYourselfInThatFormat () methods je nesmyslný recept na nezvládnutelný kód. Mnoho lidí si však myslí, že tento přístup obhajuji, takže se omlouvám, pokud jsem na tento dojem působil.

Vzhledem k tomu, že jsem viděl mnoho nedorozumění ohledně problému s uživatelským rozhraním, plánuji vám ukázat několik implementací objektově orientovaných (OO) přístupů k vytváření uživatelských rozhraní v budoucích sloupcích. Jedno takové řešení jsem představil v JavaWorld před několika lety (viz Zdroje), ale v uplynulých letech jsem vytvořil lepší systémy. Tento aktuální sloupec představuje část jednoho z těchto systémů uživatelského rozhraní: třída infrastruktury, kterou jsem použil při vytváření uživatelských rozhraní na straně klienta způsobem OO. Není samo o sobě řešením problému uživatelského rozhraní, ale je to užitečný stavební blok.

Protože ukázky kódu jsou poměrně velké, rozdělím prezentaci na dva bloky. Tento měsíc je dokumentace a kód aplikace; příští měsíc je zdrojový kód.

Přečtěte si celou sérii „Vytváření uživatelských rozhraní na straně klienta ve formátu HTML“:

  • Část 1: Zajistěte, aby byl JEditorPane užitečný (říjen 2003)
  • Část 2: Zdroje HTMLPane (listopad 2003)

Používání HTML na straně klienta

HTML je úžasná věc. Umožňuje vám rozložit komplikovaná uživatelská rozhraní s minimem rozruchu; dělá skvělou práci při oddělení struktury a rozložení uživatelského rozhraní od obchodní logiky; je snadné psát; a snadno se udržuje. Naproti tomu rozložení Abstract Window Toolkit (AWT) / Swing je nepříjemně obtížné používat. Musíte změnit (a překompilovat) kód, abyste změnili vzhled svých obrazovek, a kód pro triviální rozvržení je sám o sobě netriviální a rozšiřuje se na mnoho stránek. Nebylo by hezké, kdybyste mohli zadat celé své uživatelské rozhraní na straně klienta v HTML?

(Vím, že někteří z vás na předchozí otázku odpoví vzrušujícím „Ne, nebylo by to hezké!“ Mnoho lidí tvrdí, že HTML a dobrá uživatelská zkušenost jsou vzájemně se vylučující pojmy, protože HTML nutí vaše uživatelské rozhraní do „nekonečného kaskádového řízení režim „dialogové okno“. Na druhou stranu může spousta aplikací efektivně využívat HTML alespoň v některé části uživatelského rozhraní - pro tabulkové zprávy, pokud nic jiného. Nemůžete vyhodit dítě vodou z koupele.)

Houpačka JEditorPane třída se zpočátku zdá být odpovědí na problém s rozložením HTML. Rozumí vstupu HTML po módě. Například následující kód zobrazí rámeček, který zobrazuje nějaký jednoduchý text HTML:

JFrame main_frame = nový JFrame (); Panel JEditorPane = nový JEditorPane (); pane.setContentType ("text / html"); pane.setEditable (false); pane.setText ("" + "" + "" + "" + "AhojSvět"+" "+" "); main_frame.setContentPane (podokno); main_frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); main_frame.pack (); main_frame.show (); 

Říkám „po módě“, protože JEditorPane není zvlášť dobrý při zpracování složitého HTML. S vnořenými tabulkami nedělá skvělou práci a nedělá to dobře kaskádové styly (CSS). (Bylo mi řečeno, že mnoho z těchto problémů bude ve vydání Java 1.5 opraveno příští rok, ale zatím je musíme všichni zvládnout.) Nakonec, JEditorPane nedělá zvlášť dobrou práci při rozložení věcí, jako jsou přepínače. Nejsou správně zarovnány s účaří textu a vždy zobrazují šedé pozadí, takže nefungují dobře, pokud změníte barvu pozadí stránky (se stylem na například značka).

Všechny tyto nedostatky jsou nepříjemné, ale problém se zátkou JEditorPane je to, že funguje jako ovládací prvek textu, nikoli jako zařízení pro rozložení. Můžete určit HTML například na vstupu, ale formulář se odešle na webový server, když stisknete tlačítko Odeslat. Chcete-li být užiteční pro zadání uživatelského rozhraní na straně klienta, chcete, aby se data formuláře vrátila zpět do programu, který formulář zobrazil, nikoli na nějaký vzdálený server. Také potřebujete pohodlné způsob, jak přidat vlastní značky pro nestandardní vstupní nebo zobrazovací účely nebo poskytnout držáky pro standardní Swing JKomponenty chcete použít na formuláři. (JEditorPane umožňuje vám to udělat, ale mechanismus zdaleka není pohodlný.) Nakonec musíte zvládnout věci jako tlačítko Storno, které v HTML neexistuje.

Naštěstí nejzávažnější z výše uvedených problémů lze vyřešit pomocí přizpůsobovacích zařízení zabudovaných do JEditorPane sám. Oprava těchto problémů však vyžaduje určitou míru kompromisu. Například můžete vyřešit problém se zrušením tlačítka implementací tlumočníka JavaScriptu a podporou při kliknutí atribut, ale to je strašně hodně práce. Podobně je velmi obtížné poskytnout skutečnou podporu vlastních značek (kde můžete zpracovat vše, co přichází mezi počáteční a koncovou značkou) s existujícím analyzátorem. Můžete vyměnit JEditorPaneAnalyzátor s lepším, ale to je také hodně práce. Rozhodl jsem se pro jednodušší řešení, která svou práci zvládla. Vložil jsem do své třídy dostatek funkcí, abych jej mohl použít k vytvoření uživatelského rozhraní pro program, který jsem psal, ale neposkytl jsem „dokonalé“ řešení. Problém, který jsem řešil, byl: poskytnout způsob, jak určit uživatelské rozhraní v HTML. Problém jsem nevyřešil: poskytněte způsob, jak zobrazit všechny možné HTML v aplikaci na straně klienta. The HTMLPane třída, kterou v tomto článku představuji, pěkně řeší problém specifikovat-a-UI-v-HTML.

Pomocí HTMLPane

Moje třída vstupu HTML pouze na straně klienta, HTMLPane, je JEditorPane derivát, který řeší dříve diskutované problémy. Výpis 1 ukazuje, jak používat HTMLPane. Vytvořil jsem jednoduchý JDialog derivát nazvaný HtmlDialog ve kterém můžete určit rozvržení dialogového okna jako HTML. The HtmlDialog je triviální příklad vzorového návrhu fasády. Je to jen práce, která je nutná k vložení HTMLPane do dialogového okna a zobrazit jej.

The HtmlDialog.Test třída (Výpis 1, řádek 134) poskytuje jednoduchý příklad, jak používat HtmlDialog. Vytvoří většinou prázdný hlavní snímek (majitel). Pomocí kódu, jako je úryvek uvedený níže, hlavní() vytváří HtmlDialog objekt, jehož obsah je specifikován v relativním souboru CLASSPATH com / holub / ui / HTML / test / okay.html (Výpis 2). Řetězec „Test HtmlDialog“ se zobrazí v záhlaví. Konečně, hlavní() otevře dialogové okno voláním d.popup (), který se nevrátí, dokud uživatel nevypne dialog:

// Zobrazí soubor okay.html v dialogovém okně, které má// název „Test HtmlDialog“.// HtmlDialog dialog = nový HtmlDialog (owning_frame, "com / holub / ui / HTML / test / okay.html", "Test HtmlDialog"); // Otevřete dialogové okno a počkejte, až jej uživatel zavře.// dialog.popup (); // Vytiskne data „formuláře“, která zadal uživatel.// System.out.println ("hidden =" + dialog.data (). GetProperty ("skryté") + "uživatelský vstup" + dialog.data (). GetProperty ("uživatelský vstup")); 

Data formuláře (text, který uživatel zadal do prvek nebo ekvivalent), je k dispozici prostřednictvím HtmlDialogje data() metoda, která vrací a java.util.Vlastnosti objekt, který obsahuje páry klíč / hodnota představující data formuláře. Výše uvedené volání na dialog.data (). getProperty ("skryté") vrací řetězec „data skrytého pole“. The dialog.data (). getProperty ("vstup uživatele") volání vrátí vše, co uživatel zadal do vstupního pole.

Většina práce spočívala v instanci zapouzdřeného HTMLPane se stane v HtmlDialog konstruktor (výpis 1, řádek 46). Konstruktor nejprve nastaví ActionListener který zpracovává tlačítko Odeslat ve formuláři. Tento pozorovatel vypne aktuální dialogové okno a zkopíruje veškerá data formulářů z HTMLPane do data proměnná instance. Konstruktor poté získá vstupní soubor z CLASSPATH a poté načte HTML do souboru HTMLPane použitím setText (). (K dispozici je také setPage (URL) metoda, ale pokud byste ji použili, budete potřebovat URL pro absolutní cestu k souboru. Chtěl jsem, aby název souboru HTML byl relativní CLASSPATH.)

Zrušení zpracování je zpracováno vyskakovat() (řádek 121), který předpokládá, že bylo stisknuto tlačítko Storno, pokud v odeslaných datech formuláře existuje klíč Storno. (Více o tom, jak se tato data dostanou do Vlastnosti objekt za okamžik.)

$config[zx-auto] not found$config[zx-overlay] not found