Monday, December 19, 2016

Bab 4. Java Struktur Data dan Pemrograman GUI


Bab.4 GUI

Tujuan Instruksional
·         Menciptakan GUI (graphical user interface) menggunakan beberapa komponen antarmuka-pengguna: JButton, JCheckBox, JRadioButton, JLabel, JTextField, JTextArea, JComboBox, JList, JScrollBar, dan JSlider.
·         Menciptakan listener untuk berbagai tipe event.
·         Mengeksplorasi JButton.
·         Mengeksplorasi JCheckBox.
·         Mengeksplorasi JRadioButton.
·         Mengekplorasi JLabel.
·         Mengeksplorasi JTextLaField.
·         Mengeksplorasi JTextArea.
·         Mengeksplorasi JComboBox.
·         Mengeksplorasi JList.
·         Mengeksplorasi JScrollBar.
·         Mengeksplorasi JSlider.
·         Menampilkan beberapa jendela dalam suatu aplikasi.

4.1 Introduksi

GUI (graphical user interface)  membuat suatu sistem menjadi ramah pengguna dan mudah untuk digunakan. Menciptakan GUI memerlukan kreativitas dan pengetahuan bagaimana komponen-komponen GUI bekerja. Karena komponen-komponen GUI daam JAVA fleksibel dan handal, Anda bisa merancang berbagai antarmuka-pengguna.



Gambar 4.1 Komponen-komponen GUI Swing sering digunakan untuk menciptakan antarmuka-pengguna


Banyak IDE JAVA menyediakan beberapa perangkat untuk secara visual mendesain dan mengembangkan antarmuka GUI. Hal ini memudahkan Anda untuk merakit elemen-elemen antarmuka-pengguna di dalam aplikasi JAVA. Perangkat-perangkat tersebut, tentu saja, tidak bisa melakukan semua hal, akan tetapi, Anda harus memodifikasi program yang dihasilkan. Sebelum Anda mulai menggunakan perangkat-perangkat visual, sebaiknya Anda memahami konsep-konsep dasar pemrograman GUI dalam JAVA.

Bab-bab terdahulu telah mengenalkan beberapa komponen GUI. Bab ini akan mengintroduksi komponen-komponen GUI yang sering digunakan secara mendetil (lihat Gambar 4.1). (Karena bab ini tidak mengenalkan konsep baru, instruktor pemrograman bisa menugaskan bab ini agar dipelajari secara mandiri oleh para siswa).

4.2 Tombol
Tombol merupakan suatu komponen yang memicu event aksi ketika diklik. Swing menyediakan tombol reguler, tombol toggle, tombol kotak periksa, dan tombol radio. Beberapa fitur umum dari tombol-tombol ini didefinisikan di dalam javax.swing.AbstractButton, seperti tertampil pada Gambar 4.2.



Gambar 4.2 AbstractButton mendefinisikan fitur-fitur umum dari berbagai tipe event

Bagian ini akan mengenalkan tombol-tombol reguler yang didefinisikan di dalam kelas JButton. Kelas JButton mewarisi AbstractButton dan menyediakan beberapa konstruktor untuk menciptakan tombol, seperti tertampil pada Gambar 4.3.


4.2.1 Ikon, Ikon Pressed, dan Ikon Rollover
Tombol reguler memiliki suatu ikon default, ikon pressed, dan ikon rollover. Normalnya, Anda menggunakan ikon default. Kedua ikon lain adalah untuk efek visual. Ikon pressed tampilkan ketika tombol ditekan, sedangkan ikon rollover ditampilkan ketika mouse berada di atas tombol. Sebagai contoh, kode4.1 menampilkan gambar Bendera Merah Putih sebagai ikon reguler, Bendera Singapura sebagai ikon pressed, Bendera Thailand sebagai ikon rollover, seperti tertampil pada Gambar 4.4.

Gambar 4.3 JButton mendefinisikan tombol reguler


Gambar 4.4 Tombol memiliki beberapa tipe ikon


Kode4.1 UjiIkonTombol.java

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
import javax.swing.*;

public class UjiIkonTombol extends JFrame {
  public static void main(String[] args) {
    // Menciptakan frame dan menetapkan propertinya
    JFrame frame = new UjiIkonTombol();
    frame.setTitle("IkonTombol");
    frame.setSize(200, 100);
    frame.setLocationRelativeTo(null); // Pusat frame
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
  }

  public UjiIkonTombol() {
    ImageIcon indoIkon = new ImageIcon("Gambar/bendera_merah_putih.gif");
    ImageIcon singIkon = new ImageIcon("Gambar/bendera_singapura.gif");
    ImageIcon thaiIkon = new ImageIcon("Gambar/bendera_thailand.gif");

    JButton jbt = new JButton("Silahkan klik", indoIkon);
    jbt.setPressedIcon(singIkon);
    jbt.setRolloverIcon(thaiIkon);

    add(jbt);
  }
}

4.2.2 Penyejajaran
Penyejajaran horisontal menspesifikasi bagaimana ikon dan teks ditempatkan secara horisontal pada suatu tombol. Anda dapat menetapkan penyejajaran horisontal menggunakan setHorizontalAlignment(int) dengan salah satu dari lima konstanta LEADING, LEFT, CENTER, RIGHT, TRAILING, seperti tertampil pada Gambar 4.5. Pada kesempatan ini, LEADING dan LEFT sama, dan TRAILING dan RIGHT juga sama. Pada implementasi selanjutnya, akan ditunjukkan perbedaannya. Penyejajaran horisontal default adalah SwingConstants.CENTER.


Gambar 4.5 Anda bisa menentukan bagaimana ikon dan teks ditempatkan pada tombol secara horisontal

Penyejajaran vertikal menspesifikasi bagaimana ikon dan teks ditempatkan secara horisontal pada suatu tombol. Anda dapat menetapkan penyejajaran horisontal menggunakan setVerticalAlignment(int) dengan salah satu dari lima konstanta TOP, CENTER, BOTTOM, seperti tertampil pada Gambar 4.6. Penyejajaran horisontal default adalah SwingConstants.CENTER.


Gambar 4.6 Anda bisa menentukan bagaimana ikon dan teks ditempatkan pada tombol secara vertikal


4.2.3 Posisi Teks
Posisi teks horisontal menetapkan posisi horisontal suatu teks relatif terhadap ikon. Anda bisa menetapkan posisi teks horisontal menggunakan setHorizontalTextPosition(int) dengan salah satu dari lima konstanta LEADING, LEFT, CENTER, RIGHT, TRAILING, seperti tertampil pada Gambar 4.7. Pada kesempatan ini, LEADING dan LEFT sama, dan TRAILING dan RIGHT juga sama. Pada implementasi selanjutnya, akan ditunjukkan perbedaannya. Posisi teks horisontal default adalah SwingConstants.CENTER.

Gambar 4.7 Anda bisa menentukan posisi teks horisontal relatif terhadap ikon

Posisi teks vertikal menetapkan posisi vertikal suatu teks relatif terhadap ikon. Anda bisa menetapkan posisi teks vertikal menggunakan setVerticalTextPosition(int) dengan salah satu dari tiga konstanta TOP, CENTER, BOTTOM, seperti tertampil pada Gambar 4.8. Posisi teks vertikal default adalah SwingConstants.CENTER.

Gambar 4.8 Anda bisa menentukan posisi teks vertikal relatif terhadap ikon

JButton dapat memicu banyak tipe event, tetapi seringkali Anda perlu menambahkan listener untuk merespon event aksi. Ketika tombol ditekan, tombol tersebut akan memicu suatu ActionEvent.


4.2.4 Menggunakan Tombol
Bagian ini akan menyajikan suatu contoh, seperti tertampil pada kode4.2, yang menampilkan pesan pada panel menggunakan dua tombol <= dan =>, untuk menggerakkan pesan ke kiri atau ke kanan. Tata-letak GUI ditampilkan pada Gambar 4.9. Berikut merupakan langkah-langkah utama program:
1.  Menciptakan antarmuka pengguna
Menciptakan suatu objek PanelPesan untuk menampilkan pesan. Kelas PanelPesan diciptakan pada kode2.8, PanelPesan.java. Kemudian, objek tersebut ditempatkan di tengah frame. Dua tombol <= dan => diciptakan pada panel. Panel ditempatkan di bagian selatan frame.
2.  Memproses event
Menciptakan dan meregistrasi listener untuk pemrosesan event aksi dalam menggerakkan pesan ke kiri atau ke kanan tergantung dari apakah tombol kiri atau tombol kanan yang diklik.



