Ich versuche, eine JToggleButton
aufzubauen, die eine JDialog
(die eine JList
enthält) zeigt, wenn die JToggleButton
gedrückt wird. Und lassen Sie die JDialog
verschwinden, wenn die JToggleButton
erneut gedrückt wird, ODER wenn der Benutzer wegklickt oder woanders im Rahmen (ich simuliert dies über eine FocusListener
auf der JList
, wenn der Fokus verloren ist).Umgang mit Zustand und Ereignisfolgen von JDialog und JToggleButton
Wenn Sie die Taste nacheinander drücken, wird JDialog
korrekt angezeigt und ausgeblendet.
Allerdings ist das Problem, wenn die JDialog
sichtbar ist, und ich irgendwo anders auf den Rahmen klicken, verschwindet die JDialog
korrekt, da der Fokus verloren geht. Der Status der JToggleButton
bleibt jedoch falsch als ausgewählt festgelegt. Dies bedeutet, dass beim Klicken auf JToggleButton
jetzt die JDialog
nicht angezeigt wird, da der Status der JToggleButton
jetzt nicht mehr synchron ist. Stattdessen muss ich zweimal die JToggleButton
drücken, um die JDialog
wieder sichtbar zu bekommen. Das folgende Codebeispiel veranschaulicht dieses Problem.
Ich kann nicht scheinen, den verlorenen Fokus der JList
zu erhalten, um mit dem Zustand der JToggleButton
zu synchronisieren. Es scheint ein einfaches Problem zu sein, aber ich stehe fest auf der Suche nach einer Lösung. Kann jemand helfen? Vielen Dank.
Sehen Sie meinen Code unten:
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);
}
}
Danke für die Vorschläge, aber das ist leider immer noch ein Problem. Wenn Sie den Beispielcode verwenden, wird der 'JDialog' verschwinden, sobald der Fokus verloren ist, aber es führt zu einem neuen Problem, bei dem das Klicken auf den' JToggleButton' den 'JDialog' nun ständig sichtbar macht; anstelle des vorherigen Verhaltens, bei dem der 'JDialog' erscheint und verschwindet, wenn der' JToggleButton' jedes Mal ausgewählt oder nicht ausgewählt wird. – malaccan