Афоризм
Шаман за скверную погоду недавно в бубен получил.
Последние статьи

 • Активности Android
Многоэкранные Android приложения
 • Fragment dynamic
Динамическая загрузка фрагментов в Android
 • Fragment lifecycle
Жизненный цикл Fragment'ов в Android
 • Fragment example
Пример Fragment'ов в Android
 • Data Binding
Описание и пример Data Binding
 • Пример MVVM
Пример использования MVVM в Android
 • Компонент TreeTable
Описание компонента TreeTable для Swing
 • Пример TreeTable
Пример использования TreeTable
 • Хранилища Android
Внутренние и внешние хранилища данных
 • Пример SQLite
Пример использования SQLite в Android
 • WebSocket
Описание и пример реализации WebSocket
 • Визуальные компоненты
Улучшен компонент выбора даты из календаря
 • Анимация jQuery
Описание и примеры анимации элементов DOM
 • APK-файл Android
Создание apk-файла для android устройств, .dex файлы
 • платформа JaBricks
Платформа OSGi-приложения JaBricks
Поддержка проекта

Если Вам сайт понравился и помог, то будем признательны за Ваш «посильный» вклад в его поддержку и развитие
 • Yandex.Деньги
  410013796724260

 • Webmoney
  R335386147728
  Z369087728698

JTabbedPane, JSplitPane, JViewPort

Панель с вкладками JTabbedPane позволяет в компактном виде размещать визуальные компоненты в интерфейсе приложения. При этом пользователь может работать только с одной группой компонентов на одной из вкладок, в то время, как остальные компоненты на других вкладках будут скрыты. Таким образом можно рационально использовать пространство формы и, при этом, представлять логически связанные группы компонентов.

Разделяемая панель JSplitPane используется для гибкого распределения пространства между двумя компонентами. Она позволяет произвольным образом изменить соотношение размеров связанных компонентов.

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

В статье приводится пример использования компонента JViewPort, который является основой панели прокрутки, и который можно использовать в приложениях как «видоискатель».

Панель с вкладками JTabbedPane

JTabbedPane позволяет размещать компоненты на так называемых вкладках tabs. Вкладки могут включать надписи, иконки, всплывающие подсказки и располагаться сверху, снизу, слева и справа. Для добавления вкладки в панель JTabbedPane можно использовать методы add() или addTab(). Второй метод лучше соответствует производимому действию и параметры этого метода удобнее настраивать.

Методы addTab панели JTabbedPane

public void addTab(String title, Component component)
public void addTab(String title, Icon icon, Component component, String tip)

JTabbedPane включает два перегруженных метода addTab. В качестве параметров второму методу addTab необходимо передать надпись, соответствующую вкладке, иконку, если она используется, компонент и всплывающую подсказку.

Пример использования панели JTabbedPane

// Swing пример использования панели с вкладками JTabbedPane
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;

public class TabbedPaneTest extends JFrame
{
    private  final  Color[]  colors = {Color.cyan, Color.orange, Color.magenta, Color.blue, 
                                       Color.red , Color.green , Color.yellow , Color.pink };
    private  final  String   TEMPL_label   = "Метка %d";
    private  final  String   TEMPL_dynamic = "Динамическая метка %d";
    private  final  String   TEMPL_button  = "Кнопка %d";
    private  final  String   TEMPL_tab     = "Вкладка %d";
    public TabbedPaneTest()
    {
        super("Пример панели с вкладками JTabbedPane");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        // Левая панель с вкладками
        JTabbedPane tabsLeft = new JTabbedPane(JTabbedPane.BOTTOM,
                                               JTabbedPane.SCROLL_TAB_LAYOUT);
        // Создание вкладок
        for (int i = 1; i < colors.length; i++) {
            JPanel panel = new JPanel();
            // Подкрашиваем панель
            panel.setBackground(colors[i - 1]);
            // Размещение метки во вкладке
            panel.add(new JLabel(String.format(TEMPL_label, i)));
            // Добавление вкладки
            tabsLeft.addTab(String.format(TEMPL_tab, i), panel);
            // Подключение мнемоники
            tabsLeft.setMnemonicAt(i-1, String.valueOf(i).charAt(0));
        }
        // Подключение слушателя событий
        tabsLeft.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                // Получение выделенной вкладки
                JPanel panel = (JPanel)((JTabbedPane)e.getSource()).getSelectedComponent();
                // Количество компонентов в панели
                int count = panel.getComponentCount(); 
                // Добавление на вкладку новой метки
                panel.add(new JLabel(String.format(TEMPL_dynamic, count)));
            }
        });
        // Подключение слушателя мыши
        tabsLeft.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                // Определяем индекс выделенной мышкой вкладки
                int idx = ((JTabbedPane)e.getSource()).indexAtLocation(e.getX(), e.getY());
                System.out.println("Выбрана вкладка " + idx);
            }
        });
        
        // Правая панель с вкладками
        JTabbedPane tabsRight = new JTabbedPane(JTabbedPane.TOP);
        // Создание вкладок
        for (int i = 1; i < colors.length; i++) {
            // Создание и подкрашивание панели
            JPanel panel = new JPanel();
            panel.setBackground(colors[colors.length - i]);
            // Создание кнопки в панели
            panel.add(new JButton(String.format(TEMPL_button, i)));
            // Добавление панели во вкладку 
            tabsRight.addTab("<html><i>Вкладка №" + i, 
                             new ImageIcon("images/copy.png"), panel, "Нажмите " + i);
        }
        // Определение табличного расположения компонентов
        getContentPane().setLayout(new GridLayout());
        // Добавление вкладок в панель содержимого
        getContentPane().add(tabsLeft);
        getContentPane().add(tabsRight);
        // Вывод окна на экран
        setSize(600, 250);
        setVisible(true);
    }
    public static void main(String[] args) {
        new TabbedPaneTest();
    }
}

