Buat antarmuka pengguna sisi klien di HTML, Bagian 1

Bulan ini saya akan kembali ke pemrograman untuk sementara waktu. Saya butuh istirahat dari keanehan pada pembahasan Talkback di kolom bulan lalu. Saya memang bermaksud untuk menulis lebih banyak tentang masalah teori di masa depan, namun tidak untuk beberapa bulan ke depan.

Saya perlu membuat satu klarifikasi dari kolom bulan lalu. Banyak orang menafsirkan komentar saya tentang antarmuka pengguna sebagai menganjurkan objek kelas berat dengan miliaran metode rendering di dalamnya. Bukan itu yang ada dalam pikiran saya. Ada banyak cara yang layak untuk membuat antarmuka pengguna (UI) tanpa memperlihatkan detail implementasi. Pola Gang of Four Builder dan Pengunjung segera muncul di pikiran. drawYourself()Metode sederhana jelas tidak dapat bekerja pada apa pun kecuali objek yang paling sederhana, dan memiliki 50 drawYourselfInThisFormat()dan drawYourselfInThatFormat()metode adalah resep yang tidak masuk akal untuk kode yang tidak dapat diatur. Namun, banyak orang berpikir saya menganjurkan pendekatan itu, jadi saya minta maaf jika saya memberikan kesan itu.

Karena saya telah melihat banyak kesalahpahaman mengenai masalah UI, saya akan berencana untuk menunjukkan kepada Anda beberapa implementasi pendekatan pembangunan UI berorientasi objek (OO) di kolom mendatang. Saya mempresentasikan satu solusi seperti itu di JavaWorld beberapa tahun yang lalu (lihat Sumber), tetapi saya telah membangun sistem yang lebih baik dalam beberapa tahun terakhir. Kolom saat ini menyajikan bagian dari salah satu sistem UI ini: kelas infrastruktur yang saya gunakan dalam membangun UI sisi klien dengan cara OO. Itu sendiri bukan solusi untuk masalah UI, tetapi ini adalah blok penyusun yang berguna.

Karena sampel kodenya agak besar, saya akan memecah presentasi menjadi dua bagian. Bulan ini adalah dokumentasi dan kode aplikasi; bulan depan adalah kode sumber.

Baca keseluruhan seri "Membuat Antarmuka Pengguna Sisi Klien di HTML":

  • Bagian 1: Jadikan JEditorPane berguna (Oktober 2003)
  • Bagian 2: Sumber HTMLPane (November 2003)

Menggunakan HTML di sisi klien

HTML adalah hal yang luar biasa. Ini memungkinkan Anda mengatur antarmuka pengguna yang rumit dengan sedikit keributan; itu berfungsi dengan baik dalam memisahkan struktur UI dan tata letak dari logika bisnis; mudah untuk menulis; dan mudah dirawat. Abstrak Window Toolkit (AWT) / Swing layout, sebaliknya, sangat sulit digunakan. Anda harus memodifikasi (dan mengkompilasi ulang) kode untuk mengubah tampilan layar Anda, dan kode untuk tata letak yang sepele itu sendiri tidak sepele, meluas ke banyak halaman. Bukankah lebih baik jika Anda dapat menentukan seluruh antarmuka pengguna sisi klien Anda dalam HTML?

(Saya tahu bahwa beberapa dari Anda akan menjawab pertanyaan sebelumnya dengan meriah "Tidak, itu tidak menyenangkan!" Banyak yang berpendapat bahwa HTML dan pengalaman pengguna yang baik adalah konsep yang saling eksklusif, karena HTML memaksa antarmuka pengguna Anda menjadi "mengalir tanpa batas kotak dialog "mode. Di sisi lain, banyak aplikasi dapat memanfaatkan HTML secara efektif setidaknya di beberapa bagian antarmuka pengguna — untuk laporan tabel jika tidak ada yang lain. Anda tidak dapat membuang bayi dengan air mandi.)

JEditorPaneKelas Swing , pada awalnya, tampaknya menjadi jawaban untuk masalah tata letak HTML. Itu memahami input HTML setelah mode. Misalnya, kode berikut memunculkan bingkai yang menampilkan beberapa teks HTML sederhana:

JFrame main_frame = JFrame baru (); JEditorPane pane = new JEditorPane (); pane.setContentType ("text / html"); pane.setEditable (false); pane.setText ("" + "" + "" + "" + " Hello World " + "" + ""); main_frame.setContentPane (pane); main_frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); main_frame.pack (); main_frame.show ();

Saya mengatakan "setelah mode" karena JEditorPanetidak terlalu pandai menangani HTML yang kompleks. Itu tidak melakukan pekerjaan yang baik dengan tabel bersarang, dan tidak melakukan Cascading Style Sheets (CSS) dengan sangat baik. (Saya telah diberitahu bahwa banyak dari masalah ini akan diperbaiki pada rilis Java 1.5 tahun depan, tetapi untuk saat ini, kita semua harus mengatasinya.) Akhirnya, JEditorPanetidak melakukan pekerjaan yang sangat baik dalam meletakkan keluar hal-hal seperti tombol radio. Mereka tidak sejajar dengan benar dengan garis dasar teks, dan mereka selalu menampilkan latar belakang abu-abu, jadi mereka tidak berfungsi dengan baik jika Anda mengubah warna latar belakang halaman (dengan gaya pada tag, misalnya).

