Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых
[Назад]

Библиотека примеров приложений Java

Оглавление
Режим FlowLayout
Режим GridLayout
Режим BorderLayout
Режим CardLayout
GridBagLayout -  пример 1
GridBagLayout - заполнение формы
Инструментальная линейка
Панели
Точное размещение компонент
Прилипчивая кнопка

Назад Вперед

5.8. Панели и инструментальная линейка

Пример демонстрирует использование панелей с режимом размещения GridBagLayout. С помощью панели инструментальной линейки с кнопками вы сможете просматривать изображения.

Исходный текст примера

Архив проекта для Java WorkShop 2.0

Демонстрация
(ваш браузер должен уметь работать с аплетами Java JDK 1.1)

Немного теории

Существует еще один способ создания инструментальных панелей, основанных на использовании класса Panel. Этот класс является контейнером и потому вы можете размещать внутри объекта класса Panel различные компоненты и другие контейнеры.

Описание примера

В окно аплета мы добавляем два контейнера, созданных на базе класса Panel. Первый из них используется для поочередного отображения рисунков, а второй представляет собой инструментальную панель с кнопками (рис. 1).

pic1.gif (7074 bytes)

Рис. 1. Окно аплета с двумя добавленными в него панелями

Нажимая кнопки, вы можете по очереди просматривать графические изображения.

Рассмотрим исходный текст аплета.

Главный класс аплета PanelDemo

Главный класс нашего аплета не имеет никаких особенностей:

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class PanelDemo extends Applet
{
  . . .
}

Он создан на базе класса Applet.

Поля ip и bp хранят, соответственно, ссылки на панель изображений и панель инструментальной линейки с кнопками:

ImagePanel ip;
ButtonPanel bp;

В массиве imgSlides записаны ссылки на отображаемые рисунки.

Image[] imgSlides;
Метод init

В процессе инициализации аплета метод init создает массив изображений и загружает в него ссылки на изображения. При этом метод дожидается окончания процесса загрузки при помощи специально предназначенного для выполнения такой операции класса MediaTracker:

imgSlides = new Image[7];
    
MediaTracker tr = new MediaTracker(this);
for(int i = 0; i < 7; i++)
{
  imgSlides[i] = getImage(getCodeBase(), 
    "pic0" + (i + 1) + ".gif");
        
  tr.addImage(imgSlides[i], 0);
  try
  {
    tr.waitForAll();
  }
  catch (InterruptedException e) {}
}

Далее метод init создает панели:

ip = new ImagePanel(imgSlides);
bp = new ButtonPanel(ip);

Конструктору панели изображений передается ссылка на массив изображений, а конструктору панели инструментальной линейки - ссылка на панель изображений.

Затем мы устанавливаем режим размещения компонент GridBagLayout:

GridBagLayout gbl = new GridBagLayout();
GridBagConstraints c = 
  new GridBagConstraints();
    
setLayout(gbl);

Ниже мы устанавливаем параметры размещения для панели изображений и добавляем эту панель в окно аплета:

c.anchor = GridBagConstraints.CENTER; 
c.fill   = GridBagConstraints.NONE;  
c.gridheight = 1;
c.gridwidth  = 1;
c.gridx = GridBagConstraints.RELATIVE; 
c.gridy = GridBagConstraints.RELATIVE; 
c.insets = new Insets(5, 10, 5, 10);
    
gbl.setConstraints(ip, c);
add(ip);

При размещении панель центрируется. Она занимает одну ячейку таблицы и для нее задаются небольшие отступы с каждой стороны.

Параметры размещения панели кнопок устанавливаются аналогично:

c.insets = new Insets(0, 0, 0, 0);
c.fill   = GridBagConstraints.NONE;  
gbl.setConstraints(bp, c);
add(bp);

Отличие заключается в том, что здесь мы не задаем отступы.

Класс ImagePanel

Класс ImagePanel создан на базе класса Panel и потому объекты этого класса являются контейнерами:

class ImagePanel extends Panel
{
  . . .
}

Рассмотрим определенные в этом классе поля.

В поле dm хранятся текущие размеры панели изображения:

Dimension dm;

В поле imgSlides хранится массив изображений:

Image[] imgSlides;

Номер текущего изображения для рисования в окне панели записан в поле currentImage:

int currentImage = 0;

Поле dimMinSize хранит размер панели, которые устанавливаются несколько большим по сравнению с размерами изображений:

