| « Разработка веб-страниц с помощью google gears. Часть 3 | Разработка веб-страниц с помощью google gears. Часть 4 » |
Про java swing - часть 6
Элемент управления (контейнер) JscrollPane
Данные элементы представляют контейнеры для других элементов или контейнеров. Область прокрутки – не только набор полос и находящийся внутри элемент. Фактически область прокрутки состоит из 7 зон – одна из них центральная в которой находится сам элемент управления, две зоны образуют заголовок и левую границу и еще четыре – уголки прямоугольника, согласно приведенному рисунку.

Следующий пример был взят и творчески адаптирован на основании Dem-ки из учебника swing на сайте sun. Однако тот пример мне не понравился, т.к. при изменении размера области и скролинге возникали баги отрисовки - линейки не изменяли свой размер. Посмотрите примечания по этой теме внизу в примере использования Rule.
Сначала пример компонента играющего роль "линейки" расположенной слева и сверху основной области прокрутки. В качестве параметра конструктору класса Rule передается флаг ориентации линейки (горизонтальная или вертикальная), таке указываем единицы измерения (ну что с буржуев с их дюймами и ярдами возьмешь ...)
class Rule extends JComponent {
public static final int INCH = Toolkit.getDefaultToolkit().getScreenResolution();
// получаем сведения о разрешении экрана - сколько точек на дюймpublic static final int HORIZONTAL = 0;// константы указывающие на режим создаваемой области линейки
public static final int VERTICAL = 1;
public static final int SIZE = 35;// размер по умолчанию для линейки
public int orientation;
public boolean isMetric;
private int increment;
private int units;
// при создании линейки прокрутки необходимо указать ее ориентацию и используемые единицы измерения// будут ли использованы дюймы или сантиметрыpublic Rule(int o, boolean m) {
orientation = o; // ориентация линейки - горизонтальная или вертикальная
isMetric = m;// единицы измерения
setIncrementAndUnits();// метод изменения размеров штриха, растояния между ними
}// установить режим метрической системыpublic void setIsMetric(boolean isMetric) {
this.isMetric = isMetric;
setIncrementAndUnits();
repaint();
}// функция выполняющая расчет величины приращения линейки прокрутки на основе текущих единиц измеренияprivate void setIncrementAndUnits() {
if (isMetric) {
// получаем сколько точек должно прийтись на один сантиметрunits = (int) ((double) INCH / (double) 2.54);
increment = units;
} else {
units = INCH;
increment = units / 2;
}}public boolean isMetric() {
return this.isMetric;
}public int getIncrement() {
return increment;
}// установка размеров линейки - линейка будет занимать размер// равный одному дюйму// все методы изменения размеров линейки сводятся к перевызову базового для всех компонентов метода setPreferedSizepublic void setPreferredHeight(int ph) {
setPreferredSize(new Dimension(SIZE, ph));
}public void setPreferredWidth(int pw) {
setPreferredSize(new Dimension(pw, SIZE));
}protected void paintComponent(Graphics g) {
// Метод, который выполняет рисование линейки для области прокрутки.// Обратите внимание на то, что здесь перекрыт не вызов paint, а, именно, paintComponent.// Дело в том, что paint выполняет рисование в следующей последовательности:// фон, САМ элемент, все дочерние элементы.// А метод paintComponent выполняет рисование именно САМОГО компонента.Rectangle drawHere = g.getClipBounds();
g.setColor(new Color(230, 253, 4));
g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height);
// первым шагом всю область линейки закрасили фоновым цветомg.setFont(new Font("SansSerif", Font.PLAIN, 10));
g.setColor(Color.black);
int end = 0;
int start = 0;
int tickLength = 0;
String text = null;
if (orientation == HORIZONTAL) {
start = (drawHere.x / increment) * increment;
end = (((drawHere.x + drawHere.width) / increment) + 1)
* increment;
} else {
start = (drawHere.y / increment) * increment;
end = (((drawHere.y + drawHere.height) / increment) + 1)
* increment;
}if (start == 0) {
text = Integer.toString(0) + (isMetric ? " cm" : " in");
tickLength = 10;
if (orientation == HORIZONTAL) {
g.drawLine(0, SIZE - 1, 0, SIZE - tickLength - 1);
g.drawString(text, 2, 21);
} else {
g.drawLine(SIZE - 1, 0, SIZE - tickLength - 1, 0);
g.drawString(text, 9, 10);
}text = null;
start = increment;
}for (int i = start; i < end; i += increment) {
if (i % units == 0) {
tickLength = 10;
text = Integer.toString(i / units);
} else {
tickLength = 7;
text = null;
}if (tickLength != 0) {
if (orientation == HORIZONTAL) {
g.drawLine(i, SIZE - 1, i, SIZE - tickLength - 1);
if (text != null)
g.drawString(text, i - 3, 21);
} else {
g.drawLine(SIZE - 1, i, SIZE - tickLength - 1, i);
if (text != null)
g.drawString(text, 9, i + 3);
}}}}}
public class ScrollDemo {
public static void main(String[] args) {
JFrame jf = new JFrame("scroller pic");
JLabel lab_img = new JLabel(new ImageIcon("C:\\tmp\\2011.jpg"));
final JScrollPane jscr = new JScrollPane(lab_img);
final Rule viewCol = new Rule(Rule.HORIZONTAL, true);
// Устанавливаем размер линейки по высоте – 32 пикселяviewCol.setPreferredHeight(32);
// Устанавливаем линейку по горизонтали. Заготоловок для области прокрутки.jscr.setColumnHeaderView(viewCol);
final Rule viewRow = new Rule(Rule.VERTICAL, true);
viewRow.setPreferredWidth(32);
// Здесь добавляется линейка по вертикали.// Она будет располжена по вертикали слева.jscr.setRowHeaderView(viewRow);
jscr.getViewport().addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
viewCol.setPreferredWidth(jscr.getViewport().getComponent(0).getWidth());
// а для viewRow я не выполнил изменения размера и поэтому там возникают баги отрисовки}});
// Здесь добавляются кнопки в уголки области прокруткиjscr.setCorner(JScrollPane.UPPER_LEFT_CORNER, new JToggleButton("TL"));
jscr.setCorner(JScrollPane.LOWER_LEFT_CORNER, new JToggleButton("BL"));
jscr.setCorner(JScrollPane.UPPER_RIGHT_CORNER, new JToggleButton("TR"));
jscr.setCorner(JScrollPane.LOWER_RIGHT_CORNER, new JToggleButton("BR"));
jf.getContentPane().add(jscr, BorderLayout.CENTER);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
}}
public JScrollPane(Component view, int vsbPolicy, int hsbPolicy)
| Политика | Примечание |
| VERTICAL_SCROLLBAR_AS_NEEDED и HORIZONTAL_SCROLLBAR_AS_NEEDED | Режим по умолчанию: полосы прокрутки появляются только тогда, когда в них есть необходимость. Т.е. когда область просмотра меньше, чем клиентская область просматриваемого компонента. |
| VERTICAL_SCROLLBAR_ALWAYS и HORIZONTAL_SCROLLBAR_ALWAYS | Всегда показывать полосы прокрутки. |
| VERTICAL_SCROLLBAR_NEVER и HORIZONTAL_SCROLLBAR_NEVER | Никогда не показывать полосы прокрутки. Такой режим используется, когда мы не хотим разрешить пользователю самостоятельно выполнять прокрукту. Например он использует другой элемент управления, а вы перевызываете методы прокрутки. |
Элемент управления (контейнер) JtabbedPane
Панель с закладками представляется с помощью класса JtabbedPane. Каждая закладка представлена в виде произвольного компонента Swing. Также закладка характеризуется "ярлычком" состоящим из надписи и небольшой картинки иконки.
public static void main(String[] args) {
final JFrame jf = new JFrame("scroller pic");
JTabbedPane jtabs = new JTabbedPane(JTabbedPane.LEFT, JTabbedPane.WRAP_TAB_LAYOUT);
// Здесь мы создаем набор закладок. В качестве параметра указывается то,// где будут расположены ярлычки этих закладок.// Возможны варианты ориентации по всем 4-ем сторонам света.// Второй параметр управляет тем, что будет происходить// когда закладки не будут помещаться в одну линию.// В примере используется режим WRAP_TAB_LAYOUT.// Это значит, что закладки будут располагаться в несколько линий.// Возможен также и вариант JTabbedPane.SCROLL_TAB_LAYOUT// в этом случае появятся кнопки прокрутки.jf.getContentPane().add(jtabs, BorderLayout.CENTER);
File fs[] = new File("C:\\tmp").listFiles(
new FileFilter() {
public boolean accept(File pathname) {
return pathname.getName().toLowerCase().endsWith("jpg") ||
pathname.getName().toLowerCase().endsWith("gif");
}});
for (int i = 0; i < fs.length; i++) {
try {
File f = fs[i];
// При добавлении новой закладки следует указать ее название и то какой// Компонент будет к ней привязанImageIcon image = new ImageIcon(f.getCanonicalPath());
jtabs.add(f.getCanonicalPath(),
new JScrollPane(new JLabel(image))
);
// Теперь я создаю иконку привязанную к ярлыку закладки.// Это уменьшенная до 32*32 px основная картинкаjtabs.setIconAt(i, new ImageIcon(image.getImage().getScaledInstance(32, 32, Image.SCALE_AREA_AVERAGING)));
} catch (IOException e) {
e.printStackTrace();
}}jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
jf.setVisible(true);
}});