Gambar 4.9 Pengklikan <= dan => menyebabkan pesan pada panel bergerak ke kiri dan ke kanan


Kode4.2 DemoTombol.java

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
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.*;

public class DemoTombol extends JFrame {
  // Menciptakan panel untuk menampilkan pesan
  protected PanelPesan panelPesan
    = new PanelPesan("JAVA itu Tangguh!");

  // Mendeklarasikan dua tombol untuk menggerakkan pesan ke kiri dan ke kanan
  private JButton jbtKiri = new JButton("<=");
  private JButton jbtKanan = new JButton("=>");

  public static void main(String[] args) {
    DemoTombol frame = new DemoTombol();
    frame.setTitle("DemoTombol");
    frame.setSize(250, 100);
    frame.setLocationRelativeTo(null); // Pusat frame
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
  }

  public DemoTombol() {
    // Menetapkan warna latar belakang untuk panelPesan
    panelPesan.setBackground(Color.white);

     // Menciptakan Panel jpTombol untuk memuat dua tombol "<=” dan “right =>"
    JPanel jpTombol = new JPanel();
    jpTombol.add(jbtKiri);
    jpTombol.add(jbtKanan);

    // Menetapkan papankunci mnemonik
    jbtKiri.setMnemonic('I');
    jbtKanan.setMnemonic('A');

    // Menetapkan ikon dan menghapus teks
    // jbtKiri.setIcon(new ImageIcon("Gambar/kiri.gif"));
    // jbtKanan.setIcon(new ImageIcon("Gambar/kanan.gif"));
    // jbtKiri.setText(null);
    // jbtKanan.setText(null);

    // Menetapkan perangkat tool tip text pada tombol
    jbtKiri.setToolTipText("Menggerakkan pesan ke kiri");
    jbtKanan.setToolTipText("Menggerakkan pesan ke kanan");

    // Menampilkan panel di dalam frame
    setLayout(new BorderLayout());
    add(panelPesan, BorderLayout.CENTER);
    add(jpTombol, BorderLayout.SOUTH);

    // Meregistrasi listener dengan tombol
    jbtKiri.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        panelPesan.geserKiri();
      }
    });
    jbtKanan.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        panelPesan.geserKanan();
      }
    });
  }
}

panelPesan (baris 8) sengaja dideklarasikan protected agar dapat direferensi oleh suatu subkelas di masa mendatang.

Anda bisa menetapkan citra ikon pada tombol menggunakan metode setIcon. Jika anda menghapus // pada kode berikut (baris 38-41):

    // Menetapkan ikon dan menghapus teks
    // jbtKiri.setIcon(new ImageIcon("Gambar/kiri.gif"));
    // jbtKanan.setIcon(new ImageIcon("Gambar/kanan.gif"));
    // jbtKiri.setText(null);
    // jbtKanan.setText(null);

maka teks akan digantikan oleh ikon, seperti tertampil pada Gambar 4.10.


Gambar 4.10 Anda bisa menetapkan ikon pada JButton dan mengakses tombol menggunakan kunci mnemonik

Menekan Alt+I ekivalen dengan menekan tombol <= dan menekan Alt+A ekivalen dengan menekan tombol =>.

4.3 Kotak Periksa
Tombol toggle merupakan suatu tombol dua-keadaan seperti saklar lampu. JToggleButton mewarisi AbstractButton dan mengimplementasikan suatu tombol toggle. Seringkali sub-subkelas dari JToggleButton, JCheckBox dan JRadioButton digunakan untuk memampukan pengguna melakukan toggle suatu pilihan menjadi on atau off. Bagian ini akan mengenalkan JCheckBox dan JRadioButton akan dikenalkan pada bagian selanjutnya.

JCheckBox mewarisi semua properti dari AbstractButton, seperti text, icon, mnemonic, verticalAlignment, horizontalAlignment, horizontalTextPosition, verticalTextPosition, dan selected, dan menyediakan beberapa konstruktor untuk memeriksa kotak, seperti tertampil pada Gambar 4.11.


Gambar 4.11 JCheckBox mendefinisikan suatu tombol kotak periksa

Berikut merupakan contoh kotak periksa dengan teks Mahasiswa, warna latar depan red, warna latar belakang white, kunci mnemonik ‘M’, dan awalnya diseleksi:
JCheckBox jchk = new JCheckBox("Mahasiswa", true);
jchk.setForeground(Color.RED);
jchk.setBackground(Color.WHITE);
jchk.setMnemonic('M');

Ketika kotak periksa diklik (diseleksi atau tidak), kotak tersebut memicu suatu ItemEvent dan kemudian suatu ActionEvent. Untuk melihat apakah kotak periksa diseleksi atau tidak, digunakan metode isSelected().

Kode4.3 memberikan suatu program yang menambahkan tiga kotak periksa yang dinamai  Ditengahkan, Tebal, dan Miring kepada contoh terdahulu untuk mengijinkan pengguna dalam memeriksa apakah pesan ditengahkan, ditebalkan atau dimiringkan, seperti tertampil pada Gambar 4.12.


ambar 4.12 Tiga kotak periksa ditambahkan untuk menentukan bagaimana pesan ditampilkan

Kode4.3 DemoKotakPeriksa.java

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
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DemoKotakPeriksa extends DemoTombol{
  // Menciptakan tiga kotak periksa untuk mengendalikan penampilan pesan
  private JCheckBox jchkDitengahkan = new JCheckBox("Ditengahkan");
  private JCheckBox jchkTebal = new JCheckBox("Tebal");
  private JCheckBox jchkMiring = new JCheckBox("Miring");

  public static void main(String[] args) {
    DemoKotakPeriksa frame = new DemoKotakPeriksa();
    frame.setTitle("DemoKotakPeriksa");
    frame.setSize(500, 200);
    frame.setLocationRelativeTo(null); // Pusat frame
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
  }

  public DemoKotakPeriksa() {
    // Menetapkan kunci-kunci mnemonik
    jchkDitengahkan.setMnemonic('D');
    jchkTebal.setMnemonic('T');
    jchkMiring.setMnemonic('M');

    // Menciptakan suatu panel untuk memuak kotak-kota periksa
    JPanel jpCheckBoxes = new JPanel();
    jpCheckBoxes.setLayout(new GridLayout(3, 1));
    jpCheckBoxes.add(jchkDitengahkan);
    jpCheckBoxes.add(jchkTebal);
    jpCheckBoxes.add(jchkMiring);
    add(jpCheckBoxes, BorderLayout.EAST);

    // Meregistrasi listener dengan kotak periksa
    jchkDitengahkan.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
         panelPesan.tetapkanDitengah(jchkDitengahkan.isSelected());
      }
    });
    jchkTebal.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        setNewFont();
      }
    });
    jchkMiring.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        setNewFont();
      }
    });
  }

  private void setNewFont() {
    // Menetapkan gaya font
    int fontStyle = Font.PLAIN;
    fontStyle += (jchkTebal.isSelected() ? Font.BOLD : Font.PLAIN);
    fontStyle += (jchkMiring.isSelected() ? Font.ITALIC : Font.PLAIN);

    // Menetapkan font untuk pesan
    Font font = panelPesan.getFont();
    panelPesan.setFont(
      new Font(font.getName(), fontStyle, font.getSize()));
  }
}     

DemoKotakPeriksa mewarisi DemoKotak dan menambahkan tiga kotak periksa untuk mengendalikan bagaimana pesan ditampilkan. Ketika suatu DemoKotakPeriksa dikonstruksi (baris 12), konstruktor tanpa-argument dari superkelasnya dipanggil, sehingga Anda tidak perlu menulis-ulang kode yang telah ada di dalam konstruktor DemoKotak.

Ketika kotak periksa diseleksi atau tidak, listener dari metode actionPerformed dipanggil untuk memproses event. Ketika kotak periksa Ditengah diseleksi atau tidak diseleksi, properti ditengah pada kelas PanelPesan ditetapkan bernilai true atau false.