В примере создается окно, в котором размещается две панели с вкладками JTabbedPane. Левая панель создается с помощью конструктора, принимающего два параметра: первый параметр определяет расположение вкладок, а второй указывает, как вкладки будут располагаться на экране в том случае, если их не удастся разместить в один ряд. Вкладки по умолчанию располагаются в несколько рядов. Такому поведению соответствует константа WRAP_TAB_LAYOUT. В примере для панели выбрана константа SCROLL_TAB_LAYOUT, добавляющая в панель небольшие кнопки прокрутки. Вкладки в панель добавляются в цикле методом addTab(); в качестве содержимого каждой вкладки используется подкрашенная панель JPanel с меткой JLabel. Для каждой вкладки методом setMnemonicAt определяется мнемоника, позволяющая выполнять переход по нажатию на клавиши ALT-N, где N - номер вкладки.

Интерфейс окна представлен на следующем скриншоте.

Правая панель JTabbedPane создается с помощью более простого конструктора, в котором указывается лишь верхнее расположение вкладок JTabbedPane.TOP. Способ размещения вкладок на экране остается заданным по умолчанию. Вкладки также добавляются в цикле, как и в первом случае, но используется более функциональная перегруженная версия метода addTab(). Она принимает сразу четыре параметра: надпись для вкладки, иконка, компонент, который будет отображаться во вкладке, и текст всплывающей подсказки. Заголовок вкладки определен в формате HTML.

В классе JTabbedPane все свойства доступны с использованием методов get/set. Поэтому параметры панели с вкладками нетрудно изменить в любой момент, вызвав соответствующие методы, представленные в следующей таблице.

Свойства (методы get/set)Описание
tabPlacement Определение расположения вкладок у одной из четырех сторон панели. По умолчанию конструктор JTabbedPane без параметров располагает вкладки в вверхней части панели.
tabLayoutPolicy Определение расположения вкладок при не достаточном месте для их размещения в один ряд. Режим WRAP_TAB_LAYOUT, используемый по умолчанию, позволяет разместить вкладки в несколько рядов, а режим SCROLL_TAB_LAYOUT — оставить их в одном ряду с добавлением кнопок прокрутки.
titleAt, iconAt Свойства определения надписи и иконки для вкладки. В качестве первого параметра указывается индекс вкладки; отсчет от нуля.
toolTipTextAt Текст всплывающей подсказки к вкладке. Первым параметром метода является индекс вкладки. В режиме прокрутки вкладок (SCROLL_TAB_LAYOUT) подсказки не выводятся
foregroundAt, backgroundAt Определение цвета шрифта и фона отдельной вкладки.

Единственное событие, поддерживаемое панелью с вкладками JTabbedPane, за исключением низкоуровневых событий (общих для всех графических компонентов), относится именно к модели ее активизации. Добавив к панели JTabbedPane слушателя ChangeListener, можно перехватывать событие смены вкладки. В примере в обработчике данного события в панель активной вкладки добавляется текстовая метка.

Разделяемая панель JSplitPane

