Я довольно новичок в разработке Swing, надеюсь, мой вопрос не глупый.
У меня следующая проблема. Я отслеживаю фокус с помощью KeyboardFocusManager
, прослушиваю изменения свойства permanentFocusOwner
. Однако, когда фокус меняется с одного элемента управления на другой, я получаю промежуточное изменение свойства permanentFocusOwner
на null
.
Моя текущая логика пользовательского интерфейса вносит некоторые изменения в элементы управления, когда фокус находится внутри одной из панелей или ее дочерних панелей. Однако получение промежуточного звена null
нарушает эту логику.
Я искал в Google информацию об этой проблеме, но не нашел ничего релевантного.
Вопрос в том, является ли это поведение задуманным, и есть ли какой-нибудь способ обойти промежуточные нули.
Вот минимальное приложение, воспроизводящее указанное поведение:
import java.awt.*;
import java.beans.*;
import javax.swing.*;
public class FocusNullTest extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
FocusNullTest self = new FocusNullTest();
self.setVisible(true);
}
});
}
public FocusNullTest() {
setSize(150, 100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = getContentPane();
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.X_AXIS));
contentPane.add(new JButton("1"));
contentPane.add(new JButton("2"));
KeyboardFocusManager focusManager =
KeyboardFocusManager.getCurrentKeyboardFocusManager();
focusManager.addPropertyChangeListener(
"permanentFocusOwner",
new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent e) {
System.out.println("permanentFocusOwner changed from: "
+ e.getOldValue());
System.out.println("permanentFocusOwner changed to : "
+ e.getNewValue());
}
});
}
}
Выходные данные журнала:
(запуск программы, фокус устанавливается на кнопку 1 автоматически)
переменная перманентного фокуса изменена с: ноль
Параметр перманентного фокуса изменен на: javax.swing.JButton [, 0,18,41x26, (пропущено)]
(нажал на кнопку 2)
перманентFocusOwner изменен с: javax.swing.JButton [, 0,18,41x26, (пропущено)]
constantFocusOwner изменен на: null
перманентныйFocusOwner изменен с: ноль
Параметр перманентного фокуса изменен на: javax.swing.JButton [, 41,18,41x26, (пропущено)]
(необязательная часть, на коде намерения)
Моя цель - сделать что-то похожее на представление списка, где записи расширяются и отображают больше информации, когда они получают фокус (и сворачиваются обратно, когда теряют его). Расширенный вид содержит несколько дополнительных кнопок.
JList
не представляется подходящим элементом управления, потому что (1) он не позволяет нажимать кнопки, и (2) его записи имеют постоянную высоту, тогда как я хочу, чтобы записи динамически расширялись в фокусе , JTable
с его режимом редактирования, кажется, также не является подходящим решением, по крайней мере, из-за постоянного размера записи.
Поэтому я использую обычный JPanel
с вертикальным расположением блоков в качестве контейнера, подписываюсь на изменения модели и обновляю визуальные элементы вручную. Проблема в том, что когда я нажимаю на кнопку, содержащийся элемент списка теряет фокус. Я мог бы обнаружить, что фокус все еще остается в пределах элемента списка, если фокус не изменится на null
временно.