Nama font dan ukuran sekarang yang digunakan dalam PanelPesan didapatkan dari panelPesan.getFont() menggunakan metode getName() dan getSize(). Gaya font (Font.BOLD dan Font.ITALIC) dispesifikasi di dalam kotak periksa. Jika tidak ada gaya font yang diseleksi, maka gaya font default adalah Font.PLAIN.

Mnemonik papankunci D, T, dan M ditetapkan di dalam kotak periksa Ditengahkan, Tebal, dan Miring (baris 22-24). Anda bisa menggunakan klik mouse atau kunci pintas untuk menyeleksi suatu kotak periksa.

Metode setFont (baris 60) yang didefinisikan di dalam kelas Component diwariskan dalam kelas PanelPesan. Metode ini secara otomatis memanggil metode repaint. Pemanggilan setFont di dalam panelPesan secara otomatis menggambar-ulang pesan.

Kotak periksa memicu suatu ActionEvent dan ItemEvent ketika diklik. Anda dapat memproses salah satu ActionEvent atau ItemEvent untuk menampilkan-ulang pesan. Contoh tersebut memproses ActionEvent. Untuk memproses ItemEvent, perlu diciptakan suatu listener untuk ItemEvent dan meregistrasikannya dengan suatu kotak periksa. Listener harus mengimplementasikan handler itemStateChange untuk memproses ItemEvent. Sebagai contoh, kode berikut meregistrasi ItemListener dengan jchkDitengah:

// Merespon ItemEvent
jchkDitengah.addItemListener(new ItemListener() {
  /** Menangani ItemEvent */
  public void itemStateChanged(ItemEvent e) {
    messagePanel.setCentered(jchkDitengah.isSelected());
  }
});


4.4 Tombol Radio
Tombol radio, juga dikenal dengan tombol opsi, memampukan Anda untuk memilih pilihan tunggal dari sejumlah pilihan. Dalam penampilannya, tombol radio mirip dengan kotak periksa, tetapi kotak periksa menampilkan kotak untuk diseleksi atau kosong, sedangkan tombol radio menampilkan lingkaran terisi (bila diseleksi) atau kosong (bila tidak diseleksi).

JRadioButton mewarisi AbstractButton dan menyediakan beberapa konstruktor untuk menciptakan tombol radio, seperti tertampil pada Gambar 4.13. Konstruktor-konstruktor tersebut sama dengan konstruktor-konstruktor JCheckBox.

Berikut merupakan contoh tombol radio dengan teks Mahasiswa, warna latar depan red, warna latar belakang white, kunci mnemonik T, dan awalnya terseleksi:

JRadioButton jrb = new JRadioButton("Mahasiswa", true);
jrb.setForeground(Color.RED);
jrb.setBackground(Color.WHITE);
jrb.setMnemonic('T');

Untuk mengelompokkan tombol-tombol radio, Anda perlu menciptakan instans dari java.swing.ButtonGroup dan menggunakan metode add untuk menambahkan tombol-tombol tersebut kepada instans yang telah diciptakan:

ButtonGroup grup = new ButtonGroup();
grup.add(jrb1);
grup.add(jrb2);

Kode ini menciptakan sekelompok tombol radio jrb1 dan jrb2 sehingga dapat diseleksi secara eksklusif mutualis. Tanpa pengelompokan, jrb1 dan jrb2 akan independen satu sama lain.


Gambar 4.13 JRadioButton mendefinisikan suatu tombol radio


Ketika suatu tombol radio diubah (diseleksi atau dideseleksi), tombol tersebut memicu ItemEvent dan kemudian ActionEvent. Untuk melihat apakah tombol radio diseleksi atau tidak, dapat digunakan metode isSelected().

Kode4.4 menyajikan suatu program yang menambahkan tiga tombol radio bernama Merah, Hijau, dan Biru kepada contoh terdahulu untuk mengijinkan pengguna memilih warna pesan, seperti tertampil pada Gambar 4.14.

Kode4.4 DemoTombolRadio.java

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
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DemoTombolRadio extends DemoKotakPeriksa{
  // Mendeklarasikan tombol-tombol radio
  private JRadioButton jrbMerah, jrbHijau, jrbBiru;

  public static void main(String[] args) {
    DemoTombolRadio frame = new DemoTombolRadio();
    frame.setSize(500, 200);
    frame.setLocationRelativeTo(null); // Pusat frame
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setTitle("DemoTombolRadio");
    frame.setVisible(true);
  }

  public DemoTombolRadio() {
    // Menciptakan suatu panel baru untuk memuat kotak-kotak periksa
    JPanel jpRadioButtons = new JPanel();
    jpRadioButtons.setLayout(new GridLayout(3, 1));
    jpRadioButtons.add(jrbMerah = new JRadioButton("Merah"));
    jpRadioButtons.add(jrbHijau = new JRadioButton("Hijau"));
    jpRadioButtons.add(jrbBiru = new JRadioButton("Biru"));
    add(jpRadioButtons, BorderLayout.WEST);

    // Menciptakan sekelompok tombol-radio untuk mengelompokkan tiga tombol
    ButtonGroup group = new ButtonGroup();
    group.add(jrbMerah);
    group.add(jrbHijau);
    group.add(jrbBiru);

    // Menetapkan mnemonik papankunci
    jrbMerah.setMnemonic('E');
    jrbHijau.setMnemonic('J');
    jrbBiru.setMnemonic('U');

    // Meregistrasikan listener untuk tombol radio
    jrbMerah.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        panelPesan.setForeground(Color.red);
      }
    });
    jrbHijau.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        panelPesan.setForeground(Color.green);
      }
    });
    jrbBiru.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        panelPesan.setForeground(Color.blue);
      }
    });

    // Menetapkan warna pesan awal menjadi biru
    jrbBiru.setSelected(true);
    panelPesan.setForeground(Color.blue);
  }
}


Gambar 4.14 Tiga tombol radio ditambahkan untuk menentukan warna pesan


DemoTombolRadio mewarisi DemoKotakPeriksa dan menambahkan tiga tombol radio untuk menentukan warna pesan. Ketika tombol radio diklik, listener dari event aksi menetapkan warna latar depan tertentu pada panelPesan.

Mnemonik papankunci ‘E’, ‘J’, dan ‘U’ ditetapkan pada tombol radio Merah, Hijau, dan Biru (baris 34-36).

Program menciptakan suatu ButtonGroup dan menempatkan tiga instans dari JRadioButton (jrbMerah, jrbHijau, dan jrbBiru) ke dalam grup tersebut (baris 28-31).

Suatu tombol radio memicu ActionEvent dan ItemEvent ketika diseleksi atau dideseleksi. Anda bisa memproses salah satu ActionEvent atau ItemEvent untuk memilih warna. Pada contoh ini, ActionEvent yang diproses.

4.5 Label
Label adalah area untuk menampilkan teks pendek, citra, atau keduanya. Seringkali digunakan untuk memberikan label pada kompone-komponen lain (biasanya bidang teks). Gambar 4.15 menampilkan metode-metode dan konstruktor-konstruktor di dalam kelas JLabel.

JLabel mewarisi semua properti dari JComponent dan memiliki banyak properti yang sama dengan yang ada dalam kelas JButton, seperti, icon, text, horizontalAlignment, verticalAlignment, horizontalTextPosition, verticalTextPosition, dan iconTextGap. Sebagai contoh, berikut adalah kode untuk menampilkan suatu label dengan teks dan ikon:

// Menciptakan suatu citra ikon dari file citra
ImageIcon ikon = new ImageIcon("Gambar/bendera.gif");

// Menciptakan suatu label dengan teks, ikon,
// dengan penyejajaran horisontal ditengahkan
JLabel jlbl = new JLabel("Bendera", ikon, SwingConstants.CENTER);

// Menetapkan penyejajaran teks pada label
// dan jarak antara teks dan ikon
jlbl.setHorizontalTextPosition(SwingConstants.CENTER);
jlbl.setVerticalTextPosition(SwingConstants.BOTTOM);
jlbl.setIconTextGap(5);


Gambar 4.15 JLabel menampilkan teks, ikon, atau keduanya


4.6 Bidang Teks
Bidang teks dapat digunakan untuk mengentrikan atau menampilkan string. JTextField merupakan subkelas dari JTextComponent. Gambar 4.16 menampilkan konstruktor-konstruktor dan metode-metode di dalam kelas JTextField.