Разделяемая панель JSplitPane используется для гибкого распределения пространства между двумя компонентами и представляет тонкую полосу. Перетаскиванием мышью этой полосы можно изменить соотношение занимаемого общего пространства двумя компонентами.

Пример разделяемой панели JSplitPane

import java.awt.Color;

// Swing пример использование разделяемой панели JSplitPane

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.*;

public class SplitPaneTest extends JFrame
{
    private JLabel lblMain;
    private int    dividerMain = 200;
    private final  String TEMPL_lbl = "dividerLocation = %d";
    public SplitPaneTest()
    {
        super("Пример разделяемой панели JSplitPane");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        // Главная разделяемая панель
        final JSplitPane splitHorizontal = new JSplitPane();
        splitHorizontal.setOneTouchExpandable(true);
        // Размер разделяемой панели
        splitHorizontal.setDividerSize(8);
        // Положение разделяемой панели
        splitHorizontal.setDividerLocation(dividerMain);
        // Вертикальная разделяемая панель
        JSplitPane splitVertical = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true);
        // Создание панелей
        splitVertical.setTopComponent   (new JScrollPane());
        splitVertical.setBottomComponent(new JScrollPane());
        // Положение разделяемой панели
        splitVertical.setDividerLocation(100);
        // Текстовая метка для главной панели
        lblMain = new  JLabel(String.format(TEMPL_lbl, dividerMain));
        // Главная панель
        JPanel pnlMain = new JPanel();
        pnlMain.add(lblMain);
        pnlMain.setBackground(Color.cyan);
        // Настройка главной панели
        splitHorizontal.setLeftComponent(new JScrollPane(pnlMain));
        splitHorizontal.setRightComponent(splitVertical);
        // Слушатель изменения свойств разделяемой панели
        splitHorizontal.addPropertyChangeListener(new PropertyChangeListener()
        {
            @Override
            public void propertyChange(PropertyChangeEvent arg0)
            {
                dividerMain = splitHorizontal.getDividerLocation();
                lblMain.setText(String.format(TEMPL_lbl, dividerMain));
            }
        });
        // Размещение панели в интерфейсе и вывод окна на экран
        getContentPane().add(splitHorizontal);
        setSize(600, 400);
        setVisible(true);
    }
    public static void main(String[] args) {
        new SplitPaneTest();
    }
}

В примере создается небольшое окно, в панели содержимого которого размещаются две разделяемые панели JSplitPane : горизонтальная и вертикальная. В горизонтальных панелях компоненты располагаются в ряд, в вертикальных панелях - друг над другом. Горизонтальная разделяемая панель создается по умолчанию. Для главной разделяемой панели splitHorizontal был использован конструктор без параметров.

После создания компонента splitHorizontal были установлены свойства разделяемой панели. Свойство oneTouchExpandable=true позволяет добавить к разделителю компонентов две маленькие кнопки со стрелками, щелкая на которых можно мгновенно переместить панель в крайнее положение, полностью предоставив все пространство разделяемой панели одному из компонентов. Свойство dividerSize управляет размером разделительной полосы в пикселах. Метод setDividerLocation позволяет определить положение панели в интерфейсе. В качестве левого компонента главной разделяемой панели устанавливается (метод setLeftComponent) панель с текстовой меткой, в которой отображается положение splitHorizontal.

Слушатель PropertyChangeListener, подключенный к разделяемой панели, позволяет отслеживать изменение позиции splitHorizontal, значение которой отображается в текстовой метке lblMain.

Вторая вертикальная разделяемая панель создается конструктором, который принимает два параметра: первый задает тип панели (вертикальная или горизонтальная), а второй позволяет сразу же определить, будут ли компоненты при перемещении разделительной полосы непрерывно обновляться (перерисовываться и, если это сложный компонент, проводить проверку корректности). По умолчанию непрерывное обновление отключено. Непрерывное обновление можно включить (или выключить) и после создания разделяемой панели, меняя значение свойства continuousLayout.

Разделяемые панели используют методы setTopComponent() и setBottomComponent(), позволяющие определить верхний и нижний компоненты соответственно. Для горизонтального разделения используются методы setLeftComponent() и setRightComponent. Следует обратить внимание, что при размещении компонентов в разделительные полосы используются полосы прокрутки JScrollPane. Использовать панели прокрутки для компонентов, содержащихся в разделяемой панели, приходится почти всегда, поскольку разделяемая панель учитывает минимальный размер компонента и не позволяет делать его размер меньше. Если минимальный размер компонента значим (к примеру, минимальный размер надписи со значком равен размеру значка), толку от разделяемой панели будет мало — она просто не позволит изменять размеры компонентов и гибко распределять пространство контейнера. Принимая это во внимание, необходимо включать компоненты в панели прокрутки.

