Введение в JavaFX – Модель шахмат - Шахматные фигуры SVG
ОГЛАВЛЕНИЕ
Шахматные фигуры SVG
Шахматные фигуры, которые мы использовали в этой шахматной программе, взяты по адресу openclipart.org. Этот сайт имеет хороший выбор масштабируемой векторной графики (SVG) с открытым исходным кодом, которую вы можете использовать в своих приложениях. Благодаря им мы смогли использовать красивую графику в своем приложении, не являясь художниками. Все были бы впечатлены, если бы JavaFX позволял непосредственно загружать графику SVG. Но это не так. Чтобы использовать графику, нам пришлось преобразовать ее из SVG в графический формат JavaFX. Чтобы преобразовать SVG в графику JavaFX, нужно загрузить JavaFX 1.1 Production Suite по адресу javafx.com. Для преобразования графики SVG в графику JavaFX, нужно использовать программу "SVG to JavaFX Graphics Converter", поставляемую вместе с набором средств. Здесь приводится скриншот шахматных фигур, используемых в программе:
Используемые шахматные фигуры в графике формата SVG
Загрузка и отображение шахматных фигур
Мы обнаружили очередную ошибку в JavaFX, пытаясь загрузить графические изображения шахматных фигур в формате JavaFX. Согласно документации, можно загрузить фигуры с помощью следующего кода:
Этот код должен загружать графические файлы JavaFX, но он не работает
// Загрузка графического файла JavaFX
var pieceNode = FXDLoader.load("{__DIR__}res/WKing.fxz");
// добавление (в) графики в объект Group
var group = Group {
content: [
pieceNode
]
}
// добавление графики к доске
insert group into board.content
Приведенный выше код не работает. __DIR__ является специальной константой, возвращающей URL каталога, в котором содержится текущий файл исходного кода JavaFX. Во всех примерах кода, которые мы видели, все ресурсы (графика, иконки и т.д.) для программ на JavaFX доступны относительно __DIR__. Это работает в большинстве случаев. Например, для загрузки изображения вы можете использовать следующий код:
Загрузка изображения в JavaFX
var myImage = Image { url: "{__DIR__}images/SampleImage.jpg" backgroundLoading: true};
Однако если попытаться загрузить изображение с помощью класса FXDLoader, используя этот метод, произойдет ошибка. Проблема в том, что значение, возвращаемое __DIR__ , является URL. Это означает, что пробелы преобразуются в %20. FXDLoader выдает сообщение об ошибке, говорящее, что файл не найден. Для решения этой проблемы нужно преобразовать 20% обратно в пробелы, как это делается в следующем коде:
Решение проблемы с загрузкой графики в JavaFX
// решение проблемы, преобразование 20% в пробел, чтобы FXDLoader мог загрузить графику
def rootDir = "{__DIR__}".replaceAll("%20", " ");
// загрузка графического файла JavaFX
var pieceNode = FXDLoader.load("{rootDir}res/WKing.fxz");
// добавление графики в объект Group
var group = Group {
content: [
pieceNode
]
}
// добавление графики к доске
insert group into board.content
Мы отправили очередной отчет об ошибке, сообщающий, что FXDLoader нужно обновить, чтобы он мог обрабатывать URL, как в случае с классом Image. В примере кода от Sun рекомендуется использовать __DIR__ для загрузки других ресурсов. Он должен работать таким же образом с графическими объектами JavaFX, используя класс FXDLoader.
Пользовательский курсор мыши в JavaFX
Мы решили загрузить пользовательский курсор мыши. Хотелось, чтобы наша шахматная программа подсвечивала фигуру, над которой находится мышь, и курсор мыши принимал форму открытой руки, показанную на рисунке ниже, и принимал форму закрытой руки, когда на фигуре выполнен щелчок мыши, и она перетаскивается. Также должен подсвечиваться квадрат, на который фигура будет помещена, если отпустить кнопку мыши. Это полезно в случаях, когда пользователь перетаскивает фигуру над углом квадрата. Без подсказки пользовательского интерфейса вы можете не знать, в какой квадрат фигура будет помещена при отпускании кнопки мыши.
Подсвеченные фигуры и пользовательские фигуры при перемещении мыши над фигурой и при перетаскивании фигуры с помощью мыши
JavaFX имеет свой собственный набор установленных курсоров, доступный для использования. Если вы хотите создать ваш собственный пользовательский курсор, вы должны создать новый объект java.awt.Cursor для вашего пользовательского курсора, как показано в следующем коде:
Пользовательский (специализированный) курсор
import java.awt.*;
import java.net.*;
import javax.swing.*;
import javafx.scene.Cursor;
public class CustomCursor extends Cursor {
public-init var imageURL: String;
public-init var cursorName: String;
public override function impl_getAWTCursor(): java.awt.Cursor {
var toolkit = Toolkit.getDefaultToolkit();
var image: Image = toolkit.getImage(new URL(imageURL));
var point: Point = new Point(16, 16);
var cursor: java.awt.Cursor =
toolkit.createCustomCursor(image, point, cursorName);
}
}
Этот код немного сбивает с толку, потому что используются два различных Cursors. Новый класс CustomCursor расширяет класс JavaFX Cursor (javafx.scene.Cursor). Другой класс создает новый объект Java Cursor (java.awt.Cursor). Это два различных класса Cursor. Мы заметили, что замененный нами метод impl_getAWTCursor() не включен в список документации JavaFX 1.1 API. Причиной этого может быть неполноценность документации JavaFX API в настоящий момент (она выглядит совсем не так, как полная документация Java API) или это может быть скрытым API, который нельзя заменять.
Поскольку документация JavaFX API хуже, чем документация Java API, это не было для нас неожиданностью. Java существует намного дольше и является более развитым языком программирования. Однако, есть одна вещь, которая нам очень не понравилась в документации JavaFX API. В документации Java все классы перечислены в формате HTML в одной оконной панели. Так что если мы поищем определенный класс, его легко найти с помощью браузера. В JavaFX, если вы знаете имя класса, который вы ищете, но не знаете, в какой пакет входит этот класс, найти данный класс в документации будет довольно сложно. В документации JavaFX API все классы не перечислены в боковой оконной панели (как в документации Java), однако в боковой оконной панели перечислены все имена пакетов. Вы вынуждены щелкнуть мышкой на имени пакета, чтобы увидеть классы, входящие в этот пакет. Так что если вы хотите найти документацию для класса Cursor и не знаете, что он входит в пакет javafx.scene, этот класс будет сложно найти. Документация может выглядеть красивее, но она не удобная.
Вернемся к загрузке пользовательского курсора. Следующий код загружает пользовательский курсор в шахматную программу:
Загрузка пользовательского курсора
def rootDir = "{__DIR__}".replaceAll("%20", " ");
def grabCursor = CustomCursor {
imageURL: "{rootDir}res/grab.png"
cursorName: "Grab"
}
def grabbingCursor = CustomCursor {
imageURL: "{rootDir}res/grabbing.png"
cursorName: "Grabbing"
}
var currentCursor = Cursor.Default;
// Внутри класса Piece (фигура) создаются пользовательские функции слушателей событий
// мыши для обеспечения возможности изменения курсора
onMouseEntered: function(e: MouseEvent) {
currentCursor = grabCursor;
board.cursor = currentCursor;
}
onMouseExited: function(e: MouseEvent) {
currentCursor = Cursor.Default;
board.cursor = currentCursor;
}
// аналогично для других функций мыши - отпущенный, нажатый, произошел щелчок по кнопке мыши