JTextField mewarisi JTextComponent, yang mewarisi JComponent. Berikut adalah contoh menciptakan suatu bidang teks dengan warna latar merah dan penyejajaran horisontal kanan:

JTextField  jtfPesan = new JTextField("Klaten");
jtfPesan.setForeground(Color.RED);
jtfPesan.setHorizontalAlignment(SwingConstants.RIGHT);

Ketika Anda memindahkan kursor mouse di dalam bidang teks dan menekan ENTER, hal ini akan memicu ActionEvent.

Kode4.5 menyajikan suatu contoh program yang menambahkan bidang teks pada contoh terdahulu untuk mengijinkan pengguna untuk memasukkan pesan baru, seperti tertampil pada Gambar 4.17.

Gambar 4.16 JTextField memampukan Anda untuk memasukkan atau menampilkan string


Gambar 4.17 Suatu label dan bidang teks ditambahkan untuk menetapkan pesan baru


Kode4.5 DemoBidangTeks.java

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
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DemoBidangTeks extends DemoTombolRadio{
  private JTextField jtfPesan = new JTextField(10);

  /** Metode utama */
  public static void main(String[] args) {
    DemoBidangTeks frame = new DemoBidangTeks();
    frame.pack();
    frame.setTitle("DemoBidangTeks");
    frame.setLocationRelativeTo(null); // Pusat frame
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
  }

  public DemoBidangTeks() {
    // Menciptakan panel baru untuk memuat label dan bidang teks
    JPanel jpTextField = new JPanel();
    jpTextField.setLayout(new BorderLayout(5, 0));
    jpTextField.add(
      new JLabel("Masukkan suatu pesan"), BorderLayout.WEST);
    jpTextField.add(jtfPesan, BorderLayout.CENTER);
    add(jpTextField, BorderLayout.NORTH);

    jtfPesan.setHorizontalAlignment(JTextField.RIGHT);

    // Meregistrasikan listener
    jtfPesan.addActionListener(new ActionListener() {
      /** Menangani ActionEvent */
      public void actionPerformed(ActionEvent e) {
        panelPesan.tetapkanPesan(jtfPesan.getText());
        jtfPesan.requestFocusInWindow();
      }
    });
  }
}

DemoBidangTeks mewarisi DemoTombolRadio dan menambahkan suatu label dan suatu bidang teks untuk mengijinkan pengguna mengentrikan pesan baru. Setelah Anda menetapkan pesan baru di dalam bidang teks dan menekan kunci ENTER, suatu pesan baru akan tertampil. Penekanan kunci ENTER pada bidang teks akan memicu event aksi. Listener menetapkan pesan baru pada panelPesan (baris 33).

Metode pack() (baris 11) secara otomatis mengubah ukuran frame sesuai dengan ukuran komponen yang ditempatkan di dalamnya.

Metode requestFocusInWindow (baris 34) yang didefinisikan di dalam kelas Component meminta komponen untuk menerima masukan dengan fokus. Jadi, jtfPesan.requestFocusInWindow() meminta masukan dengan fokus pada jtfPesan. Anda akan melihat kursor pada jtfPesan setelah metode actionPerformed dipanggil.


4.7 Area Teks
Jika Anda ingin mengijinkan pengguna untuk memasukkan banyak baris teks, Anda harus menciptakan beberapa instans dari JTextField. Alternatif yang lebih baik adalah menggunakan JTextArea, yang membolehkan pengguna untuk memasukkan banyak baris teks. Gambar 4.18 mencantumkan konstruktor-konstruktor dan metode-metode di dalam JTextArea.

Seperti JTextField, JTextArea mewarisi JTextComponent, yang memuat metode-metode getText, setText, isEditable, dan setEditable. Berikut adalah suatu contoh menciptakan area teks dengan baris 5 dam kolom 20, warna latar depan red, dan font Courier, bold, 20 piksel.

JTextArea  jtaCatat = new JTextArea("Ini adalah area teks", 5, 20);
jtaCatat.setLineWrap(true);
jtaCatat.setWrapStyleWord(true);
jtaCatat.setForeground(Color.red);
jtaCatat.setFont(new Font("Courier", Font.BOLD, 20));


Gambar 4.18 JTextArea memampukan Anda untuk memasukkan atau menampilkan banyak baris karakter

Berikut adalah dua langkah utama di dalam program:
1.  Menciptakan suatu kelas bernama PanelDeskripsi yang mewarisi JPanel, seperti ditunjukkan pada kode4.6. Kelas ini memuat suatu area teks di dalam scroll pane, dan suatu label untuk menampilkan ikon citra dan judul. Kelas ini digunakan di dalam contoh sekarang dan akan digunakan kembali pada contoh-contoh berikutnya.
2.  Menciptakan suatu kelas bernama DemoAreaTeks yang mewarisi JFrame, seperti ditunjukkan pada kode 4.7. Menciptakan instans dari PanelDeskripsi dan menambahkannya pada pusat frame. Relasi antara PanelDeskripsi dan DemoAreaTeks ditunjukkan pada Gambar 4.20.

Kode4.6 PanelDeskripsi.java

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
import javax.swing.*;
import java.awt.*;

public class PanelDeskripsi extends JPanel {
  /** Label untuk menampilkan ikon citra dan teks */
  private JLabel jlbCitraJudul = new JLabel();

  /** Area teks untuk menampilkan teks */
  private JTextArea jtaDeskripsi = new JTextArea();

  public PanelDeskripsi() {
    // Menengahkan ikon dan teks dan menempatkan teks di bawah ikon
    jlbCitraJudul.setHorizontalAlignment(JLabel.CENTER);
    jlbCitraJudul.setHorizontalTextPosition(JLabel.CENTER);
    jlbCitraJudul.setVerticalTextPosition(JLabel.BOTTOM);

    // Menetapkan font dalam label dan bidang teks
    jlbCitraJudul.setFont(new Font("SansSerif", Font.BOLD, 16));
    jtaDeskripsi.setFont(new Font("Serif", Font.PLAIN, 14));

    // Menetapkan lineWrap dan wrapStyleWord bernilai true untuk area teks
    jtaDeskripsi.setLineWrap(true);
    jtaDeskripsi.setWrapStyleWord(true);
    jtaDeskripsi.setEditable(false);

    // Menciptakan suatu scroll pane untuk memuat area teks
    JScrollPane scrollPane = new JScrollPane(jtaDeskripsi);

    // Menetapkan BorderLayout untuk panel, menambahkan label dan scrollpane
    setLayout(new BorderLayout(5, 5));
    add(scrollPane, BorderLayout.CENTER);
    add(jlbCitraJudul, BorderLayout.WEST);
  }

  /** Menetapkan judul */
  public void tetapkanJudul(String judul) {
    jlbCitraJudul.setText(judul);
  }

  /** Menetapkan ikon citra */
  public void tetapkanCitraIkon(ImageIcon ikon) {
    jlbCitraJudul.setIcon(ikon);
  }

  /** Menetapkan deskripsi teks */
  public void tetapkanDeskripsi(String teks) {
    jtaDeskripsi.setText(teks);
  }
}

Area teks berada di dalam JScrollPane (baris 27), yang menyediakan fungsi-fungsi penggeser (scrolling) untuk area teks. Batang penggeser (scroll bar) secara otomatis muncul jika terdapat teks melebihi ukuran fisikal area teks, dan menghilang jika teks dihapus dan sisa teks tidak melebihi ukuran fisikal area teks.

Properti lineWrap ditetapkan bernilai true (baris 22) sehingga baris secara otomatis disatukan ketika teks tidak cukup dalam satu baris. Properti wrapStyleWord ditetapkan bernilai true (baris 23) sehingga baris disatukan dalam kata, bukan dalam karakter. Area teks ditetapkan tidak bisa diedit (baris 24), sehingga Anda tidak bisa mengedit deskripsi di dalam area teks.


Gambar 4.19 Program menampilkan suatu citra di dalam label, suatu teks di dalam label, dan teks di dalam area teks


Gambar 4.20 DemoAreaTeks menggunakan PanelDeskripsi untuk menampilkan suatu citra, judul, dan deskripsi teks


Kode4.7 DemoAreaTeks.java

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
import java.awt.*;
import javax.swing.*;