Интерфейс примера с разделяемой панелью JSplitPane представлен на следующем скриншоте.

Дополнительные свойства разделяемой панели JSplitPane

СвойстваОписание
dividerLocation Для этого свойства имеется два перегруженных метода set: первый принимает в качестве параметра целое число (int), определяющее положение в пикселах от левой/верхней границы разделяемой панели должно быть до полосы. Вторая версия метода требует параметр типа double (от нуля до единицы). Фактически это значение в процентах, показывающее, какую часть разделяемой панели будет занимать левая/верхняя ее часть.
resizeWeight Указывает, как должно распределяться избыточное пространство, если разделяемая панель увеличивается в размерах. Это свойство имеет тип double и работает точно так же, как и вторая версия предыдущего свойства. Остальная часть достанется правой/нижней панели

Панель прокрутки JScrollPane

Панель прокрутки JScrollPane дает возможность наделить компонент большого размера возможностью прокрутки на экране. JScrollPane добавляет в интерфейс, две полосы прокрутки, используя которые можно переходить к той или иной части компонента и отображать их на экране. Как правило, для добавления панели прокрутки к компоненту достаточно использовать следующий код :

add(new JScrollPane(<компонент>);

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

Рассмотрим небольшой пример, в котором настроим простые свойства панели прокрутки JScrollPane.

// Использование панелей прокрутки JScrollPane
import javax.swing.*;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;

public class ScrollPaneTest extends JFrame
{
    private  JLabelGrid label;
    public ScrollPaneTest()
    {
        super("Пример использования JScrollPane");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        // Создание панели прокрутки
        label = new JLabelGrid();
        JScrollPane scrollPane = new JScrollPane(label, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                                                        JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        // Устанавливаем заголовки
        scrollPane.setColumnHeaderView(new XHeader());
        scrollPane.setRowHeaderView   (new YHeader());
        // Определение свойств панели прокрутки
        scrollPane.setViewportBorder(BorderFactory.createLineBorder(Color.yellow));
        scrollPane.setWheelScrollingEnabled(true);
        // Размещение кнопки  печати в левом верхнем углу
        scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, 
                             new JButton(new ImageIcon("images/print.gif")));
        // Вывод окна на экран
        getContentPane().add(scrollPane);
        setSize(450, 300);
        setVisible(true);
    }
    // Внутренний класс
    class JLabelGrid extends JLabel implements Scrollable
    {
        private static final long serialVersionUID = 1L;
        
        private int CELL_SIZE  = 10;  // размер ячейки сетки
        private int CELL_COUNT = 50;  // количество ячеек сетки

        public JLabelGrid()
        {
            // Изображение волков
            setIcon(new ImageIcon("images/wolf.jpg"));
        }
        // Предпочтительный размер компонента
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(CELL_SIZE*CELL_COUNT, CELL_SIZE*CELL_COUNT);
        }
        // Прорисовка компонента
        @Override
        public void paintComponent(Graphics g) {
            // Вызов метода базового класса
            super.paintComponent(g);
            for (int x = 0; x < CELL_COUNT; x++) {
                for (int y = 0; y < CELL_COUNT; y++) {
                    // Прорисовывем ячейку
                    g.setColor(Color.black);
                    g.drawRect(x*CELL_SIZE, y*CELL_SIZE, CELL_SIZE, CELL_SIZE);
                }
            }
        }
        // Предпочтительный размер области прокрутки
        @Override
        public Dimension getPreferredScrollableViewportSize() {
            return getPreferredSize();
        }
        // Приращение при прокрутке на один элемент
        @Override
        public int getScrollableUnitIncrement(Rectangle visible, int or, int dir) {
            return CELL_SIZE;
        }
        // Приращение при прокрутке "блоком"
        @Override
        public int getScrollableBlockIncrement(Rectangle visible, int or, int dir) {
            return CELL_SIZE*10;
        }
        // Контроль размера области прокрутки
        @Override
        public boolean getScrollableTracksViewportWidth() {
            return false;
        }
        @Override
        public boolean getScrollableTracksViewportHeight() {
            return false;
        }
    }
    // Заголовок по оси X
    class XHeader extends JPanel
    {
        // Размер заголовка
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(label.getPreferredSize().width, 20);
        }
        // Прорисовываем линейку
        @Override
        public void paintComponent(Graphics g) {
            int width = getWidth();
            for (int i = 0; i < width; i += 50) {
                g.drawString("" + i, i, 15);
            }
        }
    }
    // Заголовок по оси Y
    class YHeader extends JPanel
    {
        // Размер заголовка
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(20, label.getPreferredSize().height);
        }
        // Прорисовываем линейку
        @Override
        public void paintComponent(Graphics g) {
            int height = getHeight();
            for (int i = 0; i < height; i += 50) {
                g.drawString("" + i, 0, i);
            }
        }
    }
    public static void main(String[] args)
    {
        new ScrollPaneTest();
    }
}