Semua kekurangan ini mengganggu, tetapi masalah show-stopper JEditorPaneadalah bahwa ia berfungsi sebagai kontrol teks, bukan sebagai fasilitas tata letak. Anda dapat menentukan HTML di masukan, misalnya, tetapi formulir dikirim ke server Web saat Anda menekan tombol Kirim. Agar berguna untuk menentukan UI sisi klien, Anda ingin data formulir kembali ke program yang menampilkan formulir, bukan ke server jauh. Anda juga memerlukan cara yang mudah untuk menambahkan tag kustom untuk input atau tampilan yang tidak standar atau untuk menyediakan placeholder untuk Swing standar JComponentsyang ingin Anda gunakan pada formulir. ( JEditorPanememungkinkan Anda melakukan ini, tetapi mekanismenya jauh dari nyaman.) Akhirnya, Anda perlu menangani hal-hal seperti tombol Batal, yang tidak ada di HTML.

Untungnya, masalah yang paling mengerikan di atas dapat diselesaikan dengan menggunakan fasilitas kustomisasi yang terpasang di JEditorPanedalamnya. Memperbaiki masalah ini melibatkan sejumlah kompromi. Misalnya, Anda dapat menangani masalah tombol Batal dengan mengimplementasikan interpreter JavaScript dan mendukung onclickatributnya, tetapi itu pekerjaan yang sangat banyak. Demikian pula, memberikan dukungan tag khusus yang sebenarnya (di mana Anda dapat memproses semua yang ada di antara tag awal dan akhir) sangat sulit dilakukan dengan parser yang ada. Anda bisa menggantiJEditorPaneparser dengan yang lebih baik, tapi itu banyak pekerjaan juga. Saya memilih solusi yang lebih sederhana yang berhasil. Saya memberikan fungsionalitas yang cukup di kelas saya sehingga saya dapat menggunakannya untuk membangun antarmuka pengguna untuk program yang saya tulis, tetapi tidak memberikan solusi yang "sempurna". Masalah yang saya selesaikan adalah: menyediakan cara untuk menentukan antarmuka pengguna dalam HTML. Saya tidak memecahkan masalah: berikan cara untuk menampilkan semua kemungkinan HTML dalam aplikasi sisi klien. The HTMLPanekelas I hadir dalam artikel ini memecahkan menentukan-a-UI-in-HTML masalah baik.

Menggunakan HTMLPane

Kelas input HTML khusus sisi klien saya HTMLPane,, adalah JEditorPaneturunan yang memperbaiki masalah yang dibahas sebelumnya. Kode 1 menunjukkan bagaimana menggunakan file HTMLPane. Saya membuat JDialogturunan sederhana yang disebut HtmlDialogdi mana Anda dapat menentukan tata letak kotak dialog sebagai HTML. Ini HtmlDialogadalah contoh sederhana dari pola desain Façade. Itu hanya melakukan pekerjaan hafalan yang diperlukan untuk dimasukkan HTMLPaneke dalam kotak dialog dan menampilkannya.

The HtmlDialog.Testclass (Listing 1, baris 134) memberikan contoh sederhana bagaimana menggunakan HtmlDialog. Ini membuat bingkai utama yang sebagian besar kosong ( owner). Menggunakan kode seperti cuplikan yang direproduksi di bawah ini, main()membuat HtmlDialogobjek yang isinya ditentukan dalam file relatif CLASSPATH com/holub/ui/HTML/test/okay.html(Daftar 2). String tersebut "Test HtmlDialog"muncul di bilah judul. Terakhir, main()munculkan dialog dengan memanggil d.popup(), yang tidak akan kembali hingga pengguna menutup dialog:

// Tampilkan file okay.html dalam kotak dialog yang // berjudul "Test HtmlDialog". // Dialog HtmlDialog = HtmlDialog baru (owning_frame, "com / holub / ui / HTML / test / okay.html", "Uji HtmlDialog"); // Munculkan dialog dan tunggu pengguna menutupnya. // dialog.popup (); // Cetak data "formulir" yang diketik pengguna. // System.out.println ("hidden =" + dialog.data (). GetProperty ("hidden") + "user-input" + dialog.data (). GetProperty ("user-input"));

Data formulir (teks yang diketik pengguna ke dalam elemen atau yang setara), tersedia melalui metode HtmlDialog's data(), yang mengembalikan java.util.Propertiesobjek yang menyimpan pasangan kunci / nilai yang mewakili data formulir. Panggilan di atas untuk dialog.data().getProperty("hidden")mengembalikan string "hidden-field data". The dialog.data().getProperty("user-input")panggilan kembali apa pun pengguna diketik ke dalam field input.

Sebagian besar pekerjaan yang terlibat dalam pembuatan instance yang dienkapsulasi HTMLPaneterjadi di HtmlDialogkonstruktor (Daftar 1, baris 46). Konstruktor pertama-tama menyiapkan ActionListeneryang menangani tombol Kirim pada formulir. Observer ini menutup kotak dialog saat ini dan menyalin data formulir apa pun dari HTMLPaneke datavariabel contoh. Konstruktor kemudian mendapatkan file input dari CLASSPATH, dan kemudian memuat HTML ke dalam HTMLPaneuse setText(). (Ada juga setPage(URL)metode, tetapi Anda akan membutuhkan URL untuk jalur absolut ke file jika Anda menggunakannya. Saya ingin nama file HTML menjadi relatif CLASSPATH.)

Pemrosesan batal ditangani di popup()(baris 121), yang mengasumsikan bahwa tombol Batal telah ditekan jika tombol Batal ada dalam data formulir yang dikirimkan. (Lebih lanjut tentang bagaimana data itu masuk ke Propertiesobjek dalam sekejap.)