Создание "легкого" компонента

"Легкий" компонент, не имеющий своего peer-объекта в графической системе, создается как прямое расширение класса component или Container. При этом необходимо задать те действия, которые в "тяжелых" компонентах выполняет peer-объект.

Например, заменив в листинге 10.7 заголовок класса FlowerButton строкой 

class FlowerButton extends Component implements MouseListener{

а затем перекомпилировав и выполнив программу, вы получите "легкую" кнопку, но увидите, что ее фон стал белым, потому что метод

setBackground(Color.lightGray) не сработал.

Это объясняется тем, что теперь всю черную работу по изображению кнопки на экране выполняет не peer-двойник кнопки, а "тяжелый" контейнер, в котором расположена кнопка, в нашем случае класс Frame. Контейнер же ничего не знает о том, что надо обратиться к методу setBackground о, он рисует только то, что записано в методе paint (). Придется убрать метод setBackground о из конструктора и заливать фон серым цветом вручную в методе paint о, как показано в листинге 10.8.

"Легкий" контейнер не умеет рисовать находящиеся в нем "легкие" компоненты, поэтому в конце метода paint () "легкого" контейнера нужно обратиться к методу paint () суперкласса: 

super.paint(g);

Тогда рисованием займется "тяжелый" суперкласс-контейнер. Он нарисует и лежащий в нем "легкий" контейнер, и размещенные в контейнере "легкие" компоненты.

Совет

Завершайте метод paint () "легкого" контейнера обращением к методу paint () суперкласса.

Предпочтительный размер "тяжелого" компонента устанавливается peer-объектом, а для "легких" компонентов его надо задать явно, переопределив метод getPreferredSize(), иначе некоторые менеджеры размещения, например FiowLayout (), установят нулевой размер, и компонент не будет виден на экране.

Совет

Переопределяйте метод getPref erredSize () .

Интересная особенность "легких" компонентов — они изначально рисуются прозрачными, не закрашенная часть прямоугольного объекта не будет видна. Это позволяет создать компонент любой видимой формы. Листинг 10.8 показывает, как можно изменить метод paint о листинга 10.7 для создания круглой кнопки и задать дополнительные методы, а рис. 10.8 демонстрирует ее вид.

Листинг 10.8. Создание круглой кнопки ;

public void paint(Graphics g){

int w = getSize().width, h = getSize().height;

int d = Math.min(w, h);      // Диаметр круга

Color с = g.getColor();      // Сохраняем текущий цвет

g.setColor(Color.lightGray); // Устанавливаем серый цвет

g.fillArc(0, 0, d, d, 0, 360); // Заливаем круг серым цветом

g.setColor(с);               // Восстанавливаем текущий цвет

if (isDown)(

g.drawArc(0, 0, d, d, 43, 180);

g.drawArcd, 1, d - 2, d - 2, 43, 180);

drawFlower(g, 8, 10, d, d);

}else{

g.drawArc(0, 0, d, -d, 229, 162);

g.drawArcd, 1, d - 2, d - 2, 225, 170);

drawFlower(g, 6, 8, d, d); 

public Dimension getPreferredSize(){

return new Dimension(30,30); 

}

public Dimension getMinimumSize()

{

return getPreferredSize(); } 

public Dimension getMaximumSize(){

return getPreferredSize(); 

}

 Рис. 10.8. Круглая кнопка

Сразу же надо дать еще одну рекомендацию. "Легкие" контейнеры не занимаются обработкой событий без специального указания. Поэтому в конструктор "легкого" компонента следует включить обращение к методу enabieEvents () для каждого типа событий. В нашем примере в конструктор класса FiowerButton полезно добавить строку

enabieEvents(AWTEvent.MOUSE_EVENT_MASK);

на случай, если кнопка окажется в "легком" контейнере. Подробнее об этом мы поговорим в главе 12.

В документации есть хорошие примеры создания "легких" компонентов, посмотрите страницу docs\guide\awt\demos\lightweight\index.htm.