Я пытаюсь построить JToggleButton
, который отображает JDialog
(содержит JList
), когда нажата кнопка JToggleButton
. И при исчезновении JDialog
, когда снова нажата кнопка JToggleButton
, ИЛИ, если пользователь нажимает или где-то еще в кадре (я смоделировал это с помощью FocusListener
на JList
, когда фокус потерян).Обработка состояний и последовательностей событий JDialog и JToggleButton
Нажатие кнопки в последовательности отобразит и спрячет JDialog
.
Однако проблема заключается в том, что видна JDialog
, и я нажимаю в другом месте на рамке, JDialog
правильно исчезает по мере того, как фокус теряется. Однако состояние JToggleButton
остается некорректно заданным как выбранное. Это означало, что нажатие на JToggleButton
теперь не отображает JDialog
, так как состояние JToggleButton
теперь не синхронизировано. Вместо этого мне нужно будет дважды нажать JToggleButton
, чтобы снова увидеть JDialog
. Мой пример кода ниже демонстрирует эту проблему.
Я не могу потерять фокус JList
, чтобы синхронизироваться с состоянием JToggleButton
. Это кажется простой проблемой, но я пытаюсь найти решение. Может ли кто-нибудь помочь? Благодарю.
Смотрите мой код ниже:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
public class MultiComboBox extends JToggleButton
{
public MultiComboBox(JFrame frame, String buttonText)
{
super(buttonText);
JDialog dialog = new JDialog(frame, false);
dialog.setLayout(new BorderLayout());
Object[] items = new Object[] { "one", "two", "three" };
JList list = new JList(items);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane listScrollPane = new JScrollPane(list,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
listScrollPane.setPreferredSize(list.getPreferredSize());
dialog.add(listScrollPane, BorderLayout.CENTER);
dialog.pack();
addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
final JToggleButton button = (JToggleButton) e.getSource();
System.out.println("button clicked: " + button.isSelected());
if (button.isSelected())
{
Point p = button.getLocation();
p.setLocation(p.getX() + 300, p.getY());
SwingUtilities.convertPointToScreen(p, button);
dialog.setLocation(p);
dialog.setVisible(true);
}
else
dialog.setVisible(false);
}
});
list.addFocusListener(new FocusListener()
{
@Override
public void focusGained(FocusEvent e)
{
}
@Override
public void focusLost(FocusEvent e)
{
System.out.println("list focusLost, dialog: " + dialog.isVisible());
dialog.setVisible(false);
}
});
}
public static void main(String[] args)
{
JFrame frame = new JFrame("Test");
frame.setPreferredSize(new Dimension(300, 300));
frame.setLayout(new BorderLayout());
MultiComboBox mcb = new MultiComboBox(frame, "Toggle");
JPanel buttonPanel = new JPanel(new BorderLayout());
buttonPanel.setPreferredSize(new Dimension(80, 30));
buttonPanel.add(mcb, BorderLayout.CENTER);
JPanel blankPanel = new JPanel(new BorderLayout());
frame.add(blankPanel, BorderLayout.CENTER);
frame.add(buttonPanel, BorderLayout.PAGE_START);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
Спасибо за предложения, но, к сожалению, это по-прежнему является проблемой. Используя ваш образец кода, 'JDialog' исчезнет, как только фокус будет потерян, но он вводит новую проблему, когда щелчок на' JToggleButton' теперь делает «JDialog» видимым все время; вместо предыдущего поведения, когда «JDialog» появляется и исчезает, когда «JToggleButton» выбирается/не выбирается каждый раз. – malaccan