#java #swing #user-interface #controller #event-listener
#java #swing #пользовательский интерфейс #контроллер #прослушиватель событий
Вопрос:
Я работаю над изучением использования событий для изменения параметров в графическом интерфейсе. В настоящее время я использую события контроллера, переданные из другого метода, и я думаю, что мне может не хватать некоторой ключевой информации о том, как переменные работают в этих методах. Вот мой исходный код (в настоящее время это внутренний класс).
class MyDrawPanel extends JPanel implements ControllerEventListener{
static boolean isWriting = false;
public void controlChange(ShortMessage event) {
isWriting = true;
repaint();
}
public void paintComponent(Graphics g){
if (isWriting){
int red = (int) (Math.random() * 250);
int green = (int) (Math.random() * 250);
int blue = (int) (Math.random() * 250);
g.setColor(new Color(red, green, blue));
int xpos = (int) (Math.random() * 190 10);
int ypos = (int) (Math.random() * 190 10);
int width = (int) (Math.random() * 50 10);
int height = (int) (Math.random() * 50 10);
g.fillRect(xpos, ypos, width, height);
//isWriting = false;
}
То, что я пытаюсь сделать, это рисовать новый прямоугольник каждый раз, когда слушатель получает событие, но я могу добиться только одного из двух. Если я попытаюсь вернуть «isWriting» обратно в false в конце оператора if, оператор if, похоже, постоянно оценивает значение false и не рисует никаких прямоугольников. Если я закомментирую этот код, чтобы установить isWriting обратно в false, рисование работает для одного прямоугольника, но нет ничего, чтобы изменить переменную обратно и вызвать метод repaint, поэтому я получаю только один прямоугольник.
Я знаю, что мои события попадают к слушателю, поскольку я использовал sout для увеличения количества каждый раз, когда он получает событие, поэтому кажется, что проблема связана с состоянием переменной isWriting . Спасибо за помощь!
Комментарии:
1. Никогда не меняйте состояние своего класса из метода рисования. Я не совсем понимаю, что именно вы пытаетесь здесь сделать, какое поведение вы пытаетесь вызвать. Можете ли вы уточнить?
2. Вы хотите, чтобы прямоугольник отображался только в течение определенного периода времени? Если это так, используйте таймер переключения. Или когда пользователь подтверждает получение сообщения? Затем используйте другой прослушиватель. Еще раз, пожалуйста, уточните.
Ответ №1:
Вы хотите избежать изменения состояния вашего класса из метода рисования. Это не тот метод, который вы полностью контролируете, и поэтому это может привести к неожиданным и трудным для отладки побочным эффектам.
Я не уверен на 100% в том, что вы пытаетесь сделать, но если вы пытаетесь рисовать новый прямоугольник каждый раз при получении сообщения, и вы хотите, чтобы этот прямоугольник сохранялся (и таким образом, возможно, отображал несколько прямоугольников), то,
- Либо нарисуйте прямоугольники на BufferedImage, а затем отобразите BufferedImage в методе paintComponent вашей JPanel, либо
- Создайте ArrayList объекта, который содержит как прямоугольник, так и цвет, а затем с каждым событием создавайте новый из этих объектов, добавляйте его в список и вызывайте
repaint()
. Затем в paintComponent выполните итерацию по списку, рисуя прямоугольники. - Не забывайте, что вы всегда должны вызывать метод paintComponent super в своем переопределении.
В противном случае, если вы хотите, чтобы прямоугольник отображался только в течение определенного периода времени, используйте таймер переключения. Или, если, когда пользователь подтверждает получение сообщения, используйте другой прослушиватель. Еще раз, пожалуйста, уточните свой вопрос.
Руководства:
- Урок: Выполнение пользовательского рисования: вводный урок по Swing graphics
- Рисование в AWT и Swing: расширенное руководство по графике Swing
Комментарии:
1. Вы попали в точку с тем, что я пытаюсь сделать, оставляя каждый прямоугольник. Я все еще супер новичок, когда дело доходит до всех вещей Java (и, честно говоря, довольно новичок в программировании в целом), поэтому мне потребуется некоторое время, чтобы попытаться собрать что-то с вашими предложениями (я изучал это около часа и не сделал многоиз прогресса, изображения буфера для меня совершенно новые, а списки массивов — это все еще то, что я изучаю), поэтому я не смогу сказать вам, работало ли это в течение нескольких дней.
2. Один вопрос, который у меня есть, находится в вашем 3-м пуле, из какого переопределенного метода я должен вызывать метод перерисовки? На самом деле я не уверен, какой метод я переопределяю.
3. @bailey2092: Вы бы вызвали метод super в переопределении — вы переопределяете paintComponent . Пожалуйста, ознакомьтесь с первым руководством, ссылку на которое я только что опубликовал в ответе выше. Во втором руководстве более подробно, если вам интересно.
4. Да, я работал над этим две недели и ничего не добился. Мой код сейчас в беспорядке, потому что я понятия не имею, куда что-либо в swing должно идти, и понятия не имею, куда должны идти слушатели. Я не могу понять, как добавить объект rectangle в arraylist и включить цвет и размеры. Я не могу понять, что такое поток отправки событий или что вообще должен делать runnable, потому что в моем коде он выделен серым цветом, как будто он не используется. Я не знаю, когда перерисовывать или как вызвать перерисовку из другого метода.
5. @bailey2092: исправляйте по одной проблеме за раз и часто делайте это изолированно от остальной части вашей программы, в небольших тестовых программах, включая небольшую программу для решения вашей проблемы с прослушивателем, небольшую программу для решения вашей проблемы с рисованием и т. Д.