Dimension dimMinSize;
Конструктор класса ImagePanel

В задачу конструктора класса ImagePanel входит получение размеров самого первого изображения в массиве и установка минимальных размеров окна панели:

public ImagePanel(Image[] img)
{
  int imHeight;
  int imWidth;
    
  imgSlides = img;
  imHeight = img[0].getHeight(this);
  imWidth = img[0].getWidth(this);
    
  dimMinSize = 
    new Dimension(imWidth + 4, imHeight + 4);
}

Предполагается, что все изображения имеют одинаковые размеры.

Метод paint класса ImagePanel

Этот метод рисует текущее изображение в окне панели со смещением в два пиксела:

public void paint(Graphics g)
{
  super.paint(g);
  dm = getSize();
    
  g.drawImage(imgSlides[currentImage],
   2, 2, this);
    
  g.drawRect(0, 0,
   dm.width - 1, dm.height - 1);
}

Номер текущего изображения берется из поля currentImage. После рисования изображение обводится тонкой рамкой, которая по умолчанию будет иметь черный цвет.

Другие методы класса ImagePanel

В классе ImagePanel определены еще несколько методов, возвращающих размеры окна панели:

public Dimension getPreferredSize()
{
  return dimMinSize;
}

public Dimension getMinimumSize()
{
  return dimMinSize;
}
  
public Dimension preferredSize()
{
  return dimMinSize;
}
  
public Dimension minimumSize()
{
  return dimMinSize;
}

Класс ButtonPanel

Класс ButtonPanel также создан на базе класса Panel:

class ButtonPanel extends Panel
  implements ActionListener
{
  . . .
}

Так как в окне этой панели размещены кнопки, для обработки создаваемых ими событий мы реализуем интерфейс ActionListener.

Поля класса хранят размеры панели, массив ссылок на кнопки и ссылку на панель изображений:

Dimension dm;
Button[] button;
ImagePanel ip;
Конструктор класса ButtonPanel

Прежде всего конструктор сохраняет ссылку на панель изображений в поле ip:

ip = ipanel;

Далее он создает массив кнопок:

button = new Button[7];

Перед добавлением кнопок в окно панели мы устанавливаем режим размещения GridBagLayout:

GridBagLayout gbl = new GridBagLayout();
GridBagConstraints c = 
  new GridBagConstraints();
    
setLayout(gbl);

Параметры размещения всех кнопок, кроме последней, одинаковые:

c.anchor = GridBagConstraints.NORTHWEST; 
c.fill   = GridBagConstraints.NONE;  
c.gridheight = 1;
c.gridwidth  = GridBagConstraints.REMAINDER;
c.gridx = GridBagConstraints.RELATIVE; 
c.gridy = GridBagConstraints.RELATIVE; 
c.weightx = 1;
c.weighty = 0;
c.insets = new Insets(5, 10, 0, 10);

Каждая кнопка в нашем случае является единственной в своей строке, поэтому для параметра gridwidth мы выбрали значение GridBagConstraints.REMAINDER.

Параметр insets последней кнопки задается при ее добавлении, которое выполняется в цикле:

for(int i = 0; i < 7; i++)
{
  button[i] = 
    new Button("Image " + (i + 1));
      
  if(i == 6)
    c.insets = new Insets(5, 10, 5, 10);
      
  gbl.setConstraints(button[i], c);
  add(button[i]);
      
  button[i].addActionListener(this);
}
Метод paint класса ButtonPanel

Задачей этого метода является рисование тонкой рамки красного цвета по краю панели кнопок:

public void paint(Graphics g)
{
  super.paint(g);
  dm = getSize();
    
  g.setColor(Color.red);
  g.drawRect(0, 0,
    dm.width - 1, dm.height - 1);
}
Метод actionPerformed класса ButtonPanel

Этот метод получает управление, когда пользователь нажимает на одну из кнопок инструментальной панели:

public void actionPerformed(ActionEvent e)
{
  for(int i = 0; i < 7; i++)
  {
    if(e.getSource().equals(button[i]))
    {
      ip.currentImage = i;
      ip.repaint();
    }
  }
}

Он ищет в цикле нажатую кнопку, и, если находит, устанавливает в переменной currentImage значение, равное номеру кнопки. Затем метод перерисовывает окно панели изображений. В результате там рисуется новое изображение с номером, равным номеру нажатой кнопки.


Назад Вперед

[Назад]