public class DemoAreaTeks extends JFrame {
  // Mendeklarasikan dan menciptakan suatu panel deskripsi
  private PanelDeskripsi panelDeskripsi = new PanelDeskripsi();

  public static void main(String[] args) {
    DemoAreaTeks frame = new DemoAreaTeks();
    frame.pack();
    frame.setLocationRelativeTo(null); // Pusat frame
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setTitle("DemoAreaTeks");
    frame.setVisible(true);
  }

  public DemoAreaTeks() {
    // Menetapkan judul, teks, dan citra dalam deskripsi panel
    panelDeskripsi.tetapkanJudul("Sistem Operasi");
    String deskripsi = "Sistem Operasi \n\n" +
      "Sistem operasi melakukan beberapa tugas dasar, seperti  " +
      "mengenali masukan dari keyboard, mengirim keluaran ke monitor,  " +
      "menjejak file dan direktori pada disk, dan mengendalikan " +
      "divais-divais periferal (disk drive dan printer). " +
      "Sistem operasi juga harus menjamin bahwa beberapa program   " +
      "dan beberapa pengguna yang berbeda yang berjalan pada saat " +
      "bersamaan tidak akan saling menginterferensi satu sama lain. " +
      "Sistem operasi bertanggung jawab atas keamanan data.";
    panelDeskripsi.tetapkanDeskripsi(deskripsi);
    panelDeskripsi.tetapkanCitraIkon(new ImageIcon("Gambar/Logo.gif"));

    // Menambahkan panel deskripsi pada frame
    setLayout(new BorderLayout());
    add(panelDeskripsi, BorderLayout.CENTER);
  }
}


4.8 Kotak Combo
Kotak combo, dikenal pula dengan daftar pilihan, memuat daftar item yang dapat dipilih oleh pengguna. Hal ini berguna untuk membatasi rentang pilihan pengguna dan menghindari validasi yang rumit atas masukan data. Gambar 4.21 mencantumkan beberapa metode dan konstruktor di dalam JComboBox.

Statemen-statemen berikut menciptakan suatu kotak combo dengan empat item, warna latar depan merah, warna latar belakang putih, dan item kedua terseleksi:

JComboBox jcb = new JComboBox(new Object[]
{"Item 1", "Item 2", "Item 3", "Item 4"});
jcb.setForeground(Color.red);
jcb.setBackground(Color.white);
jcb.setSelectedItem("Item 2");

JComboBox dapat memicu ActionEvent dan ItemEvent, dua dari banyak event. Ketika suatu item diseleksi, ActionEvent dipicu. Ketika suatu item baru diseleksi, JComboBox memicu ItemEvent dua kali, sekali mendeseleksi item terpilih sebelumnya, dan sekali untuk menyeleksi item terpilih sekarang. Perhatikan bahwa tidak ada ItemEvent yang dipicu jika item sekarang diseleksi kembali. Untuk merespon suatu ItemEvent, Anda perlu mengimplementasikan handler itemStateChanged(ItemEvent e) untuk memproses pilihan. Untuk mendapatkan data dari menu JComboBox, Anda dapat menggunakan getSelectedItem() untuk mengembalikan item terpilih saat ini, atau menggunakan metode e.getItem() untuk mendapatkan item dari handler itemStateChanged(ItemEvent e).

Kode4.8 menyajikan suatu program yang mengijinkan pengguna untuk menampilkan citra dan deskripsi dari bendera suatu negara dengan menyeleksi negara dari suatu kotak combo, seperti tertampil pada Gambar 4.22.


Gambar4.21 JComboBox memampukan Anda untuk menyeleksi suatu item dari sehimpunan item

Berikut adalah bebarapa langkah penting di dalam program:
1.  Menciptakan antarmuka-pengguna
Menciptakan suatu kotak combo dengan nama-nama negara sebagai nilai-nilai pilihan. Selanjutnya menciptakan objek PanelDeskripsi. Kelas PanelDeskripsi diintroduksi pada contoh terdahulu. Kemudian menempatkan kotak combo di utara frame dan panel deskripsi di tengah frame.
2.  Memproses event
Menciptakan suatu listener untuk mengimplementasikan handler itemStateChanged dalam menetapkan judul bendera, citra, dan teks di dalam panel deskripsi untuk nama negara yang terseleksi.


Kode4.8 DemoKotakCombo.java

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
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DemoKotakCombo extends JFrame{
  // Mendeklarasikan suatu array yang memuat String-String untuk judul bendera
  private String[] judulBendera= {"Indonesia", "Singapura", "Thailand",
   "Vietnam"};

  // Mendeklarasikan suatu array ImageIcon untuk 4 bendera negara
  private ImageIcon[] citraBendera= {
    new ImageIcon("Gambar/bendera_merah_putih.gif"),
    new ImageIcon("Gambar/bendera_singapura.gif"),
    new ImageIcon("Gambar/bendera_thailand.gif"),
    new ImageIcon("Gambar/bendera_vietnam.gif"),
  };

  // Mendeklarasikan array string untuk deskripsi bendera
  private String[] deskripsiBendera = new String[9];

  // Mendeklarasikan dan menciptakan suatu panel deskripsi
  private PanelDeskripsi panelDeskripsi = new PanelDeskripsi();

  // Menciptakan suatu kotak combo untuk menyeleksi negara
  private JComboBox jcbo = new JComboBox(judulBendera);

  public static void main(String[] args) {
    DemoKotakCombo frame = new DemoKotakCombo();
    frame.pack();
    frame.setTitle("DemoKotakCombo");
    frame.setLocationRelativeTo(null); // Pusat frame
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
  }

  public DemoKotakCombo() {
    // Set text description
    deskripsiBendera[0] = "Sang Saka Merah Putih \n\n" +
      "Pada Tanggal 17 Agustus 1945, Indonesia meraih kemerdekaannya " +
      "dari penjajahan dan penindasan Bangsa Belanda. Proklamator " +
      "Republik Indonesia, Soekarno dan Hatta, mengumumkan kemerdekaan " +
      "Bangsa Indonesia. Simbol negara, Bendera Merah Putih, dikibarkan " +
      "dan seluruh Rakyat Indonesia bersuka citra dari Sabang sampai " +
      "Merauke. Cit-cita Bangsa Indonesia adalah mendidik seluruh anak " +
      "bangsa agar terlepas pula dari kebodohan. Karena kebodohanlah, " +
      "saat itu, Indonesia dijajah oleh Belanda.";
    deskripsiBendera[1] = "Deskripsi untuk Singapura ... ";
    deskripsiBendera[2] = "Deskripsi untuk Thailand ... ";
    deskripsiBendera[3] = "Deskripsi untuk Vietnam ... ";

    // Menetapkan negara pertama (Indonesia) untuk ditampilkan
    setDisplay(0);

    // Menambahkan kotak combo dan panel deskripsi pada daftar
    add(jcbo, BorderLayout.NORTH);
    add(panelDeskripsi, BorderLayout.CENTER);

    // Meregistrasikan listener
    jcbo.addItemListener(new ItemListener() {
      /** Menangani seleksi item */
      public void itemStateChanged(ItemEvent e) {
        setDisplay(jcbo.getSelectedIndex());
      }
    });
  }

  /** Menetapkan penampila informasi pada panel deskripsi */
  public void setDisplay(int index) {
    panelDeskripsi.tetapkanJudul(judulBendera[index]);
    panelDeskripsi.tetapkanCitraIkon(citraBendera[index]);
    panelDeskripsi.tetapkanDeskripsi(deskripsiBendera[index]);
  }
}

Gambar 4.22 Informasi tentang suatu negara, termasuk citra bendera dan deskripsi bendera, ditampilkan ketika negara tertentu dipilih di dalam kotak combo


Listener merespon ItemEvent dari kotak combo dan mengimplementasikan ItemListener (baris 58-65). Selain menggunakan ItemEvent, Anda juga bisa menggunakan ActionEvent untuk menangani seleksi item kotak combo.

Progam menyimpan informasi bendera dalam tiga array: judulBendera, citraBendera, dan deskripsiBendera (baris 7-19). Array judulBendera memuat nama-nama empat negara, array citraBendera memuat citra bendera dari empat negara, dan array deskripsiBendera memuat deskripsi bendera tiap negara.

