[java] обработка сообщений

shtreg

Разрабатываю шахматную программу.
Есть функция, ожидающая от пользователя ход (фигура и целевая клетка она должна вернуть значение только после того, как пользователь этот ход обозначит. Для этого она садится в цикл, ожидающий пока обработчик события от кнопки поменяет некую глобальную переменную. Понятно, что все криво, но переделывать пока времени нет, занимаюсь логикой игры.
Но в этом цикле надо как-то попросить "джаву" эти события обрабатывать. В дельфи было Application.ProcessMessages, нужен максимально близкий аналог этого метода. Нужно именно это, предложения все переделать по человечески не нужны, сам понимаю, это потом.

Andbar

ход компа может занимать много времени, так что, по моему, лучше сразу реализовывать его в отдельном потоке, чем писать костыль, коль всё равно приходится узнавать на форуме, как писать костыль.

katrin2201

А что у тебя за среда? ОСь, ГУИ там, етц?
Рожать треды не вариант?

kill-still

В Яве "событий" как таковых нет. Если что-то где-то происходит, то объект, вызвавший "событие" пробегается по своим слушателям, и вызывает по интерфейсу ActionListener метод actionPerformed. Из объектов не являющихся слушателями узнать о событии невозможно (насколько я знаю). Так что для того чтобы обработать "событие", тебе надо зарегистрировать слушателя (addActionListener) и т.д.

SPARTAK3959

Попробуй
EventDispatchThread)Thread.currentThread.pumpEvents(new Conditional {
public boolean evaluate {
return globalVar;//вернуть false, когда нужно прервать цикл.
}
});

Только знай, что тот, кому придется это читать тебя точно захочет убить.

Werdna

Разрабатываю шахматную программу.
Есть функция, ожидающая от пользователя ход (фигура и целевая клетка она должна вернуть значение только после того, как пользователь этот ход обозначит. Для этого она садится в цикл, ожидающий пока обработчик события от кнопки поменяет некую глобальную переменную. Понятно, что все криво, но переделывать пока времени нет, занимаюсь логикой игры.
Всегда удивляло, зачем делать криво? Возьми GNU Chess, и там есть АПИ, разрабатывай сколько влезет логику игры.
Нет, блин, делают своё убожество. :(

Gaishnik

Тебе нужны континуации. В Java их нет.

pitrik2

эта твоя функция в каком потоке работает?
у тебя ваще Swing или что?
если свинг и функция эта в свинговском потоке вызывается то как уже сказали континуэйшенов нет
если не отдельно потоке, то поток этот можно просто усыпить типа навсегда, и тогда когда пользователь сделает ход то обработчик хода пошлет notify и разбудит этот поток, т.е. все время переменную проверять не надо будет

stm6695895

ээ, ну например можно так (вообще, тут одна игровая библиотека используется, ну, впрочем, у тебя шахматы :) )
Пишешь класс:

import java.util.LinkedList;
import java.util.ListIterator;

public class EventManager
{
private static EventManager instance;
public static EventManager instance
{
if (instance == null)
instance = new EventManager;
return instance;
}

private LinkedList<KeyListener> listeners = new LinkedList<KeyListener>

public void addListener(int key, KeyListener listener)
{
listener.setMonitored(key);
listeners.add(listener);
}

public void checkEvents
{
for(ListIterator<KeyListener> li = listeners.listIterator; li.hasNext;)
{
li.next.check;
}
}
}

И еще один класс:
  
import org.lwjgl.input.Keyboard;

public class KeyListener
{
protected int monitored;
protected boolean wasPressed;

public void setMonitored(int key)
{
monitored = key;
}

public void check
{
if(Keyboard.isKeyDown(monitored
{
wasPressed = true;
onKeyDown;
}
else if (wasPressed)
{
onKeyUp;
wasPressed = false;
}
}

public void onKeyDown{};
public void keyPressed{};
public void onKeyUp{};
}

В главном классе своей программы, в конструкторе, например, пишешь что-нибудь типа:
  
EventManager.instance.addListener(Keyboard.KEY_SPACE, new KeyListener
{
public void onKeyDown
{
//здесь твой код, меняешь свою глобальную переменную
}
});

Ну и потом, в цикле той своей функции, а лучше в каком-нибудь главном цикле программы или и правда в отдельном потоке вызываешь метод

EventManager.instance.checkEvents;

который и будет проверять все прослушиваемые клавиши. Как-то так. Аналогично на прослушку можно и мышку посадить, если надо.
Для работы такой схемы нужно подключить библиотеку jinput.jar (В ней класс Keyboard взять можно на сайте http://lwjgl.org вместе со всем остальным. В общем, вот такие костыли, как вариант :)

pitrik2

ты используешь дженерики но не используешь foreach
почему?

stm6695895

ты используешь дженерики но не используешь foreach
почему?
ээ, ты имеешь в виду, почему я пишу
  
for(ListIterator<KeyListener> li = listeners.listIterator; li.hasNext;)

?
да просто, привык так. И вроде бы я где-то читал, что это конструкция работает быстрее, чем foreach. хз, впрочем, не проверял)

pitrik2

да просто, привык так. И вроде бы я где-то читал, что это конструкция работает быстрее, чем foreach. хз, впрочем, не проверял)
дурачкая привычка имхо
ну просто дженерики многие ругают это понять можно, но не использовть foreach это как-то странно
по поводу быстрее
на бред конечно похоже, чуваки в сане не настоко же тупые
но даже если и протупили с какимнить очередным jvm апдейтом это починяется, т.е. полюбому на такое низзя закладываться

pitrik2

нет конечно
токо причем тут это?

stm6695895

ну просто дженерики многие ругают это понять можно
о, а за что ругают дженерики?
все-таки то что в foreach элементы не удаляются, не очень-то удобно, по моему

marat777

и ещё instance а не getInstance

pitrik2

эээ
это уже придирки к стилю
он и скобки на другой строке открывающиеся ставит
к стилю придираться бессмысленно, каждый пишет или как ему показалось правильным или как его заставили придурки по команде

marat777

это не придирка, это выглядит так же странно в контексте, как неиспользование foreach, как некий артефакт
другие-то функции оформлены с is и т. п.
расстановка скобок же единообразна

pitrik2

это не придирка, это выглядит так же странно в контексте, как неиспользование foreach, как некий артефакт
другие-то функции оформлены с is и т. п.
нет ты не прав
оформлены геттеры/сеттеры
instance - это синглтон, он не обязан быть оформлен как геттер
я и правда у многих в коде такое встречал

asvsergey

о, а за что ругают дженерики?

За приведение к базовому типу. Так называемое "стирание"
Оставить комментарий
Имя или ник:
Комментарий: