В данной статье я рассмотрю один из вариантов реализации такого элемента пользовательского интерфейса как кнопки.
Данный класс будет первым среди элементов пользовательского интерфейса которые необходимы для нормального приложения, поэтому я создал абстрактный класс GUIElement описывающий их общие параметры.
public Point getPosition() { return new Point(x,y); }
public GUIElement getParent() { return (GUIElement)parent; }
public void setParent(Object parent) { this.parent = parent; }
public void Add(GUIElement element) { element.setParent(this); childrens.add(element); }
public abstract void evaluteInput(InputMap inputMap);
public abstract void Action();
public abstract void Draw(FrameBuffer buffer); }
В классе описаны параметры положения объекта, его размеры, информация о том является ли он частью другого объекта, отображается ли он, действие по клику на него, обработка ввода, функция вывода его на экран и т.д. Теперь рассмотрим непосредственно класс GUIButton
Код
public class GUIButton extends GUIElement{
//текстура состояния покоя private Texture tex; //текстура состояния выбора private Texture texSel;
private String text; private GLFont font; private Color color; /** * состояние кнопки * 0 не выбрана и не нажата, 1 выбрана , 2 нажата */ private int Status=0;
public GUIButton(int x,int y, int heigth,int width,Texture tex,Texture texSel) { super(x,y,heigth,width); this.tex = tex; this.texSel = texSel; setVisible(true); color = Color.BLACK; }
@Override public void Draw(FrameBuffer buffer) { if (!getVisible()) { return; }
int text_x = 0; int text_y = 0;
int parent_x=0; int parent_y=0;
//получение координат родительского элемента if (getParent()!=null) { parent_x=getParent().x; parent_y=getParent().y; } //расчет координат надписи if (font!=null) { Dimension d = font.getStringBounds(text).getSize(); text_x=x+(width-d.width)/2 + parent_x; text_y=y+heigth-d.height + parent_y; }
switch(Status) { case 0: { buffer.blit(tex, parent_x+0, parent_y+0, x, y, width, heigth, true); break; } case 1: { buffer.blit(texSel, parent_x+0, parent_y+0, x, y, width, heigth, true); break; } case 2: { buffer.blit(texSel, parent_x+0, parent_y+0, x, y+2, width, heigth, true); text_y+=2; break; } } //отрисовка надписи если она есть if (font!=null) { font.blitString(buffer, text, text_x, text_y, 1, color); } }
@Override public void evaluteInput(InputMap inputMap) { if(getVisible()) { int xpos = inputMap.mouse_x; int ypos = inputMap.mouse_y;
if((xpos>=x)&&(xpos<=x+width)&&(ypos>=y)&&(ypos<=y+heigth)) { Status=1; if (inputMap.mouse_leftbutton_down) { Status = 2; Action(); } } else { Status = 0; } } }
@Override public void Action() {}
public void setFont(GLFont font) { this.font = font; }
public void setText(String text) { this.text = text; }
public void setTextColor(Color color) { this.color = color; }
public Color getTextColor() { return color; } }
В классе определены текстуры для отображения разных состояний кнопки в зависимости от положения и статуса кнопок мыши. Также реализована поддержка надписи на кнопке при помощи GLFont, надпись располагается строго по центру. При отрисовки кнопки учитывается координаты родительского элемента если он есть. Что позволит в будущем располагать ее на других элементах пользовательского интерфейса. Стоит обратить внимание на процесс создание кнопки, в данном примере вместе с созданием кнопки мы переопределяем метод Action что позволяет задать ей необходимый функционал( в данном примере выход из приложения).
После создания кнопки она добавляется в менеджер управления графическим интерфейсом GUIManager , этот класс представляет из себя контейнер в котором находятся все элементы графического интерфейса. GUIManager проверяет состояние устройств ввода при помощи вызова функции evaluteInput(InputMap inputMap), а также отображает все элементы добавленные в менеджер вызовом функции Draw(FrameBuffer buffer). Вместо использование подобного класса можно было использовать модель обработки событий JAVA AWT, но я решил ее не использовать т.к. считаю, что использование GUIManager удобней. Возможно в будущем я подойду к тому, чтобы воспользоватся моделью обработки JAVA AWT. Код примера находится Доступно только для пользователей.