В примере для создания панели прокрутки используется конструктор JScrollPane с тремя параметрами, в котором первым размещается компонент JLabelGrid, нуждающийся в прокрутке. Второй и третий параметры управляют полосами прокрутки. Второй параметр определяет поведение вертикальной полосы прокрутки, третий — горизонтальной. По умолчанию используются описанные в классе JScrollPane в качестве констант значения XXX_SCROLLBAR_AS_NEEDED (где XXX может принимать значение VERTICAL или HORIZONTAL). Они указывают, что полосы прокрутки должны появляться на экране только в том случае, если компонент в панели прокрутки действительно велик и ему требуется прокрутка. В примере использовали значение SCROLLBAR_ALWAYS, которое означает, что полосы прокрутки будут находиться на экране в любом случае, даже если прокрутка не требуется. Есть и еще один режим вывода полос прокрутки — XXX_SCROLLBAR_NEVER. При выборе этого значения появление полос прокрутки на экране блокируется, даже если в этом возникает необходимость.

Панель прокрутки всегда добавляет особую рамку к видимой части компонента. Видимая часть компонента выводится на экран окном просмотра JViewport. Рамку панели прокрутки можно сменить с помощью свойства viewportBorder. В примере она меняется рамкой LineBorder желтого цвета. Наконец, свойство wheelScrollingEnabled определяет, будет ли поддерживаться прокрутка колесиком мыши.

Интерфейс примера с использованием JScrollPane представлен на следующем скриншоте.

Особый интерес представляет компонент JLabelGrid, реализующий свой режим прокрутки с помощью интерфейса Scrollable. Было отмечено, что если панель прокрутки JScrollPane обнаруживает, что размещенный в ней компонент реализует данный интерфейс, она настраивает процесс прокрутки согласно информации, возвращаемой описанными в нем методами. Методы интерфейса Scrollable представлены в следующей таблице.

Наименование методаОписание метода
getPreferredScrollableViewportSize() Возвращает предпочтительный размер для области прокрутки компонента. Как правило, этот размер совпадает с предпочтительным размером самого компонента. За примером далеко ходить не надо, и можно посмотреть на раскрывающийся список JComboBox, который выводит перечень своих элементов именно в панели прокрутки. С помощью свойства maximumRowCount компонента JComboBox можно ограничить количество выводимых элементов, даже если есть возможность вывести на экран их все. В данном случае роль ограничителя играет размер, возвращаемый данным методом.
getScrollableUnitlncrement() Возвращает приращение в пикселах, на которое должно сместиться изображение в панели прокрутки при нажатии на кнопку полосы прокрутки. В примере возвращается размер ячейки сетки. На самом деле, сетку логичнее всего прокручивать по одной ячейке. Параметрами данного метода являются видимая часть изображения, ориентация полосы прокрутки JScrollBar (вертикальная или горизонтальная) и тип прокрутки назад или вперед, соответственно положительное или отрицательное число. Анализ и обработка данных параметров позволяет реализовать «тонкую» прокрутку, зависящую от позиции изображения и направления прокрутки.
getScrollableBlocklncrement() Возвращает приращение в пикселах при прокрутке «блоком». Данное приращение происходит при нажатии на полосе прокрутки, а не на кнопках. В примере блок состоит из 10 ячеек и не зависит от параметров. Параметры данного метода аналогичны параметрам метода предыдущего. На их основании также можно возвращать различные приращения в зависимости от позиции изображения и направления прокрутки.
getScrollableTracksViewportWidth(),
getScrollableTracksViewportHeight()
Эти методы возвращают булевые значения, показывающие зависимость содержимого компонента в области прокрутки, от размеров последней. Первый метод говорит о ширине области прокрутки, второй — о высоте. Это означает следующее : вместо того чтобы положиться на механизм прокрутки и не менять свой размер при изменении размеров контейнера, компонент следит за изменениями размеров и соответственным образом меняет свое содержимое, чтобы оно в доступные размеры помещалось. Как правило, методы эти возвращают true только по отдельности, так как фактически это означает отказ от прокрутки — компонент вместо этого заявляет, что постарается вместить содержимое в то пространство, что ему доступно. Чаще всего эти методы применяются там, где компонент отказывается от прокрутки по одному из направлений, вертикальному или горизонтальному. Примером может служить текстовое поле с переносом по словам. Несмотря на то, что вертикальная прокрутка такому полю нужна, горизонтальная ему уже не понадобится, так как слова переносятся автоматически и длина строки может быть любой.