Элемент управления (контейнер) JsplitPane
Последний компонент широко используемый контейнер - JsplitPane. С его помощью мы создаем разделение области компонента на две зоны, в каждой из которых размещается отдельный компонент. С помощью разделителя Splitter-а мы можем изменять размер области.
// Здесь я указываю ориентацию разделителя. Она будет вертикальнойJSplitPane jsplt1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
// Здесь параметр конструктора - тоже ориентация, но уже горизонтальнаяJSplitPane jsplt2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
// Добавляю левый (верхний) компонентjsplt1.setLeftComponent(new JLabel("<HTML> <B> Left Zone</B>"));
// теперь создаем подкомпоненты для вложенной области JSplitPane// сначала левый, затем правыйjsplt2.setLeftComponent(new JLabel("<HTML> <B> Left - Left Zone</B>"));
jsplt2.setRightComponent(new JLabel("<HTML> <B> Left - Right Zone</B>"));
// можно создавать вложенные JSplitPanejsplt1.setRightComponent(jsplt2);
// и последний шаг – устанавливаем прапорции мест,// которые будут отведены для каждой из частей контейнера// здесь используется дробное число в долях единицы.// однако возможны варианты и с заданием жескткого количества пикселей (метод одноименный, но получает на вход int)jsplt1.setDividerLocation(0.3);
jsplt2.setDividerLocation(0.8);
jf.getContentPane().add(jsplt1, BorderLayout.CENTER);
jsplt1.setOneTouchExpandable(true);


| « Разработка веб-страниц с помощью google gears. Часть 3 | Разработка веб-страниц с помощью google gears. Часть 4 » |