ТОР 5 статей: Методические подходы к анализу финансового состояния предприятия Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века Характеристика шлифовальных кругов и ее маркировка Служебные части речи. Предлог. Союз. Частицы КАТЕГОРИИ:
|
RemovePropertyChangeListener()для ограниченных свойств применяются методы addVetoableChangeListener(VetoableChangeListener v) и removeVetoableChangeListener(VetoableChangeListener v). Здесь VetoableChangeListener – интерфейс с одним методом void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException(). По аналогии со вспомогательным классом PropertyChangeSupport, который используется при реализации связанных свойств, для ограниченных свойств в пакете java.beans есть вспомогательный класс VetoableChangeSupport. В нем реализованы алгоритмы, необходимые для поддержки событий ограниченных свойств. В качестве примера вспомним класс SomeBean, рассмотренный ранее. Его свойство someProperty() реализовано как связанное. Переделаем пример и реализуем это свойство как ограниченное. /* пример # 26: bean-класс с ограниченным свойством: SomeBean.java */ import java.beans.*; public class SomeBean { private String someProperty = null; private VetoableChangeSupport vcs; public SomeBean(){ vcs = new VetoableChangeSupport(this); } public void addVetoableChangeListener (VetoableChangeListener pcl){ vcs.addVetoableChangeListener(pcl); } public void removeVetoableChangeListener (VetoableChangeListener pcl){ pcs.removePropertyChangeListener(pcl); }
public String getSomeProperty(){ return someProperty; } public void setSomeProperty(String value) throws PropertyVetoException{ vcs.fireVetoableChange(“someProperty”, someProperty, value); someProperty = value; } } Как видно, принципиально ничего не изменилось. Только вместо PropertyChangeSupport использован VetoableChangeSupport и в описании set -метода добавлено throws PropertyVetoException. Теперь someProperty является ограниченным свойством, и зарегистрировавшийся слушатель может запретить его изменение. Рассмотренные возможности организации связи бина с другими компонентами не являются единственно возможными. Бин, как и любой класс, может быть источником событий и/или слушателем. И эти события могут быть не связаны с изменением свойств бина. В таких случаях обычно используют существующие события типа ActionEvent, хотя можно построить и свои события. Задания к главе 13 Вариант А 1. Создать апплет. Поместить на него текстовое поле JTextField, кнопку JButton и метку JLabel. В метке отображать все введенные символы, разделяя их пробелами. 2. Поместить в апплет две панели JPanel и кнопку. Первая панель содержит поле ввода и метку “Поле ввода”; вторая – поле вывода и метку “Поле вывода”. Для размещения в окне двух панелей и кнопки “Скопировать” использовать менеджер размещения BorderLayout. 3. Изменить задачу 2 так, чтобы при нажатии на кнопку “Скопировать” текст из поля ввода переносился в поле вывода, а поле ввода очищалось. 4. Задача 2 модифицируется так, что при копировании поля ввода нужно, кроме собственно копирования, организовать занесение строки из поля ввода во внутренний список. При решении использовать коллекцию, 5. К условию задачи 2 добавляется еще одна кнопка с надписью “Печать”. При нажатии на данную кнопку весь сохраненный список должен быть выведен в консоль. При решении использовать коллекцию, в частности TreeSet. 6. Написать программу для построения таблицы значений функции Использовать метку JLabel, содержащую текст “Функция: ”; панель, включающую три текстовых поля JTextField, содержащих значения параметра, шага (например, 0.1) и количества точек. Начальное значение x=0. С каждым текстовым полем связана метка, содержащая его название. В приложении должно находиться текстовое поле со скроллингом, содержащее полученную таблицу. 7. Создать форму с набором кнопок так, чтобы надпись на первой кнопке при ее нажатии передавалась на следующую, и т.д. 8. Создать форму с выпадающим списком так, чтобы при выборе элемента списка на экране появлялись GIF-изображения, двигающиеся в случайно выбранном направлении по апплету. 9. В апплете изобразить прямоугольник (окружность, эллипс, линию). Направление движения объекта по экрану изменяется на противоположное щелчком по клавише мыши. При этом каждый второй щелчок меняет цвет фона. 10. Создать фрейм с изображением окружности. Длина дуги окружности изменяется нажатием клавиш от 1 до 9. 11. Создать фрейм с кнопками. Кнопки “вверх”, “вниз”, “вправо”, “влево” двигают в соответствующем направлении линию. При достижении границ фрейма линия появляется с противоположной стороны. 12. Создать фрейм и разместить на нем окружность (одну или несколько). Объект должен “убегать” от указателя мыши. При приближении на некоторое расстояние объект появляется в другом месте фрейма. 13. Создать фрейм/апплет с изображением графического объекта. Объект на экране движется к указателю мыши, когда последний находится 14. Изменить задачу 12 так, чтобы количество объектов зависело от размеров апплета и изменялось при “перетягивании” границы в любом направлении. 15. Промоделировать в апплете вращение спутника вокруг планеты по эллиптической орбите. Когда спутник скрывается за планетой, то он не виден. 16. Промоделировать в апплете аналоговые часы (со стрелками) с кнопками для увеличения/уменьшения времени на час/минуту. Вариант B Для заданий варианта В главы 4 создать графический интерфейс для занесения информации при инициализации объекта класса, для выполнения действий, предусмотренных заданием, и для отправки сообщений другому пользователю системы. Тестовые задания к главе 13 Вопрос 13.1. Какой менеджер размещения использует таблицу с ячейками равного размера? 1) FlowLayout; 2) GridLayout; 3) BorderLayout; 4) CardLayout. Вопрос 13.2. Дан код: import java.awt.*; public class Quest2 extends Frame{ Quest2(){ Button yes = new Button("YES"); Button no = new Button("NO"); add(yes); add(no); setSize(100, 100); setVisible(true); } public static void main(String[] args){ Quest2 q = new Quest2(); } } В результате будет выведено: 1) две кнопки, занимающие весь фрейм, YES – слева и NO – справа; 2) одна кнопка YES, занимающая целый фрейм; 3) одна кнопка NO, занимающая целый фрейм; 4) две кнопки наверху фрейма – YES и NO. Вопрос 13.3. Какое выравнивание устанавливается по умолчанию для менеджера размещений FlowLayout? 1) FlowLayout.RIGHT; 2) FlowLayout.LEFT; 3) FlowLayout.CENTER; 4) FlowLayout.LEADING; 5) указывается явно. Вопрос 13.4. Сколько кнопок будет размещено в приведенном ниже апплете? import java.awt.*; public class Quest4 extends java.applet.Applet{ Button b = new Button("YES"); public void init(){ add(b); add(b); add(new Button("NO")); add(new Button("NO")); }}1) одна кнопка с YES и одна кнопка NO; 2) одна кнопка с YES и две кнопки NO; 3) две кнопки с YES и одна кнопка NO; 4) две кнопки с YES и две кнопки NO. Вопрос 13.5. Объект JСheckBox объявлен следующим образом: JCheckBox ob = new JCheckBox(); Какая из следующих команд зарегистрирует его в блоке прослушивания событий? 1) ob.addItemListener(); 2) ob.addItemListener(this); 3) addItemListener(this); 4) addItemListener(); 5) ни одна из приведенных.» ПОТОКИ ВЫПОЛНЕНИЯ Класс Thread и интерфейс Runnable К большинству современных распределенных приложений (Rich Client) // пример # 1: расширение класса Thread: Talk.java package chapt14; public class Talk extends Thread { public void run() { for (int i = 0; i < 8; i++) { System. out. println("Talking"); try { // остановка на 400 миллисекунд Thread. sleep (400); } catch (InterruptedException e) { System. err. print(e); } } } } При реализации интерфейса Runnable необходимо определить его единственный абстрактный метод run(). Например: /* пример # 2: реализация интерфейса Runnable: Walk.java: WalkTalk.java */ package chapt14;
public class Walk implements Runnable { public void run() { for (int i = 0; i < 8; i++) { System. out. println("Walking"); try { Thread. sleep (400); } catch (InterruptedException e) { System. err. println(e); } } } } package chapt14;
public class WalkTalk { public static void main(String[] args) { // новые объекты потоков Talk talk = new Talk(); Thread walk = new Thread(new Walk()); // запуск потоков talk.start(); walk.start();
//Walk w = new Walk(); // просто объект, не поток // w.run(); //выполнится метод, но поток не запустится! } } Использование двух потоков для объектов классов Talk и Walk приводит Жизненный цикл потока
При выполнении программы объект класса Thread может быть в одном из четырех основных состояний: “новый”, “работоспособный”, “неработоспособный” и “пассивный”. При создании потока он получает состояние “новый” (NEW) и не выполняется. Для перевода потока из состояния “новый” в состояние “работоспособный” (RUNNABLE) следует выполнить метод start(), который вызывает метод run() – основной метод потока. Рис. 14.1. Состояния потока Поток может находиться в одном из состояний, соответствующих элементам статически вложенного перечисления Thread.State: NEW – поток создан, но еще не запущен; RUNNABLE – поток выполняется; BLOCKED – поток блокирован; WAITING – поток ждет окончания работы другого потока; TIMED_WAITING – поток некоторое время ждет окончания другого потока; TERMINATED — поток завершен. Получить значение состояния потока можно вызовом метода getState(). Поток переходит в состояние “неработоспособный” (WAITING) вызовом методов wait(), suspend() (deprecated-метод)или методов ввода/вывода, которые предполагают задержку. Для задержки потока на некоторое время (в миллисекундах) можно перевести его в режим ожидания (TIMED_WAITING) с помощью методов sleep(long millis) и wait(long timeout), при выполнении которого может генерироваться прерывание InterruptedException. Вернуть потоку работоспособность после вызова метода suspend() можно методом resume() (deprecated-метод), а после вызова метода wait() – методами notify() или notifyAll(). Поток переходит в “пассивное” состояние (TERMINATED), если вызваны методы interrupt(), stop() (deprecated-метод)или метод run() завершил выполнение. После этого, чтобы запустить поток еще раз, необходимо создать новый объект потока. Метод interrupt() успешно завершает поток, если он находится в состоянии “работоспособность”. Если же поток неработоспособен, то метод генерирует исключительные ситуации разного типа в зависимости от способа остановки потока. Интерфейс Runnable не имеет метода start(), а только единственный метод run(). Поэтому для запуска такого потока, как Walk, следует создать объект класса Thread и передать объект Walk его конструктору. Однако при прямом вызове метода run() поток не запустится, выполнится только тело самого метода. Методы suspend(), resume() и stop() являются deprecated-методами и запрещены к использованию, так как они не являются в полной мере “потоко- Управление приоритетами и группы потоков Потоку можно назначить приоритет от 1 (константа MIN_PRIORITY) до 10 (MAX_PRIORITY) с помощью метода setPriority(int prior). Получить значение приоритета можно с помощью метода getPriority(). // пример # 3: демонстрация приоритетов: PriorityRunner.java: PriorThread.java package chapt14; public class PriorThread extends Thread { public PriorThread(String name){ super (name); } public void run(){ for (int i = 0; i < 71; i++){ System. out. println(getName() + " " + i); try { sleep (1); //попробовать sleep(0); } catch (InterruptedException e) { System. err. print("Error" + e); } } } } package chapt14;
public class PriorityRunner { public static void main(String[] args) { PriorThread min = new PriorThread("Min"); //1 PriorThread max = new PriorThread("Max"); //10 PriorThread norm = new PriorThread("Norm"); //5 min.setPriority(Thread.MIN_PRIORITY); max.setPriority(Thread.MAX_PRIORITY); norm.setPriority(Thread.NORM_PRIORITY); min.start(); norm.start(); max.start(); } } Поток с более высоким приоритетом в данном случае, как правило, монополизирует вывод на консоль. Потоки объединяются в группы потоков. После создания потока нельзя изменить его принадлежность к группе. ThreadGroup tg = new ThreadGroup("Группа потоков 1"); Thread t0 = new Thread(tg, "поток 0"); Все потоки, объединенные группой, имеют одинаковый приоритет. Чтобы определить, к какой группе относится поток, следует вызвать метод Управление потоками Приостановить (задержать) выполнение потока можно с помощью метода sleep( время задержки ) класса Thread. Менее надежный альтернативный способ состоит в вызове метода yield(), который может сделать некоторую паузу и позволяет другим потокам начать выполнение своей задачи. Метод join() блокирует работу потока, в котором он вызван, до тех пор, пока не будет закончено выполнение вызывающего метод потока. // пример # 4: задержка потока: JoinRunner.java package chapt14; class Th extends Thread { public Th(String str) { super (); setName(str); } public void run() { String nameT = getName(); System. out. println("Старт потока " + nameT); if ("First".equals(nameT)) { try { sleep (5000); } catch (InterruptedException e) { e.printStackTrace(); } System. out. println("завершение потока " + nameT); } else if ("Second".equals(nameT)) { try { sleep (1000); } catch (InterruptedException e) { e.printStackTrace(); } System. out. println("завершение потока " + nameT); } } } public class JoinRunner { public static void main(String[] args) { Th tr1 = new Th("First"); Th tr2 = new Th("Second"); tr1.start(); tr2.start(); try { tr1.join(); System. out. println("завершение main"); } catch (InterruptedException e){ e.printStackTrace(); } /* join() не дает работать потоку main до окончания выполнения потока tr1 */ } } Возможно, будет выведено: Старт потока First Не нашли, что искали? Воспользуйтесь поиском:
|