Program menciptakan suatu instans dari PanelDeskripsi (baris 22), yang diberikan pada kode4.6, PanelDeskripsi.java. Program menciptakan suatu kotak combo dengan nilai-nilai inisial dari judulBendera (baris 25). Ketika pengguna menyeleksi suatu item di dalam kotak combo, handler itemStateChanged dieksekusi, menemukan indeks terpilih, dan menetapkan judul bendera, citra bendera, dan deskripsi bendera pada panel.

4.9 List
List merupakan suatu komponen yang secara mendasar melakukan fungsi yang sama dengan kotak combo. Perbedaanya adalah list memampukan pengguna untuk memilih nilai tunggal atau nilai jamak (lebih dari satu nilai). JList Swing sangat handal. Gambar 4.23 mencantumkan beberapa metode dan konstruktor yang paling sering digunakan di dalam kelas JList.

Gambar 4.23 JList memampukan Anda untuk memilih beberapa item dari sehimpunan item.

Gambar 4.24 JList memiliki tiga mode: seleksi tunggal, seleksi interval-tunggal, dan seleksi interval-jamak


selectionMode merupakan salah satu dari tiga nilai (SINGLE_SELECTION, SINGLE_INTERVAL_SELECTION, MULTIPLE_INTERVAL_SELECTION) yang didefinisikan di dalam javax.swing.ListSelectionModel yang mengindikasikan apakah item tunggal, item interval-tunggal, atau item interval-jamak yang dipilih. Seleksi item interval-tunggal mengijinkan beberapa pilihan, tetapi pilihan-pilihan yang diseleksi harus bertetangga. Seleksi item interval-jamak mengijinkan pilihan tanpa batasan apapun, seperti tertampil pada Gambar 4.24.

Statemen-statemen berikut menciptakan suatu list dengan enam item, warna latar depan red, warna latar belakang white, warna latar depan pilihan pink, warna latar belakang pilihan black, dan baris terlihat sebanyak 4:

JList jlst = new JList(new Object[]
{"Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6"});
jlst.setForeground(Color.RED);
jlst.setBackground(Color.WHITE);
jlst.setSelectionForeground(Color.PINK);
jlst.setSelectionBackground(Color.BLACK);
jlst.setVisibleRowCount(4);

List tidak dapat digeser secara otomatis. Untuk membuat list agar dapat digeser, suatu scroll pane harus diciptakan dan ditambahkan padanya.

JList memicu javax.swing.event.ListSelectionEvent untuk memberitahu listener dari seleksi. Listener harus mengimplementasikan handler valueChanged di dalam antarmuka javax.swing.event.ListSelectionListener untuk memproses event yang terjadi.

Kode4.9 menyajikan suatu program  yang mengijinkan pengguna untuk memilih negara-negara di dalam suatu list dan menampilkan bendera-bendera dari negara-negara terpilih. Gambar 4.25 menunjukkan contoh keluaran program.

Gambar 4.25 Ketika beberapa negara dipilih, citra-citra terkait ditampilkan di dalam label


Kode4.9 DemoList.java

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
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;

public class DemoList extends JFrame {
  final int JUMLAH_BENDERA = 4;

  // Mendeklarasikan suatu array yang memuat String-String untuk judul bendera
    private String[] judulBendera = {"Indonesia", "Singapura", "Thailand",
      "Vietnam"};

  // List untuk negara-negara
  private JList jlst = new JList(judulBendera);

  // Mendeklarasikan suatu array ImageIcon untuk 4 bendera negara
  private ImageIcon[] ikonCitra= {
    new ImageIcon("Gambar/bendera_merah_putih.gif"),
    new ImageIcon("Gambar/bendera_singapura.gif"),
    new ImageIcon("Gambar/bendera_thailand.gif"),
    new ImageIcon("Gambar/bendera_vietnam.gif"),
  };

  // Arrays label-label untuk menampilkan citra
  private JLabel[] jlblViewerCitra = new JLabel[JUMLAH_BENDERA];

  public static void main(String[] args) {
    DemoList frame = new DemoList();
    frame.setSize(650, 500);
    frame.setTitle("DemoList");
    frame.setLocationRelativeTo(null); // Pusat frame
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
  }

  public DemoList() {
    // Menciptakan panel untuk memuat empat label
    JPanel p = new JPanel(new GridLayout(2, 2, 2, 2));

    for (int i = 0; i < JUMLAH_BENDERA; i++) {
      p.add(jlblViewerCitra[i] = new JLabel());
      jlblViewerCitra[i].setHorizontalAlignment
       (SwingConstants.CENTER);
    }

    // Menambahkan p dan list pada frame
    add(p, BorderLayout.CENTER);
    add(new JScrollPane(jlst), BorderLayout.WEST);

    // Meregistrasi listener
    jlst.addListSelectionListener(new ListSelectionListener() {
      /** Manangani seleksi list */
      public void valueChanged(ListSelectionEvent e) {
        // Mendapatkan indeks-indeks terpilih
        int[] indeks = jlst.getSelectedIndices();

        int i;
        // Menetapkan ikon-ikon dalam label
        for (i = 0; i < indeks.length; i++) {
          jlblViewerCitra[i].setIcon(ikonCitra[indeks[i]]);
        }

        // Menghapus ikon dari sisa label
        for (; i < JUMLAH_BENDERA; i++) {
        jlblViewerCitra[i].setIcon(null);
        }
      }
    });
  }
}

Listener kelas inner tak-bernama merespon ListSelectionEvent untuk menangani pemilihan nama-nama negara di dalam list (baris 49-67). ListSelectionEvent dan ListSelectionListener didefinisikan di dalam paket javax.swing.event, sehingga paket ini diimpor ke dalam program (baris 3).

Program menciptakan suatu array yang memuat empat label untuk menampilkan citra-citra bendera empat negara. Program menempatkan keempat citra bendera ke dalam suatu array citra (baris 16-21) dan menciptakan suatu list terdiri-dari empat negara dengan urutan yang sama dengan array citra (baris 9-10). Jadi, indeks 0 pada array citra terkait dengan negara pertama di dalam list.

Secara default, mode seleksi dalam list adalah interval-jamak, yang membolehkan pengguna untuk memilih beberapa item sekaligus. Ketika pengguna memilih negara-negara di dalam list, handler valueChanged (baris 52-67) akan dieksekusi, yang mendapatkan indeks dari item-item terpilih dan menetapkan ikon-ikon citra terkait di dalam label untuk ditampilkan.

4.10 Batang Penggeser atau Scroll Bar
JScrollBar merupakan suatu komponen yang memampukan pengguna untuk memilih suatu rentang nilai, seperti tertampil pada Gambar 4.26.


Gambar 4.26 Batang penggeser merepresentasikan suatu rentang nilai secara grafikal


Normalnya, pengguna mengubah nilai batang penggeser dengan menggeret mouse. Misalnya, pengguna dapat menggeret batang penggeser ke kiri atau ke kanan, atau mengklik area inkremen unit atau dekremen unit. Anda juga bisa menggunakan papankunci untuk mengubah batang penggeser. Secara konvensi, kunci Page Up dan Page Down ekivalen dengan pengklikan area inkremen unit dan dekremen unit.

JScrollBar memiliki properti-properti berikut, seperti ditampilkan pada Gambar 4.27. Ketika pengguna mengubah nilai batang penggeser, batang penggeser tersebut memicu instans dari AdjustmentEvent, yang dilewatkan kepada setiap listener. Suatu objek, yang berharap akan diberitahu bila ada perubahan pada batang penggeser, harus mengimplementasikan metode adjustmentValueChanged di dalam antarmuka java.awt.event.AdjustmentListener.


Gambar 4.27 JScrollBar memampukan Anda untuk memilih dari suatu rentang nilai


Kode4.10 memberikan suatu program yang menggunakan batang penggeser horisontal dan vertikal untuk mengendalikan suatu pesan yang akan ditampilkan pada panel. Batang penggeser horisontal digunakan untuk menggeser pesan ke kiri atau ke kanan, dan batang penggeser vertikal digunakan untuk menggeser pesan ke atas atau ke bawah. Contoh keluaran program ditampilkan pada Gambar 4.28. Berikut adalah langkah-langkah utama di dalam program:
1.  Menciptakan antarmuka-pengguna
Menciptakan suatu objek PanelPesan dan menempatkannya di tengah frame. Menciptakan batang penggeser vertikal dan menempatkannya di sisi timur frame. Menciptakan batang penggeser horisontal dan menempatkannya di sisi selatan frame.
2.  Memproses event
Menciptakan listener untuk mengimplementasikan handler adjustmentValueChanged untuk menggerakkan pesan sesuatu dengan pergerakan di dalam batang penggeser.