Полоса прокрутки JScrollPane не что иное, как удобный «фасад» для системы, занимающейся прокруткой компонента. Эта система состоит из специальным образом расположенных вспомогательных компонентов для прокрутки : вертикальных и горизонтальных полос прокрутки, заголовков и «уголков» панели. Отображение лишь части от целого компонента и переход к другим его частям лежит на плечах компонента JViewport, основной рабочей «лошадки» системы прокрутки.

Заголовки панели прокрутки дополняют прокручиваемый компонент сверху и слева, позволяя размещать в них вспомогательную информацию. Как правило, заголовки используются в качестве навигационных или информационных дополнений: линеек или координатных осей, которые помогают быстро определить размеры прокручиваемой области, текущую позицию или получить иную вспомогательную информацию.

В примере к панели прокрутки добавлены заголовки и размещена кнопка печати в левом верхнем уголке. Определить заголовки позволяют свойства columnHeaderView и rowHeaderView (верхний и левый заголовки соответственно). В качестве заголовков были использованы специальные компоненты, представленные в виде внутренних классов XHeader и YHeader. Они унаследованы от панелей JPanel и прорисовывают координатную сетку по оси X и Y с шагом в 50 пикселов.

Обратите внимание на то, какой размер возвращается методами getPreferredSize() : по одной из осей он постоянен, а по второй зависит от компонента, находящегося в панели прокрутки. При создании заголовков чаще всего приходится поступать именно так : размеры заголовков должны совпадать с размерами области прокрутки, иначе они будут не в состоянии сообщить информацию обо всей прокручиваемой области.

«Видоискатель» JViewport

Компонент JViewport удобно представлять себе в виде своеобразного «видоискателя», работающего примерно так же, как в фотоаппарате : есть общая картина, которую хотелось бы запечатлеть, но доступного пространства меньше. JViewport позволяет показывать часть компонента и при необходимости перемещаться к любой другой его части.

К основным возможностям класса JViewport относится определение компонента для отображения, называемого видом, определение размера области для отображения, называемой видимым диапазоном (extent) и определение точки левого верхнего угла в области координат вида, с которой и отсчитывается видимая область. Управляя точкой левого верхнего угла можно отображать различные части компонента.

«Видоискатель» JViewport редко применяется изолированно. Но если потребуется реализовать нестандартный способ прокрутки, то компонент JViewport может быть полезен и сам по себе. В следующем примере метка JLabel с изображением волков, размещается не в полосе прокрутки JscrollPane, а в JViewport.

// Пример работы с компонентом JViewport

import javax.swing.*;

import java.awt.*;

public class ViewportTest extends JFrame
{
    public ViewportTest()
    {
        super("Пример JViewport");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        // Метка с изибражением
        JLabel label = new JLabel(new ImageIcon("images/wolf.jpg"));
        // "Видоискатель"
        JViewport viewport = new JViewport();
        // Настройка "видоискателя" - размещение метки
        viewport.setView(label);
        // Определение видимого диапазона
        viewport.setExtentSize(new Dimension(200, 200));
        // Точка начала видимой области
        viewport.setViewPosition(new Point(150, 150));
        // Ограничение размера "видоискателя"
        viewport.setPreferredSize(new Dimension(200, 200));
        // Определение менеджера расположения
        getContentPane().setLayout(new FlowLayout());
        // Вывод окна на экран
        getContentPane().add(viewport);
        setSize(400, 300);
        setVisible(true);
    }
    public static void main(String[] args) {
        new ViewportTest();
    }
}

С помощью «видоискателя» JViewport в интерфейсе отображается только часть большого изображения. На следующем скриншоте представлен интерфейс примера использования JViewport.

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

Скачать примеры

Исходные коды примеров, рассмотренных на странице, можно скачать здесь (133 Кб).

  Рейтинг@Mail.ru