Класс FontMetrics
Класс FontMetrics является абстрактным, поэтому нельзя воспользоваться его конструктором. Для получения объекта класса FontMetrics, содержащего набор метрических характеристик шрифта f, надо обратиться к методу getFontMetrics (f) класса Graphics или класса Component.
Подробно с характеристиками компьютерных шрифтов можно познакомиться по книге.
Класс FontMetri.cs позволяет узнать ширину отдельного символа ch в пикселах методом charwidth(ch), общую ширину всех символов массива или под-массива символов или байтов методами getchars() и getBytes(), ширину целой строки str в пикселах методом stringwidth(str).
Несколько методов возвращают в пикселах вертикальные размеры шрифта.
Интерлиньяж (leading) — расстояние между нижней точкой свисающих элементов таких букв, как р, у и верхней точкой выступающих элементов таких букв, как б, и, в следующей строке — возвращает метод getLeading ().
Среднее расстояние от базовой линии шрифта до верхней точки прописных букв и выступающих элементов той же строки (ascent) возвращает метод getAscent (}, а максимальное — метод getMaxAscent ().
Среднее расстояние свисающих элементов от базовой линии той же строки (descent) возвращает метод getDescent (), а максимальное — метод getMaxDescent().
Наконец, высоту шрифта (height) — сумму ascent + descent + leading — возвращает метод getHeight (). Высота шрифта равна расстоянию между базовыми линиями соседних строк.
Эти элементы показаны на рис. 9.1.
Рис. 9.1. Элементы шрифта
Дополнительные характеристики шрифта можно определить методами класса LineMetrics из пакета java.awt.font. Объект этого класса можно получить несколькими методами getLineMetrics () класса FontMetrics.
Листинг 9.2 показывает применение графических примитивов и шрифтов, а рис. 9.2 — результат выполнения программы из этого листинга.
Листинг 9.2. Использование графических примитивов и шрифтов
import java.awt.*;
import j ava.awt.event.*;
class GraphTest extends Frame{
GraphTest(String s) {
super(s);
setBounds(0, 0, 500, 300);
setVisible(true);
}
public void paint(Graphics g){
Dimension d = getSize();
int dx = d.width / 20, dy - d.height / 20;
g.drawRect(dx, dy + 20,
d.width - 2 * dx, d.height - 2 * dy - 20);
g.drawRoundRect(2 * dx, 2 * dy + 20,
d.width - 4 * dx, d.height -4 * dy - 20, dx, dy);
g.fillArctd.width / 2 - dx, d.height - 2 * dy + 1,
2 * dx, dy - 1, 0, 360);
g.drawArctd.width / 2 - 3 * dx, d.height - 3 * dy / 2 - 5,
dx, dy / 2, 0, 360);
g.drawArctd.width / 2 + 2 * dx, d.height - 3 * dy / 2 - 5,
dx, dy / 2, 0, 360);
Font fl = new Font("Serif", Font.BOLD(Font.ITALIC, 2 * dy);
Font f2 = new Font ("Serif", Font.BOLD, 5 * dy / 2);
FontMetrics fml = getFontMetrics(fl);
FontMetrics fm2 = getFontMetrics(f2);
String s1 = "Всякая последняя ошибка";
String s2 =« "является предпоследней.";
String s3 = "Закон отладки";
int firstLine = d.height / 3;
int nextLine = fml.getHeight();
int secondLine = firstLine + nextLine / 2;
g.setFont(f2);
g.drawstring(s3, (d.width-fm2.stringWidth(s3)) / 2, firstLine);
g.drawLine(d.width / 4, secondLine - 2,
3 * d.width / 4, secondLine - 2);
g.drawLine(d.width / 4, secondLine — 1,
3 * d.width / 4, secondLine - 1);
g.drawLine(d.width / 4, secondLine,
3 * d.width / 4, secondLine);
g.setFont(fl);
g.drawstring(s1, (d.width - fml.stringWidth(si)) 12,
firstLine + 2 * nextLine);
g.drawString(s2, (d.width - fml.stringWidth(s2)) / 2,
firstLine + 3 * nextLine);
}
public static void main(String[] args){
GraphTest f = new GraphTest(" Пример рисования");
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent ev){
System.exit(0);
}
});
}
}
В листинге 9.2 использован простой класс Dimension, главная задача которого — хранить ширину и высоту прямоугольного объекта в своих полях width и height. Метод getsize () класса component возвращает размеры компонента в виде объекта класса Dimension. В листинге 9.2 размеры компонента f типа GrapMest установлены в конструкторе методом setBounds() равными 500x300 пикселов.
Еще одна особенность листинга 9.2 — для вычерчивания толстой линии, отделяющей заголовок от текста, пришлось провести три параллельные прямые на расстоянии один пиксел друг от друга.
Как вы увидели из обзора класса Graphics и сопутствующих ему классов, средства рисования и вывода текста в этом классе весьма ограничены. Линии можно проводить только сплошные и только толщиной в один пиксел, текст выводится только горизонтально и слева направо, не учитываются особенности устройства вывода, например, разрешение экрана.
Эти ограничения можно обойти разными хитростями: чертить несколько параллельных линий, прижатых друг к другу, как в листинге 9.2, или узкий заполненный прямоугольник, выводить текст по одной букве, получить разрешение экрана методом getScreenSize() класса Java.awt.Toolkit и использовать его в дальнейшем. Но все это затрудняет программирование, лишает его стройности и естественности, нарушает принцип KISS.
В Java 2 класс Graphics, в рамках системы Java 2D, значительно расширен классом Graphics2D.
Рис. 9.2. Пример использования класса Graphics