Gambar 4.28 Batang penggeser menggeser pesan pada panel secara horisontal dan vertikal


Kode4.10 DemoBatangPenggeser.java

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
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DemoBatangPenggeser extends JFrame {
  // Menciptakan batang penggeser horisontal dan vertikal
  private JScrollBar jscbHort =
    new JScrollBar(JScrollBar.HORIZONTAL);
  private JScrollBar jscbVert =
    new JScrollBar(JScrollBar.VERTICAL);

  // Menciptakan suatu PanelPesan
  private PanelPesan panelPesan =
   new PanelPesan("JAVA itu Tangguh!");

  public static void main(String[] args) {
    DemoBatangPenggeser frame = new DemoBatangPenggeser();
    frame.setTitle("DemoBatangPenggeser");
    frame.setLocationRelativeTo(null); // Pusat frame
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
  }

  public DemoBatangPenggeser() {
    // Manambahkan batang penggeser dan panel pesan pada frame
    setLayout(new BorderLayout());
    add(panelPesan, BorderLayout.CENTER);
    add(jscbVert, BorderLayout.EAST);
    add(jscbHort, BorderLayout.SOUTH);

    // Register listener for the scroll bars
    jscbHort.addAdjustmentListener(new AdjustmentListener() {
      public void adjustmentValueChanged(AdjustmentEvent e) {
        // getValue() dan getMaximumValue() mengembalikan int, tetapi
        // untuk kepresisian yang lebih baik, digunakan double
        double nilai = jscbHort.getValue();
        double nilaiMaksimum = jscbHort.getMaximum();
        double Xbaru = (nilai * panelPesan.getWidth() /
          nilaiMaksimum);
        panelPesan.tetapkanKoordinatX((int)Xbaru);
      }
    });
    jscbVert.addAdjustmentListener(new AdjustmentListener() {
      public void adjustmentValueChanged(AdjustmentEvent e) {
        // getValue() dan getMaximumValue() mengembalikan int, tetapi
        // untuk kepresisian yang lebih baik, digunakan double
        double nilai = jscbVert.getValue();
        double nilaiMaksimum = jscbVert.getMaximum();
        double Ybaru = (nilai * panelPesan.getHeight() /
          nilaiMaksimum);
        panelPesan.tetapkanKoordinatY((int)Ybaru);
      }
    });
  }
}

Program menciptakan dua batang penggeser (jscbVert dan jscbHort) (baris 7-10) dan suatu instans PanelPesan (panelPesan) (baris 13-14). panelPesan ditempatkan di tengah frame; jscbVert dan jscbHort ditempatkan di sisi timur dan selatan frame (baris 29-30).

Anda bisa menciptakan orientasi atau arah batang penggeser di dalam konstruktor atau menggunakan metode setOrientation(). Secara default, nilai properti 100 untuk maximum, 0 untuk minimum, 10 untuk blockIncrement, dan 10 untuk visibleAmount.

Ketika pengguna menggeret bubble, atau mengklik inkremen atau dekremen unit, nilai batang penggeser berubah. Suatu instans dari AdjustmentEvent dipicu dan dilewatkan kepada listener dengan memanggil handler AdjustmentValueChanged. Listener untuk batang penggeser vertikal menggeser pesan ke atas dan ke bawah (baris 33-43) dan listener untuk batang penggeser horisontal menggeser pesan ke kiri dan ke kanan (baris 44-54).

Nilai maksimum suatu batang penggeser vertikal tergantung dari tinggi panel, dan nilai maksimum suatu batang penggeser horisontal tergantung dari lebar panel. Rasio antara nilai sekarang dengan nilai maksimum suatu batang penggeser horisontal sama dengan rasio x dengan lebar panel pesan. Dengan logika yang sama, rasio antara nilai sekarang dengan nilai maksimum suatu batang penggeser vertikal sama dengan rasio y dengan tinggi panel pesan (baris 39, 50).


4.11 Slider
JSlider sama dengan JScrollBar, tetapi JSlider memiliki lebih banyak properti dan mempunyai banyak bentuk. Gambar 4.29 menampilkan dua jenis slider.

Gambar 4.29 Slider menggeser pesan pada panel secara horisontal maupun vertikal


JSlider mengijinkan pengguna untuk secara grafikal memilih suatu nilai dengan cara menggeret knob dalam rentang tertentu. Slider memiliki penanda mayor dan penanda minor. Jumlah piksel di antara penanda mayor dan penanda minor ditentukan oleh properti majorTickSpacing dan minorTickSpacing. Slider dapat ditampilkan baik secara horisontal maupun vertikal dengan atau tanpa penanda, dan dengan atau tanpa label. Konstruktor-konstruktor dan properti-properti yang sering digunakan dalam JSlider ditampilkan pada Gambar 4.30.

Gambar 4.30 JSlider memampukan Anda untuk memilih dari suatu rentang nilai


Ketika pengguna mengubah nilai slider, slider memicu suatu instans dari javax.swing.event.ChangeEvent, yang dilewatkan kepada sembarang listener yang teregistrasi. Sembarang objek yang berminat untuk diberitahu tentang perubahan nilai slider harus mengimplementasikan metode stateChanged dalam antarmuka ChangeListener yang didefinisikan di dalam paket javax.swing.event.

Kode4.11 menuliskan suatu program yang menggunakan slider untuk mengendalikan pesan yang ditampilkan pada panel, seperti tertampil pada Gambar 4.29. Berikut merupakan langkah-langkah utama di dalam program:
1.  Menciptakan antarmuka pengguna
Menciptakan suatu objek PanelPesan dan menempatkannya di tengah frame. Menciptakan slider vertikal dan menempatkannya di sisi timur frame. Menciptakan slider horisontal dan menempatkannya di sisi selatan frame.
2.  Memproses event
Menciptakan listener untuk mengimplementasikan handler stateChanged di dalam antaramuka ChangeListener untuk menggerakkan pesan sesuai dengan pergeseran knob pada slider.

Kode4.11 DemoSlider.java

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
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;

public class DemoSlider extends JFrame {
  // Menciptakan slider horisontal dan vertikal
  private JSlider jsldHort = new JSlider(JSlider.HORIZONTAL);
  private JSlider jsldVert = new JSlider(JSlider.VERTICAL);

  // Menciptakan suatu PanelPesan
  private PanelPesan panelPesan =
    new PanelPesan("JAVA itu Tangguh!");

  public static void main(String[] args) {
    DemoSlider frame = new DemoSlider();
    frame.setTitle("DemoSlider");
    frame.setLocationRelativeTo(null); // Pusat frame
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
  }

  public DemoSlider() {
    // Menambahkan slider dan panel pesan pada frame
    setLayout(new BorderLayout(5, 5));
    add(panelPesan, BorderLayout.CENTER);
    add(jsldVert, BorderLayout.EAST);
    add(jsldHort, BorderLayout.SOUTH);

    // Menetapkan properti-properti slider
    jsldHort.setMaximum(50);
    jsldHort.setPaintLabels(true);
    jsldHort.setPaintTicks(true);
    jsldHort.setMajorTickSpacing(10);
    jsldHort.setMinorTickSpacing(1);
    jsldHort.setPaintTrack(false);
    jsldVert.setInverted(true);
    jsldVert.setMaximum(10);
    jsldVert.setPaintLabels(true);
    jsldVert.setPaintTicks(true);
    jsldVert.setMajorTickSpacing(10);
    jsldVert.setMinorTickSpacing(1);

    // Meregistrasi listener untuk slider
    jsldHort.addChangeListener(new ChangeListener() {
      /** Menangani aksi pengubahan scroll-bar */
      public void stateChanged(ChangeEvent e) {
        // getValue() dan getMaximumValue() mengembalikan int,
        // tetapi untuk kepresisian lebih baik, digunakan double
        double nilai = jsldHort.getValue();
        double nilaiMaksimum = jsldHort.getMaximum();
        double Xbaru = (nilai * panelPesan.getWidth() /
         nilaiMaksimum);
        panelPesan.tetapkanKoordinatX((int)Xbaru);
      }
    });
    jsldVert.addChangeListener(new ChangeListener() {
      /** Menangani aksi pengubahan scroll-bar */
      public void stateChanged(ChangeEvent e) {
        // getValue() dan getMaximumValue() mengembalikan int,
        // tetapi untuk kepresisian lebih baik, digunakan double
        double nilai = jsldVert.getValue();
        double nilaiMaksimum = jsldVert.getMaximum();
        double Ybaru = (nilai * panelPesan.getHeight() /
         nilaiMaksimum);
        panelPesan.tetapkanKoordinatY((int) Ybaru);
      }
    });
  }
}

