Я буду использовать здесь несколько примеров для иллюстрации того, как GUI можно определить, а затем использовать Event Driven программирование в графическом интерфейсе.
MyWindowDemo это простая программа, которая определяется как подкласс класса JFrame.
Единственное, что можно найти в теле MyWindowDemo, так это объявление конструктора.
Я покажу вам, что конструктор должен создать, прежде чем углубляться в детали.
Как вы можете увидеть, это окно, похожее на те, которые вы часто видите при запуске окна на компьютере.
Вы видите синюю рамку вокруг окна.
В верхней части окна находится панель заголовка вместе со знакомыми кнопками.
В частности, кнопками, чтобы максимизировать или минимизировать окно.
А также красная кнопка с крестом внутри, что позволит вам закрыть окно.
Итак, используя JFrame, все это может быть создано для вас автоматически, без необходимости писать собственную программу.
Давайте теперь вернемся к конструктору.
В конструкторе метод setTitle обеспечит окну название, которое будет отображаться в панели заголовка окна, как вы можете здесь увидеть.
Метод setSize установит размер окна, в этом случае, это 400 пикселей в ширину и 200 пикселей в высоту.
Таким образом, ширина этого окна в два раза больше его высоты.
Метод setDefaultCloseOperation использует параметр JFrame.EXIT_ON_CLOSE.
Это выглядит немного сложно, но все, что он делает, это просто останавливает программу, когда окно закрывается, когда нажимается крест в верхнем правом углу кнопки.
Метод setVisible сделает окно видимым.
Все эти методы доступны из JFrame, так как MyWindowDemo это подкласс JFrame, и мы можем просто использовать эти методы при создании конкретного объекта.
Откроем сейчас IDEA, чтобы продемонстрировать, как работает эта программа.
Откроем класс MyWindowDemo.
Как вы можете видеть, это программа, которую мы только что описали.
Скомпилируем и запустим программу путем создания экземпляра, и вы сможете увидеть, что окно создается в верхнем левом углу.
Вы можете использовать другие методы, например, setLocation, если вы не хотите поместить окно в углу, но в определенном месте в середине, скажем в позиции 200, 200.
Если вы скомпилируете и запустите программу путем создания экземпляра, теперь вы сможете увидеть, что окно вместо позиции в углу, находится сейчас на позиции 200, 200.
Когда вы закроете окно, как я уже говорил, потому что мы используем EXIT_ON_CLOSE, вы сможете увидеть, что программа также остановилась.
Предыдущий пример просто создает пустое окно.
Чтобы сделать его более интересным, давайте добавим несколько элементов в окно.
Сначала мы создадим JPanel с именем content, чтобы мы могли поместить некоторые графические компоненты в панель.
Когда мы добавляем компоненты на панель, так или иначе мы должны сказать компьютеру, где поместить эти компоненты.
Было бы довольно утомительно определять позиционирование компонентов, один за другим.
К счастью, платформа Java предоставила некоторые макеты по умолчанию так, чтобы компоненты могли быть размещены упорядоченным образом.
Мы можем использовать метод setLayout, чтобы сообщить программе, какой макет используется.
В этом случае, менеджер компоновки будет использовать макет FlowLayout, который просто расставляет компоненты в ряд, масштабируя в их размер по умолчанию.
Если недостаточно свободного места, чтобы разместить все компоненты в текущей строке, менеджер компоновки будет создавать другую строку.
То есть, макет будет размещать компоненты слева направо, а затем сверху вниз.
Есть и другие стратегии компоновки, и вы можете найти их легко в Интернете.
Первый компонент, который мы здесь создаем, это некоторый текст, используя класс JLabel и переменную label.
Здесь мы используем строку “My Panel” для маркировки панели.
Метка затем может быть добавлена к содержанию панели с помощью метода аdd.
Вторым компонентом является кнопка.
Кнопка создается как тип JButton и кнопке дается метка "Click Me".
Опять же, кнопка добавляется к панели content.
Панель содержимого JFrame, в этом случае установлена как панель JPanel, которую мы только что создали, с помощью метода setContentPane.
Это результирующее окно, которое мы увидим, если создадим экземпляр окна.
Откроем IDEA, чтобы посмотреть, как работает программа.
Здесь вы можете видеть, что это то же самое, что мы только что описали.
Скомпилируем и запустим программу.
Создадим экземпляр класса MyWindowDemo2,
И вы можете увидеть, что это окно в основном такое же, как и раньше, за исключением того, что сейчас у нас есть текст My Panel, добавленный к окну, и есть также кнопка, которая называется Click Me.
Но теперь, если вы попытаетесь нажать на эту кнопку, ничего не случится.
Потому что мы не добавили к ней слушателей, как мы обсуждали в предыдущих примерах событийного программирования.
До сих пор, кнопка или что-то еще в окне не взаимодействовали с пользователем, потому что не было слушателя, присоединенного к чему-либо в окне.
Скажем, если мы хотим, чтобы кнопка что-то сделала, когда пользователь нажимает на нее.
При подключении кнопки к событию MouseClick, кнопка будет рассматриваться в качестве источника события.
Мы используем метод addMouseListener, чтобы зарегистрировать этот объект для источника событий кнопки.
Так что можно было бы получать уведомления, когда событие щелчка мыши происходит в кнопке.
Для того чтобы определить, что делать, когда мышь нажата, мы должны реализовать интерфейс MouseListener.
Следует помнить, что интерфейс состоит из набора абстрактных методов, которые еще не были реализованы.
Все методы в интерфейсе должны быть реализованы в классе.
В этом примере, мы сделаем что-то простое, просто проигрывание звукового сигнала, когда мышь нажимает на кнопку.
Таким образом, в реализации mouseClicked, метод beep(), который доступен в классе Toolkit, обеспечивает звуковые сигналы.
И мы ничего не делаем в других методах, включая mousePress, mouseRelease, MouseEnter и mouseExited.
Но они должны быть реализованы, даже если они ничего не делают, в противном случае программа не будет скомпилирована.
Конечно, вы можете выполнить другие какие-либо действия, если вы хотите, в любом из этих методов.
Давайте опробуем эту программу в IDEA.
Создадим экземпляр класса MyWindowDemo3.
И здесь то же самое окно, которое мы уже видели, и вы можете видеть, что здесь реализован метод mouseClicked.
Для других методов, ничто не было реализовано.
Когда вы создаете объект этого класса, как вы можете видеть, это окно выглядит точно так же, как и раньше, но теперь, если вы нажмете на эту кнопку Click Me, вы можете услышать звук.
Но если вы щелкните в любом месте за пределами кнопки, вы не слышите звуковой сигнал.
В программе, которую мы только что видели, это был только один источник событий, то есть, кнопка "Click me".
Этот новый класс MyWindowDemo4 похож на тот, который вы только что видели, но вместо создания кнопки "Click me" в качестве единственного источника событий, давайте еще больше расширим сферу применения программы, таким образом, чтобы JPanel, которую мы создали, с именем content, также использовалась в качестве источника событий.
Поэтому здесь, при добавлении content.addMouseListerner, мы регистрируем content как другой источник событий для событий мыши.
В предыдущем примере, хотя все методы в MouseListener были реализованы, только метод mouseClicked на самом деле делал какую-то работу, то есть, выдавал звуковой сигнал.
Попробуем также реализовать другие методы, чтобы сделать что-то простое.
Метод mouseClicked останется таким же, чтобы издавать звуковой сигнал.
Метод mouseEntered вызывается, когда мышь входит в источник события, и здесь мы вызовем метод setText для объекта label.
Объект label объявляется как JLabel, который может быть использован для отображения какого-либо текста, и здесь мы инициализируем его символьной строкой "My Panel".
В методе mouseEntered setText изменяет метку на новую строку "Entered".
Точно так же, реализуем метод mouseExited, который вызывается, когда мышь выходит из источника, так чтобы изменить метку на строку "Еxited".
Для метода mousePressed, который запускается при нажатии на кнопку мыши, кроме указания, что мышь нажата, реализация будет также определять место, где была нажата мышь, с помощью методов getX и getY для объекта события мыши, который является параметром метода, а затем отобразим информацию в метке.
Метод mouseReleased, который срабатывает, когда пользователь отпускает кнопку мыши, реализован таким же образом, за исключением того, что сообщение указывает, что кнопка мыши была отпущена.
Таким образом с помощью этой программы вы можете наглядно посмотреть различия между вызовами методов mouseClicked, mousePressed и mouseReleased.
Это класс MyWIndowDemo4 что мы только что описали.
Как вы можете видеть, панель контента и кнопка нажми меня, настроены как источники событий.
Пять методов реализованы, как это описано выше, а именно, метод mouseClicked, метод mouseEntered и метод mouseExited, а также mousePressed и mouseReleased.
Создадим экземпляр класса MyWindowDemo4.
Окно, которое здесь отображается, выглядит точно так же, как и раньше.
Сначала метка "Panel label" отображается рядом с кнопкой Click me, когда мышь вне окна.
Помните, что у нас сейчас есть панель как источник событий, которая является белой областью в окне, и кнопка "Click me" как источник событий.
Теперь, когда мышь перемещается внутри окна, метка меняется на "Entered".
Когда мышь перемещается из окна, метка теперь отображается как "Exited".
Давайте перейдем в окно снова, и нажмем кнопку мыши, и отображается сообщение "Pressed at x y".
Отпустим кнопку, и вы сможете увидеть сообщение "Released at".
Пока я испытал четыре метода на панели, а именно, mouseEntered, mouseExited, mousePressed и mouseReleased.
Давайте также протестируем оставшийся метод mouseClicked.
Если я нажимаю на кнопку мыши, можно увидеть, что она нажата, например, в позиции 166 80, и, если вы отпустите ее в той же самой позиции, вы должны также слышать звуковой сигнал.
Так происходит, если мышь нажата, а затем отпущена в том же месте на экране.
В предыдущем демо, мышь генерировала звуковой сигнал только при щелчке мышью на кнопке Click me, а теперь будет реакция на щелчок мыши в любом месте в панели, так как панель также настроена в качестве источника событий.
Давайте переместим мышь в кнопку, и вы можете увидеть, что метка будет изменена на "Entered".
Это потому, что кнопка также настроена в качестве источника событий для одного и того же слушателя мыши.
Но когда мышь перемещается за пределы кнопки, метка отображается по-прежнему, как "Entered" вместо "Exited", потому что мышь вернулась в панель, которая также источник событий.
Давайте переместимся в кнопку еще раз, и ничего не изменилось, потому что вы вошли в область кнопки.
Теперь, если вы щелкните внутри кнопки, не перемещая мышь, вы все еще можете услышать звуковые сигналы, но интересно то, что место, где была нажата кнопка мыши, отличается от того места, где мышь была отпущена.
Несмотря на то, что мышь фактически не перемещается.
Это потому, что расположение кнопки Click me было перенесено, когда отображаемая строка символов имеет разную длину.