package oreilly.beans.yesno; import java.awt.*; import java.awt.event.*; import java.beans.*; /** * Tämä luokka on YesNoDialog-komponentin asetuseditori. Siinä näytetään * TextArea-komponentti ja kolme TextField-kenttää, joihin käyttäjä voi syöttää * dialogissa näytettävän ilmoituksen sekä kaikkien kolmen napin otsikot. * Editorilla ei voi muuttaa dialogin otsikkoa tai muita resursseja. */ public class YesNoDialogCustomizer extends Panel implements Customizer, TextListener { protected YesNoDialog bean; // Muokattava komponentti. protected TextComponent message, fields[]; // Editorin komponentit. // Oletuskonstruktori: YesNoDialogCustomizer() { super(); } // Komponenttien käsittelyohjelma kutsuu tätä metodia kun se kertoo, mitä // oliota on tarkoitus muokata. Tämä metodia kutsutaan aina ennen kuin // editori tuodaan näkyviin joten editorin käyttöliittymän voi luoda tässä // metodissa. public void setObject(Object o) { bean = (YesNoDialog)o; // Laitetaan muokattava olio talteen. // Laitetaan paneelin yläosaan otsikko. this.setLayout(new BorderLayout()); this.add(new Label("Enter the message to appear in the dialog:"), "North"); // Lisätään sen alle tekstialue, johon voi kirjoittaa ilmoituksen. message = new TextArea(bean.getMessage()); message.addTextListener(this); // TextArea-olio ei tiedä itselleen sopivaa kokoa joten se pitää kertoa. message.setSize(400, 200); this.add(message, "Center"); // Lisätään tekstikenttärivejä, joihin kirjoitetaan nappien otsikot. Panel buttonbox = new Panel(); // Rivisäiliö. buttonbox.setLayout(new GridLayout(1, 0, 25, 10)); // Kentät tasavälein. this.add(buttonbox, "South"); // Laitetaan rivi // alalaitaan. // Luodaan kolme TextField-oliota, jotka tälle riville laitetaan. // Jokaisen kentän ylle laitetaan Label-oliolla otsikko, joten luodaan // säiliöt kutakin TextField+Label-yhdistelmää varten. fields = new TextComponent[3]; // TextFields-taulukko. String[] labels = new String[] { // Kunkin kentän otsikot. "Yes Button Label", "No Button Label", "Cancel Button Label"}; String[] values = new String[] { // Alkuarvot. bean.getYesLabel(), bean.getNoLabel(), bean.getCancelLabel()}; for(int i = 0; i < 3; i++) { Panel p = new Panel(); // Luodaan säiliö. p.setLayout(new BorderLayout()); // Asetellaan BorderLayout- // oliolla. p.add(new Label(labels[i]), "North"); // Laitetaan otsikko ylälaitaan. fields[i] = new TextField(values[i]); // Luodaan tekstikenttä. p.add(fields[i], "Center"); // Laitetaan se otsikon // alapuolelle. fields[i].addTextListener(this); // Asetetaan // tapahtumakuuntelija. buttonbox.add(p); // Lisätään säiliö riviin. } } // Lisätään hieman tilaa paneelin ulkoreunojen ympärille. public Insets getInsets() { return new Insets(10, 10, 10, 10); } // Tämä on TextListener-rajapinnassa määritelty metodi. Aina kun TextArea- // tai TextFields-olioon kirjoitetaan jotain, tätä metodia kutsutaan. // Metodi päivittää komponentin vastaavan ominaisuuden ja lähettää // ominaisuuden muutosilmoitustapahtuman niin kuin asetuseditoreissa pitää // tehdä. Huomaa, että jokaisesta näppäimenpainalluksesta ei tarvitse // lähettää ilmoitusta. Yhtä hyvin voitaisiin tehdä "Apply" (käytä) -nappi, // jolla muutokset hyväksytään kerralla jolloin ominaisuuden // muutostapahtuma lähetettäisiin vain kerran. public void textValueChanged(TextEvent e) { TextComponent t = (TextComponent)e.getSource(); String s = t.getText(); if (t == message) bean.setMessage(s); else if (t == fields[0]) bean.setYesLabel(s); else if (t == fields[1]) bean.setNoLabel(s); else if (t == fields[2]) bean.setCancelLabel(s); listeners.firePropertyChange(null, null, null); } // Tässä käytetään hyväksi PropertyChangeSupport-luokkaa. Oliolla pidetään // kirjaa komponentille tehtävistä muutoksista kiinnostuneista // kuuntelijoista. protected PropertyChangeSupport listeners = new PropertyChangeSupport(this); public void addPropertyChangeListener(PropertyChangeListener l) { listeners.addPropertyChangeListener(l); } public void removePropertyChangeListener(PropertyChangeListener l) { listeners.removePropertyChangeListener(l); } }