Как установить фокус на JTextField?
Я заставляю свою игру работать без мыши, поэтому использование указателя не является выбором. Меню High Score покажет, когда игрок проиграет.
как его сфокусировать?
9 ответов
если вы хотите JTextField чтобы быть сосредоточенным, когда ваш GUI появляется, Вы можете использовать это:
если есть только один Контейнер Верхнего Уровня тогда последние строки в конструкторе GUI будут, например,
Если страница содержит несколько элементов и хочет установить последовательность вкладок и фокус, я предложу использовать FocusTraversalPolicy.
grabFocus () не будет работать, если вы используете FocusTraversalPolicy.
в моем случае ничего выше не работало, пока я не вызвал requestFocus ()после Мой конструктор вернулся.
MyPanel.initFocus () будет иметь:
этот код курсора мыши «jtextfield» «Jcombobox» расположение сфокусировано
Он не работал для меня, когда пытался использовать:
просто перейти к полю на java.ОУ.робот С помощью клавиши «Tab». Например:
если вы должны нажать несколько раз на «Tab», чтобы получить свой компонент, вы можете использовать следующий метод:
если ваше местоположение компонента динамическое, вы можете запустить цикл while без ограничений, но добавьте некоторый слушатель фокуса на компоненте, чтобы остановить цикл, как только он прибыл к нему.
пока yourTextField.requestFocus() Это решение, это не лучшее, так как в официальной документации Java это обескураживает как метод requestFocus() зависит от платформы.
в документации сказано, что:
обратите внимание, что использование этого метода не рекомендуется, потому что его поведение зависит от платформы. Вместо этого мы рекомендуем использовать requestFocusInWindow().
How to Use the Focus Subsystem
Many components even those primarily operated with the mouse, such as buttons can be operated with the keyboard. For a key press to affect a component, the component must have the keyboard focus.
From the user’s point of view, the component with the keyboard focus is generally prominent with a dotted or black border, for example. The window containing the component is also more prominent than other windows onscreen. These visual cues let the user know to which component any typing will relate. Only one component at a time in the window system can have the keyboard focus.
Exactly how a window gains the focus depends on the windowing system. There is no foolproof way, across all platforms, to ensure that a window gains the focus. On some operating systems, such as Microsoft Windows, the front window usually becomes the focused window. In these cases, the Window.toFront method moves the window to the front, thereby giving it the focus. However, on other operating systems, such as Solaris™ Operating System, the window manager may choose the focused window based on cursor position, and in these cases the behavior of the Window.toFront method is different.
A component generally gains the focus when the user clicks it, or when the user tabs between components, or otherwise interacts with a component. A component can also be given the focus programmatically, such as when its containing frame or dialog-box is made visible. This code snippet shows how to give a particular component the focus every time the window gains the focus:
If you want to ensure that a particular component gains the focus the first time a window is activated, you can call the requestFocusInWindow method on the component after the component has been realized, but before the frame is displayed. The following sample code shows how this operation can be done:
Alternatively, you can apply a custom FocusTraversalPolicy to the frame and call the getDefaultComponent method to determine which component will gain the focus.
The rest of this section covers the following topics:
Introduction to the Focus Subsystem
The focus subsystem is designed to do the right thing as invisibly as possible. In most cases it behaves in a reasonable manner, and if it does not you can tweak its behavior in various ways. Some common scenarios might include:
The FocusConceptsDemo example illustrates a few concepts.
The KeyboardFocusManager is a critical element of the focus subsystem. It manages state and initiates changes. The keyboard manager tracks the focus owner — the component that receives typing from the keyboard. The focused window is the window that contains the focus owner.
A focus traversal policy determines the order in which a group of components are navigated. Swing provides the LayoutFocusTraversalPolicy class, which decides the order of navigation based on layout manager-dependent factors, such as size, location, and orientation of components. Within a focus cycle, components can be navigated in a forward or backward direction. In a hierarchy of focus cycle roots, upwards traversal takes the focus out of the current cycle into the parent cycle.
In most Look and Feel models, components are navigated using the Tab and Shift-Tab keys. These keys are the default focus traversal keys and can be changed programmatically. For example, you can add Enter as a forward focus traversal key with the following four lines of code:
You have just received a brief introduction to the focus architecture. If you want more details, see the specification for the Focus Subsystem.
Validating Input
A common requirement of GUI design is a component that restricts the user’s input — for example, a text field that allows only numeric input in decimal format (money, for example) or a text field that allows only 5 digits for a zip code. An easy-to-use formatted text field component that allows input to be restricted to a variety of localizable formats. You can also specify a custom formatter for the text field, which can perform special checking such as determining whether values are not only formatted correctly, but also reasonable.
A component’s input verifier is consulted whenever the component is about to lose the focus. If the component’s value is not acceptable, the input verifier can take appropriate action, such as refusing to yield the focus on the component or replacing the user’s input with the last valid value and then allowing the focus to transfer to the next component. However, InputVerifier is not called when the focus is transferred to another top-level component.
The following two examples show mortgage calculators. One uses formatted text fields and the other uses input verification with standard text fields.
Note that the verify method is implemented to detect invalid values but does nothing else. The verify method exists only to determine whether the input is valid — it should never bring up a dialog-box or cause any other side effects. The shouldYieldFocus method calls verify and, if a values is invalid, sets it to the minimum or maximum value. The shouldYieldFocus method is allowed to cause side effects, in this case, it always formats the text field and may also change its value. In our example, the shouldYieldFocus method always returns true so that the transfer of the focus is never actually prevented. This is just one way verification can be implemented. Find another version of this demo called InputVerificationDialogDemo that puts up a dialog-box when user input is invalid and requires the user to enter a legal value.
The input verifier is installed using the setInputVerifier method of the JComponent class. For example, the InputVerificationDemo has the following code:
Making a Custom Component Focusable
For a component to gain the focus, it must satisfy three requirements: it must be visible, enabled, and focusable. An input map may also be given. For more information about input map, read How to Use Key Bindings.
The call to the setFocusable(true) method makes the component focusable. If you explicitly give your component key bindings in its WHEN_FOCUSED input map, you do not need to call the setFocusable method.
To visually show changes in the focus (by drawing a red border only when the component has the focus), Picture has a focus listener.
To gain the focus when the user clicks on the picture, the component has a mouse listener. The listener’s mouseClicked method requests for the focus to be transferred to the picture. Here is the code:
See Tracking Focus Changes to Multiple Components for more discussion of the TrackFocusDemo example.
Customizing Focus Traversal
The FocusTraversalDemo example demonstrates how to customize focus behavior.
The check box was removed from the focus cycle with this line of code:
Here is the application’s custom FocusTraversalPolicy :
Tracking Focus Changes to Multiple Components
In some situations an application may need to track which component has the focus. This information might be used to dynamically update menus or perhaps a status bar. If you need to track the focus only on specific components, it may make sense to implement a focus event listener.
The following example demonstrates tracking the focus owner by installing a property change listener on the keyboard focus manager.
Timing Focus Transfers
Focus transfers are asynchronous. This quality can lead to some odd timing-related problems and assumptions, especially during automatic transfers of the focus. For example, imagine an application with a window containing a Start button, a Cancel button and a text field. The components are added in this order:
When the application is launched, the LayoutFocusTraversalPolicy determines the focus traversal policy — in this case, it is the order that the components were added to their container. In this example, the desired behavior is that the Start button has the initial focus, and when the Start button is clicked, it is disabled, and then the Cancel button receives the focus. The correct way to implement this behavior would be to add the components to the container in the desired order or to create a custom focus traversal policy. If, for some reason, that is not possible, then you can implement this behavior with the following code snippet:
As desired, the focus goes from the Start button to the Cancel button, rather than to the text field. But a different result would occur if the same methods were called in the opposite order as follows:
In this case, the focus is requested on the Cancel button before it has left the Start button. The call to the requestFocusInWindow method initiates the focus transfer, but it does not immediately move the focus to the Cancel button. When the Start button is disabled, the focus is transferred to the next component (so there is always a component with the focus) and, in this case, it would then move the focus to the text field, not to the Cancel button.
There are several situations in which you need to make focus requests after all other changes that might affect the focus applies to:
The Focus API
The following tables list the commonly used constructors and methods related to focus. The focus API falls into four categories:
For more detailed information about the focus architecture, see the specification for the Focus Subsystem. You may also find How to Write a Focus Listener useful.
| Class or Method | Purpose |
|---|---|
| LayoutFocusTraversalPolicy | The class that, by default, determines the focus traversal policy for Swing components. |
| getComponentAfter(Container, Component) | Given the component that is passed as input, returns the component that should next have the focus. |
| getComponentBefore(Container, Component) | Given the component that is passed as input, returns the component that should have the focus before this component. The method is used for backward tabbing. |
| getDefaultComponent(Container) (in javax.swing.SortingFocusTraversalPolicy ) | Returns the component that should have the default focus. |
| getFirstComponent(Container) | Returns the first component in the traversal cycle. |
| getInitialComponent(Container) | Returns the component that should receive the focus when a window is made visible for the first time. |
| getLastComponent(Container) | Returns the last component in the traversal cycle. |
| setFocusTraversalPolicy(FocusTraversalPolicy) getFocusTraversalPolicy(FocusTraversalPolicy) (in java.awt.Container ) | Sets or gets the focus traversal policy or determines if a policy has been set. Note that setting a focus traversal policy on a container that is not the focus cycle root may have no apparent effect. A value of null means that a policy has not been explicitly set. If no policy has been set, a policy is inherited from the parent focus cycle root. |
| isFocusCycleRoot() setFocusCycleRoot(boolean) (in java.awt.Container ) | Checks or sets whether a container is the root of a focus traversal cycle. |
| isFocusTraversalPolicyProvider() setFocusTraversalPolicyProvider(boolean) (in java.awt.Container ) | Checks or sets whether a container will be used to provide focus traversal policy. |
Examples that Use Focus
The following table lists examples that manipulate the focus:
How to Set Focus on JTextField?
I make my game run without mouse so using pointer is not a choice. High Score menu will show when player lose.
10 Answers 10
If you want your JTextField to be focused when your GUI shows up, you can use this:
if is there only one Top-Level Container then last lines in GUI constructor would be for example
If the page contains multiple item and like to set the tab sequence and focus I will suggest to use FocusTraversalPolicy.
grabFocus() will not work if you are using FocusTraversalPolicy.
In my case nothing above worked untill I called requestFocus() AFTER my constructor has returned.
MyPanel.initFocus() would have:
This code mouse cursor “jtextfield” “Jcombobox” location focused
It was not working for me when tried to use:
Just jump to the field by java.awt.Robot using key «Tab». For example:
If you should press multiple times on «Tab» to get your Component you can use below method:
If your Component location is dynamic, you can run over the while loop without limitation, but add some focus listener on the component, to stop the loop once arrived to it.
FocusListener — слушаем фокус компонента
Работа с приложением может осуществляться не только с помощью мыши, но и клавиатуры. Здесь важно понятие фокуса (focus). Для обработки событий фокуса при написании Java приложений необходимо использовать FocusListener. Думаю все знают, что такое фокус. Однако хотелось бы немного рассказать про то, как я понимаю понятие фокус. Фокус — это некий указатель, который говорит о том, какой сейчас компонент активен и может реагировать на клавиатуру. В фокусе может находиться только один компонент. Фокус, как правило отображается прямоугольником с тонкой линией (хотя это не всегда так) или пунктирным прямоугольником. Фокус возможно переключать, чтобы добраться до требуемого компонента. Как правило переключение фокуса производится при помощи кнопки Tab. Самый хороший пример работы фокуса, это несколько текстовых полей, в которые требуется ввести некие данные. Одновременно вводить мы не можем — это очевидно, значит должно быть что-то, что говорит, какой компонент сейчас активен и в него можно ввести данные с клавиатуры. Указатель, указывающий на поле, в которое мы в данный момент вводим данные и есть фокус. Фокус могут иметь не только текстовые поля. Его могут иметь, например и кнопки.
Иногда возникает необходимость произвести какие-то действия при получении фокуса компонентом или наоборот при его потере. Делается это всё при помощи слушателей. При получении фокуса компонентом и при его потере система генерирует событие, которое нужно отследить и отреагировать на него. Для реагирования на фокусные события есть специальный слушатель FocusListener. Интерфейс имеет два метода focusGained — вызывается системой при получении компонентом фокуса и focusLost — вызывается при потере фокуса компонентом. Всё предельно просто. Реализуем интерфейс, пишем нужный код в методы, а затем добавляем получившегося слушателя к нужному компоненту при помощи метода addFocusListener.
Тестовое приложение. Оно очень простое и содержит две кнопки. Как только кнопка «Button 2» получает или теряет фокус, и вызываются соответствующие методы слушаетля фокуса, это сразу же отображается текстовым сообщением ниже кнопок.
Внешний вид тестового приложения представлен на рисунке ниже.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class TestFrame extends JFrame <
private JLabel eventLabel;
public TestFrame() <
super(«Test frame»);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
JPanel buttonsPanel = new JPanel();
JButton button1 = new JButton(«Button 1»);
button1.setPreferredSize(new Dimension(150, 80));
buttonsPanel.add(button1);
JButton button2 = new JButton(«Button 2»);
button2.setPreferredSize(new Dimension(150, 80));
buttonsPanel.add(button2);
eventLabel = new JLabel();
eventLabel.setHorizontalAlignment(JLabel.CENTER);
mainPanel.add(eventLabel, BorderLayout.CENTER);
public static JLabel createEmptyLabel() <
JLabel label = new JLabel();
label.setPreferredSize(new Dimension(100, 30));
return label;
>
public static void main(String[] args) <
javax.swing.SwingUtilities.invokeLater(new Runnable() <
public void run() <
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new TestFrame();
frame.setPreferredSize(new Dimension(330, 160));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
>
>);
>
public class CustomListener implements FocusListener <
Учебник по JavaFX: FXML и SceneBuilder
Как создать графический интерфейс с JavaFX, используя разметку FXML и SceneBuilder.
Все посты в серии о JavaFX:
Традиционный способ
Просто напоминание — код выглядел так:
Как видите весь пользовательский интерфейс создан в Java коде.
Это очень простой пример, но по мере усложнения вашего приложения, когда приходится вводить несколько уровней вложенных макетов и множество компонентов, результирующий код может стать очень сложным для понимания. Однако это еще не все — в одном и том же классе присутствует код, который отвечает за структуру, визуальные эффекты и поведение одновременно.
У класса явно нет единой ответственности. Сравните это, например, с веб-интерфейсом, где каждая страница имеет четко разделенные задачи:
Представляем FXML
Очевидно, что иметь весь код в одном месте не очень хорошая идея. Вам нужно как-то структурировать его, чтобы его было легче понять и сделать более управляемым.
В действительности есть много шаблонов дизайна для этого. Как правило, в конечном итоге вы приходите к варианту «Model-View-Whatever» — это что-то вроде «Model View Controller», «Model View Presenter» или «Model View ViewModel».
Можно часами обсуждать плюсы и минусы разных вариантов — давайте не будем делать это здесь. Более важно то, что с JavaFx вы можете использовать любой из них.
Это возможно потому, что в дополнение к процедурной конструкции вашего пользовательского интерфейса вы можете использовать декларативную разметку XML.
Оказывается иерархическая структура XML — это отличный способ описать иерархию компонентов в пользовательском интерфейсе. HTML работает достаточно хорошо, верно?
Формат XML, специфичный для JavaFX, называется FXML. В нем вы можете определить все компоненты приложения и их свойства, а также связать их с контроллером, который отвечает за управление взаимодействиями.
Загрузка FXML файлов
Итак, как мы можем изменить наш метод запуска для работы с FXML?
Здесь root представляет корневой компонент вашего пользовательского интерфейса, остальные компоненты вложены в него.
Метод load имеет generic возвращаемое значение, поэтому вы можете указать конкретный тип, а не Parent. Далее, вы получаете доступ к компонентно-ориентированным методам. Однако, это делает ваш код более хрупким. Если вы измените тип корневого компонента в вашем FXML, приложение может перестать работать во время выполнения, но при этом во время компиляции не будет ошибок. Это происходит потому, что теперь есть несоответствие типа, объявленного в вашем FXML и в загрузчике Java FXML.
Создание FXML файла
После создадания файла в его первой строке необходимо ввести декларацию XML:
Импорт
Прежде чем добавить отдельные компоненты в файл, необходимо убедиться, что они правильно распознаются. Для этого необходимо добавить операторы импорта. Это очень похоже на импорт в Java классах. Вы можете импортировать отдельные классы или использовать знаки подстановки как обычно. Давайте рассмотрим пример раздела импорта:
Хорошей новостью является то, что вместо добавления всех операторов импорта вручную, ваша IDE должна помочь вам добавить импорт аналогично добавлению их в классы Java.
Добавление компонентов
Теперь пришло время добавить некоторые компоненты. В предыдущей статье мы узнали, что каждая сцена может иметь только один дочерний компонент. Для начала давайте добавим простую метку (label):
Конечно, метка в качестве корневого компонента — это не очень реалистичный пример. Обычно предпочтительнее использовать какой-то макет (layout), который является контейнером для нескольких компонентов и организует их расположение. Мы рассмотрим макеты позже в этой серии, а сейчас давайте просто воспользуемся простым VBox, который размещает свои дочерние элементы вертикально друг над другом.
FX Namespace
Существует пара элементов и атрибутов FXML, которые по умолчанию недоступны. Вам нужно добавить пространство имен (Namespace) FXML, чтобы сделать их доступными. Его необходимо добавить к корневому компоненту:
Теперь можно использовать новые элементы из пространства имен fx. Давайте попробуем добавить уникальные идентификаторы в наши компоненты:
Атрибут fx:id является уникальным идентификатором компонента, который можно использовать для ссылки на компонент из других частей нашего FXML и даже из нашего контроллера.
Скрипты
Наше приложение пока статично. Есть несколько меток и кнопка, но приложение не делает ничего динамического.
Давайте отреагируем на нажатие нашей кнопки и изменим заголовок с «Click me!» на «Click me again!».
Первое, что нужно сделать, это добавить обработчик события onAction для нашей кнопки.
Обратите внимание на fx:id, это идентификатор, который будет использоваться позже для ссылки на кнопку.
Теперь нужно предоставить функцию, которая будет вызвана для обработки события. Ее можно определить внутри тега fx:script. Важно то, что вы можете использовать различные языки для написания скрипта, JavaScript, Groovy или Clojure. Давайте посмотрим пример на JavaScript:
Заметьте, что мы ссылаемся на наш компонент Button с помощью идентификатора mainButton, который был объявлен так:
Также необходимо указать, какой язык сценариев вы используете в файле FXML:
Давайте рассмотрим полный текст примера:
Должен ли я использовать это?
В приведенном выше примере показано, как ссылаться на компоненты с помощью fx:id и как добавить простое поведение с помощью скрипта на JavaScript. Неужели это то, что вы должны на самом деле делать?
Ответ — в большинстве случаев нет. Есть несколько проблем с таким подходом. Причина, по которой введен FXML, была разделение интересов — чтобы отделить структуру и поведение пользовательского интерфейса. В этом скрипте снова вернулось поведение слитное со структурой пользовательского интерфейса. Более того, поскольку мы больше не работаем с кодом Java, а с XML, были утрачены все проверки кода во время компиляции и безопасность типов. Теперь все проблемы в приложении будут обнаружены во время выполнения, а не во время компиляции. Приложение стало очень хрупким и подверженым ошибкам.
Добавление контроллера
Итак, что можно сделать, чтобы получить четкое разделение интересов? Можно связать контроллер с нашим файлом FXML. Контроллер — это Java класс, который отвечает в приложении за обработку поведения и взаимодействия с пользователем. Таким образом можно вернуть безопасность типов и проверки времени компиляции.
Контроллер является POJO, он не должен расширять или реализовывать что-либо, а также не должен иметь никаких специальных аннотаций.
Как можно связать класс контроллера с нашим FXML? По существу, есть два варианта.
На Java
Вы можете создать экземпляр контроллера самостоятельно или использовать любые другие способы создания экземпляра, такие как инъекция зависимости. Затем просто загрузите вашим FXMLLoader.
В FXML
Вы можете указать класс вашего контроллера как атрибут fx:controller, который должен находиться в корневом компоненте.
Если вы объявляете свой класс Controller в FXML, он автоматически создается для вас. Этот подход имеет одно ограничение — в контроллере нужно создать конструктор без аргументов, чтобы позволит легко создавать новый экземпляр класса Controller.
Для получения доступа к экземпляру контроллера, созданного автоматически, можно использовать загрузчик FXML:
Вызов методов контроллера
Теперь, когда имеется контроллер, можно удалить скрипт и реализовть логику нажатия кнопок прямо в контроллере:
Следующим шагом является регистрация вызова этого метода в качестве обработчика события onAction нашей кнопки. Чтобы ссылаться на методы из нашего контроллера, нам нужно использовать знак # перед именем метода:
При нажатии на кнопку, она вызывает метод MainSceneController.buttonClicked(). Имейте в виду, что это работает, только если метод объявлен public. Если модификатор доступа более строгий, необходимо аннотировать метод аннотацией @FXML.
Внедрение компонентов в контроллер
Пока что мы просто печатаем на консоль. Что если мы снова захотим изменить текст нашей кнопки на «Click me again»? Как мы можем получить ссылки на компоненты в нашем контроллере?
К счастью, это легко. Помните эти атрибуты fx:id?
JavaFX пытается автоматически сопоставить компоненты с fx:id с полями определенным в вашем контроллере с тем же именем.
Предположим, у нас есть кнопка описанная выше с
JavaFX пытается внедрить объект кнопки в ваш контроллер в поле с именем mainButton:
Как и в предыдущих методах, ваши поля должны быть public или аннотированными @FXML.
Теперь, когда у нас есть ссылка на нашу кнопку, можно легко изменить ее текст:
Scene Builder
Написание вашей структуры GUI в XML может быть более естественным, чем в Java (особенно если вы знакомы с HTML). Тем не менее, до сих пор это не очень удобно. Хорошей новостью является то, что существует официальный инструмент под названием Scene Builder, который поможет вам в создании пользовательского интерфейса. В двух словах, это графический редактор для вашего графического интерфейса.
В редакторе имеется три основных области:
Standalone
Scene Builder можно загрузить как отдельное приложение, которое можно использовать для редактирования FXML файлов.
Интеграция с IntelliJ IDEA
В качестве альтернативы, Scene Builder предлагает интеграцию с IDE.
В IntelliJ IDEA вы можете нажать правой кнопкой мыши на любом FXML файле и затем выбрать опцию меню «Открыть» в SceneBuilder.
В качестве альтернативы, IntelliJ IDEA интегрирует SceneBuilder непосредственно в IDE. Если вы откроете файл FXML в IDEA, в нижней части экрана появятся две вкладки
В IntelliJ IDEA можто настроить расположение исполняемого файла SceneBuilder:
Settings → Languages & Frameworks → JavaFX → Path to SceneBuilder











