Главная

Популярная публикация

Научная публикация

Случайная публикация

Обратная связь

ТОР 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 модифицируется так, что при копировании поля ввода нужно, кроме собственно копирования, организовать занесение строки из поля ввода во внутренний список. При решении использовать коллекцию,
в частности ArrayList.

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) ни одна из приведенных.»

 
Глава 14

ПОТОКИ ВЫПОЛНЕНИЯ

Класс Thread и интерфейс Runnable

К большинству современных распределенных приложений (Rich Client)
и Web-приложений (Thin Client) выдвигаются требования одновременной поддержки многих пользователей, каждому из которых выделяется отдельный поток, а также разделения и параллельной обработки информационных ресурсов. Потоки – средство, которое помогает организовать одновременное выполнение нескольких задач, каждую в независимом потоке. Потоки представляют собой классы, каждый из которых запускается и функционирует самостоятельно, автономно (или относительно автономно) от главного потока выполнения программы. Существуют два способа создания и запуска потока: расширение класса Thread или реализация интерфейса Runnable.

// пример # 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 приводит
к выводу строк: Talking Walking. Порядок вывода, как правило, различен при нескольких запусках приложения.

Жизненный цикл потока

Новый
Работоспособный
Неработоспособный
Пассивный

При выполнении программы объект класса 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");

Все потоки, объединенные группой, имеют одинаковый приоритет. Чтобы определить, к какой группе относится поток, следует вызвать метод
getThreadGroup(). Если поток до включения в группу имел приоритет выше приоритета группы потоков, то после включения значение его приритета станет равным приоритету группы. Поток же со значением приоритета более низким, чем приоритет группы после включения в оную, значения своего приоритета не изменит.

Управление потоками

Приостановить (задержать) выполнение потока можно с помощью метода 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






Не нашли, что искали? Воспользуйтесь поиском:

vikidalka.ru - 2015-2024 год. Все права принадлежат их авторам! Нарушение авторских прав | Нарушение персональных данных