JSlider mirip dengan JScrollBar tetapi memiliki lebih banyak fitur. Seperti ditunjukkan pada contoh ini, Anda bisa menentukan nilai maksimum, label, penanda mayor, pananda minor pada JSlider (baris 31-35). Anda juga dapat memilih untuk menyembunyikan trek (baris 36). Karena nilai suatu slider vertikal berkurang dari atas ke bawah, metode setInverted membalikkan urutan tersebut (baris 37).

JSlider memicu ChangeEvent ketika slider diubah. Listener harus mengimplementasikan handler stateChanged di dalam ChangeListener (baris 45-68). Perhatikan bahwa JScrollBar memicu AdjustmentEvent ketika batang penggeser digerakkan.


4.12 Jendela Jamak
Pada kesempatan tertentu, Anda mungkin menginginkan untuk mempunyai lebih dari satu jendela dalam suatu aplikasi. Aplikasi tersebut diharapkan dapat membuka suatu jendela baru untuk melakukan tugas tertentu. Jendela baru tersebut disebut dengan subjendela, dan frame utama disebut dengan jendela utama.

Untuk menciptakan subjendela dari suatu aplikasi, Anda harus mendefinisikan suatu subkelas dari JFrame yang menentukan tugas yang akan dilaksanakan dan memberitahu jendela baru tentang apa yang harus dilakukan. Anda kemudian dapat menciptakan suatu instans dari kelas ini di dalam aplikasi dan menjalankan jendela baru dengan menetapkan instans frame menjadi kelihatan (visible).

Kode4.12 menyajikan contoh yang menciptakan suatu jendela utama dengan area teks di dalam scroll pane dan suatu tombol yang dinamai Tampil Histogram. Ketika pengguna mengklik tombol tersebut, suatu jendela baru muncul yang menampilkan histogram (jumlah kemunculan tiap huruf di dalam area teks). Gambar 4.31 menampilkan contoh keluaran program.

Gambar 4.31 Histogram ditampilkan pada suatu frame terpisah


Berikut adalah beberapa langkah utama program:
1.  Menciptakan kelas utama untuk frame yang dinamai DemoJendelaJamak pada kode4.12. Menambahkan suatu area teks dalam scroll pane, dan menempatkan scroll pane pada pusat frame. Menciptakan suatu tombol Tampil Histogram dan menempatkannya di sisi selatan frame.
2.  Menciptakan suatu subkelas dari JPanel yang dinamai Histogram pada kode4.13. Kelas memuat suatu bidang data yang dinamai hitung bertipe int[], yang menghitung jumlah kemunculan setiap huruf (dari 26 huruf). Nilai hitung akan ditampilkan pada histogram.
3.  Mengimplementasikan handler actionPerformed dalam DemoJendelaJamak, sebagai berikut:
a)  Menciptakan suatu instans dari Histogram. Menghitung kemunculan tiap huruf di dalam area teks dan melewatkan hitung kepada objek Histogram.
b)  Menciptakan suatu frame baru dan menempatkan objek Histogram di tengah frame. Menampilkan frame.

Kode4.12 DemoJendelaJamak.java

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
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DemoJendelaJamak extends JFrame {
  private JTextArea jta;
  private JButton jbtTampilHistogram = new JButton("Tampil Histogram");
  private Histogram histogram = new Histogram();

  // Menciptakan suatu frame baru untuk memuat panel histogram
  private JFrame histogramFrame = new JFrame();

  public DemoJendelaJamak() {
    // Menyimpan area teks di dalam scroll pane
    JScrollPane scrollPane = new JScrollPane(jta = new JTextArea());
    scrollPane.setPreferredSize(new Dimension(300, 200));
    jta.setWrapStyleWord(true);
    jta.setLineWrap(true);

    // Menempatkan scroll pane dan tombol dalam frame
    add(scrollPane, BorderLayout.CENTER);
    add(jbtTampilHistogram, BorderLayout.SOUTH);

    // Meregistrasi listener
    jbtTampilHistogram.addActionListener(new ActionListener() {
      /** Menangani aksi tombol */
      public void actionPerformed(ActionEvent e) {
        // Menghitung kemunculan huruf di dalam area teks
        int[] hitung = hitungHuruf();

        // Menetakan jumlah huruf pada histogram untuk ditampilkan
        histogram.tampilHistogram(hitung);

        // Menampilkan frame
        histogramFrame.setVisible(true);
      }
    });

    // Menciptakan suatu frame baru untuk memuat panel histogram
    histogramFrame.add(histogram);
    histogramFrame.pack();
    histogramFrame.setTitle("Histogram");
  }

  /** Menghitung huruf di dalam area teks */
  private int[] hitungHuruf() {
    // Menghitung untuk 26 huruf
    int[] hitung = new int[26];

    // Mendapatkan isi dari area teks
    String teks = jta.getText();

    // Menghitung jumlah kemunculan setiap huruf (huruf besar dibedakan dari huruf kecil)
    for (int i = 0; i < teks.length(); i++) {
      char karakter = teks.charAt(i);

      if ((karakter >= 'A') && (karakter <= 'Z')) {
        hitung[karakter - 'A']++;
      }
      else if ((karakter >= 'a') && (karakter <= 'z')) {
        hitung[karakter - 'a']++;
      }
    }

    return hitung; // Mengembalikan array hitung
  }

  public static void main(String[] args) {
    DemoJendelaJamak frame = new DemoJendelaJamak();
    frame.setLocationRelativeTo(null); // pusat frame
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setTitle("DemoJendelaJamak");
    frame.pack();
    frame.setVisible(true);
  }
}

Kode4.13 Histogram.java

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
import javax.swing.*;
import java.awt.*;

public class Histogram extends JPanel{
  // Menghitung jumlah kemunculan 26 huruf
  private int[] hitung;

  /** Menetapkan hitung dan menampilkan histogram */
  public void tampilHistogram(int[] hitung) {
    this.hitung = hitung;
    repaint();
  }

  /** Menggambar histogram */
  protected void paintComponent(Graphics g) {
    if (hitung == null) return; // Tidak ada yang ditampilkan jika hitung adalah null

    super.paintComponent(g);

    // Mencari ukuran panel dan lebar batang dan interval secara dinamis
    int lebar = getWidth();
    int tinggi = getHeight();
    int interval = (lebar - 40) / hitung.length;
    int lebarIndividu = (int)(((lebar - 40) / 24) * 0.60);

    // Find the maximum hitung. The maximum hitung has the highest bar
    int hitungMaks = 0;
    for (int i = 0; i < hitung.length; i++) {
      if (hitungMaks < hitung[i])
        hitungMaks = hitung[i];
    }

    // x adalah posisi awal untuk batang pertama dalam histogram
    int x = 30;

    // Menggambar garis basis horisontal
    g.drawLine(10, tinggi - 45, lebar - 10, tinggi - 45);
    for (int i = 0; i < hitung.length; i++) {
      // Mencari tinggi batang
      int tinggiBatang =
      (int)(((double)hitung[i] / (double)hitungMaks) * (tinggi - 55));

      // Menampilkan batang (i.e. persegi-panjang)
      g.drawRect(x, tinggi - 45 - tinggiBatang, lebarIndividu,
        tinggiBatang);

      // Menampilkan karakter di bawah garis basis
      g.drawString((char)(65 + i) + "", x, tinggi - 30);

      // Menggerakkan x untuk menampilkan karakter berikutnya
      x += interval;
    }
  }

  /** Mengoverride getPreferredSize */
  public Dimension getPreferredSize() {
    return new Dimension(300, 300);
  }
}






No comments:

Post a Comment