#java #graphics #fonts #size
#java #графика #шрифты #размер
Вопрос:
Я загружаю пользовательский шрифт (из ttf-файла) в свой проект и использую deriveFont (float f) для изменения размера. Однако размер фактически не устанавливается (застрял на 1). Вот мой код:
public static void main(String[] args) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
try {
Font mont =
Font.createFont(
Font.TRUETYPE_FONT,
new File(System.getProperty("user.dir") "/data/Montserrat-MediumItalic.ttf"))
.deriveFont(20f);
ge.registerFont(mont);
Arrays.stream(ge.getAllFonts())
.filter(font -> font.getFontName().contains("Mont"))
.forEach(font -> System.out.println(font.getFontName() ", Size: " font.getSize()));
} catch (FontFormatException | IOException e) {
e.printStackTrace();
}
}
вывод:
Montserrat Medium Italic, Size: 1
примечание: замена font.getSize()
на font.getSize2D
prints 1.0
.
Новое: использование decode:
Сейчас я использую это
Font test = Font.decode("Montserrat Medium Italic-ITALIC-20");
(исправлен класс, который не загружается)
Обновление 2:
эта строка: Font mont = Font.createFont(Font.ITALIC, new File(System.getProperty("user.dir") "/data/Montserrat-MediumItalic.ttf"));
выдает
IllegalArgumentException: font format not recognized
Комментарии:
1.
ge.registerFont(mont)
Возвращаетсяtrue
? Получаете ли вы какие-либо выходные данные, если попытаетесь перечислить шрифт перед его регистрацией?2. Что
mont.getSize()
возвращает?3. @JohnBollinger это (часть) javadocs для getSize():
Returns the point size of this <code>Font</code>, rounded to an integer.
4. Кроме того, register возвращает значение true. Помещение выходных данных перед регистром приводит к отсутствию выходных данных вообще.
5. Я могу прочитать документацию
Font.getSize()
сам, спасибо. И сделал. Я спросил о результате конкретного выражения, включающего вызов этого метода.
Ответ №1:
Однако размер фактически не устанавливается (застрял на 1).
Это кажется маловероятным. Я попросил прямого подтверждения в комментарии к вопросу («Что mont.getSize()
возвращает?» — ой, какая смущающе плохая грамматика), но пока вы не ответили. Я достаточно уверен, что если вы проверите, вы увидите, что mont.getSize()
размер соответствует запрошенному вами размеру.
Альтернативное объяснение вашего наблюдаемого поведения легко доступно. Вы используете GraphicsEnvironment.getAllFonts()
для составления отчета о зарегистрированных шрифтах, но, согласно его документации, этот метод
Возвращает массив, содержащий экземпляр размера в одну точку всех шрифтов, доступных в этой графической среде.
(Выделено мной.)
Другой ответ и особенно комментарии к нему предполагают, что Font
объекты, возвращаемые GraphicsEnvironment.getAllFonts()
, могут отличаться и другими способами от соответствующих Font
экземпляров, переданных GraphicsEnvironment.registerFont()
. Хотя, насколько я вижу, такие изменения не документированы, они согласуются с предполагаемым использованием Font
объектов, полученных из GE, как описано в getAllFonts()
документах:
Типичным использованием было бы разрешить пользователю выбирать определенный шрифт. Затем приложение может изменять размер шрифта и устанавливать различные атрибуты шрифта, вызывая метод deriveFont в выбранном экземпляре.
Они продолжают говорить, что
Если шрифт в этой графической среде имеет несколько программируемых вариантов, в массив возвращается только один экземпляр этого шрифта, а другие варианты должны быть получены приложением.
Я не уверен, что «несколько программируемых вариантов» означают атрибуты, которые могут быть изменены при выводе одного Font
объекта из другого (ибо тогда у какого шрифта не было бы программируемых вариантов?), Но ясно, что getAllFonts()
это не механизм для считывания точных Font
объектов, ранее представленных GraphicsEnvironment.registerFont()
. Эти объекты могут даже не сохраняться как таковые.
С другой стороны, вы, возможно, можете быть спокойны, что не несете ответственности за предварительную регистрацию всех различных вариантов шрифта, которые вам могут понадобиться.
Комментарии:
1. Спасибо за подробный ответ. Я печатаю
mont.getSize()
сразу послеmont.deriveFont(20f)
, и он печатает «1»2.@PhaseRush, если
getSize()
методFont
экземпляра, полученный с помощью вызоваderiveFont(20f)
, возвращает 1, значит, что-то сильно не так. Однако я не могу не заметить, что ваш комментарий описывает тестирование чего-то другого.mont.deriveFont(20f)
создает и возвращает новыйFont
экземпляр; он не изменяет тот, на котором он вызывается. Таким образом,mont.getSize()
после этого должно быть возвращено то же значение, что и непосредственно перед этим.3. @PhaseRush Вы не печатаете
mont.getSize()
в коде в вашем вопросе.4. хорошо, спасибо, я исправил свою проблему, выполнив 2 вещи. 1. обновлен размер, изменив шрифт mont = bunchOfFuncs(); mont.derive(20f); на шрифт mon = sameBunchOfFuncs().derive() 2. исправлен недопустимый аргумент, изменив имя файла ttf на «Montserraft.ttf». Теперь, когда мне нужен шрифт, я использую Font.decode(Montserrat-PLAIN-20), и это работает
Ответ №2:
Я думаю, я знаю, в чем проблема. Когда вы вызываете ge.registerFont(mont)
, он делает именно это, он регистрирует базовый шрифт, без изменений в объекте font. deriveFont()
Функция изменяет только состояние текущего объекта font, но не может изменить фактический шрифт. Когда вы регистрируете шрифт, он регистрируется с размером 1. Если вы напечатаете размер всех других шрифтов, вы обнаружите, что они также имеют значение по умолчанию 1. Я не думаю, что вы можете зарегистрировать шрифт с пользовательским размером по умолчанию или переопределить размер по умолчанию Font.getFont()
. Когда вы получаете шрифт с помощью Font.getFont()
, он всегда будет иметь размер по умолчанию 12 (из спецификации).
Если вам нужно, чтобы шрифт был специально отформатирован, я бы предложил создать статическую переменную класса:
Font MontMediumItalic_20;
Затем загрузите шрифт один раз, либо в загрузчике ресурсов, либо в конструкторе, и примените к нему все изменения.
В качестве альтернативы вы также можете использовать Font.decode()
Пожалуйста, дайте мне знать, если вам нужна какая-либо помощь.
Комментарии:
1. Что за «базовый шрифт»?
Font
Класс имеет концепцию получения одного шрифта из другого, но не имеет представления об одном, лежащем в основе другого, и, конечно, он не предоставляет средств для получения такого базового шрифта. Более того,GraphicsEnvironment.registerFont()
документы, которые он может использовать для регистрации только созданных шрифтов, таких как те, которые получены с помощьюFont.deriveFont()
, что не имело бы смысла, если бы то, что он регистрирует, действительно было каким-то родовым, оригинальным, базовым шрифтом.2. С другой стороны, вполне вероятно, что
GraphicsEnvironment
будет регистрировать шрифты стандартного размера, например, 1 точка, хотя в документах не приводится никаких оснований ожидать такого поведения.3. @Jhon под базовым шрифтом don’t я имел в виду базовый шрифт, загруженный непосредственно из файла .tff, без каких-либо изменений, за исключением нормализации размера шрифта до 1.
4. Опять же,
Font
класс не имеет представления о такой вещи, и это, похоже, не согласуется с требованием, чтобыFont
зарегистрированные вGraphicsEnvironment
быть созданными .5. @John Я согласен, что это
deriveFont
противоречит интуиции, но нет смысла регистрировать шрифт нестандартного размера, потому что согласно спецификации любой вызовFont.decode
илиFont.getFont
вернет либо указанный размер, либо стандартный размер 12.