Повторяющиеся изменения элементов управления в графическом интерфейсе

#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 в своем переопределении.

В противном случае, если вы хотите, чтобы прямоугольник отображался только в течение определенного периода времени, используйте таймер переключения. Или, если, когда пользователь подтверждает получение сообщения, используйте другой прослушиватель. Еще раз, пожалуйста, уточните свой вопрос.

Руководства:

Комментарии:

1. Вы попали в точку с тем, что я пытаюсь сделать, оставляя каждый прямоугольник. Я все еще супер новичок, когда дело доходит до всех вещей Java (и, честно говоря, довольно новичок в программировании в целом), поэтому мне потребуется некоторое время, чтобы попытаться собрать что-то с вашими предложениями (я изучал это около часа и не сделал многоиз прогресса, изображения буфера для меня совершенно новые, а списки массивов — это все еще то, что я изучаю), поэтому я не смогу сказать вам, работало ли это в течение нескольких дней.

2. Один вопрос, который у меня есть, находится в вашем 3-м пуле, из какого переопределенного метода я должен вызывать метод перерисовки? На самом деле я не уверен, какой метод я переопределяю.

3. @bailey2092: Вы бы вызвали метод super в переопределении — вы переопределяете paintComponent . Пожалуйста, ознакомьтесь с первым руководством, ссылку на которое я только что опубликовал в ответе выше. Во втором руководстве более подробно, если вам интересно.

4. Да, я работал над этим две недели и ничего не добился. Мой код сейчас в беспорядке, потому что я понятия не имею, куда что-либо в swing должно идти, и понятия не имею, куда должны идти слушатели. Я не могу понять, как добавить объект rectangle в arraylist и включить цвет и размеры. Я не могу понять, что такое поток отправки событий или что вообще должен делать runnable, потому что в моем коде он выделен серым цветом, как будто он не используется. Я не знаю, когда перерисовывать или как вызвать перерисовку из другого метода.

5. @bailey2092: исправляйте по одной проблеме за раз и часто делайте это изолированно от остальной части вашей программы, в небольших тестовых программах, включая небольшую программу для решения вашей проблемы с прослушивателем, небольшую программу для решения вашей проблемы с рисованием и т. Д.