如何监听用户对
JTabbedPane
选项卡的选择?
目前,我们附加了
ChangeListener
,但问题是即使用户没有选择选项卡,ChangeEvent
也会发布。具体来说,它是在删除选项卡并重新计算选项卡索引时发布的。当发生这种情况时,我们不想执行我们应该对用户选择执行的相同逻辑。我不想讨论细节(它们只会让你感到困惑),但这会导致我们的应用程序出现一个讨厌的错误,这不仅仅是性能问题
为了证明这一点,让我向您展示
javax.swing.JTabbedPane#removeTabAt
方法的片段
// triggers ChangeEvent
if (selected > index) {
setSelectedIndexImpl(selected - 1, false);
选项卡式窗格中的选项卡应该是动态的。删除和添加回来遵循我们应用程序的要求
这是 MRE:
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
public class TabbedPaneDemo {
private static JTabbedPane tabbedPane;
private static JButton removeGreenTabButton;
private static JButton restoreGreenTabButton;
public static void main(String[] args) {
Container mainPanel = createMainPanel();
JFrame frame = new JFrame("Tabbed Pane demo");
frame.setContentPane(mainPanel);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static JComponent createMainPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.add(createButtonPanel(), BorderLayout.NORTH);
panel.add(createTabbedPane());
return panel;
}
private static JPanel createButtonPanel() {
JPanel panel = new JPanel();
panel.add(createRemoveTabButton());
panel.add(createRestoreTabButton());
return panel;
}
private static JButton createRemoveTabButton() {
removeGreenTabButton = new JButton("Remove green tab");
removeGreenTabButton.addActionListener(e -> {
tabbedPane.remove(0);
restoreGreenTabButton.setEnabled(true);
removeGreenTabButton.setEnabled(false);
});
return removeGreenTabButton;
}
private static JButton createRestoreTabButton() {
restoreGreenTabButton = new JButton("Restore green tab");
restoreGreenTabButton.setEnabled(false);
restoreGreenTabButton.addActionListener(e -> {
tabbedPane.insertTab("Green tab", null, createGreenPanel(), null, 0);
removeGreenTabButton.setEnabled(true);
restoreGreenTabButton.setEnabled(false);
});
return restoreGreenTabButton;
}
private static JTabbedPane createTabbedPane() {
tabbedPane = new JTabbedPane();
tabbedPane.addTab("Green tab", createGreenPanel());
tabbedPane.addTab("Red tab", createRedPanel());
tabbedPane.setPreferredSize(new Dimension(250, 150));
tabbedPane.addChangeListener(createChangeListener());
return tabbedPane;
}
private static Component createGreenPanel() {
JPanel panel = new JPanel();
panel.setBackground(Color.GREEN);
return panel;
}
private static Component createRedPanel() {
JPanel panel = new JPanel();
panel.setBackground(Color.RED);
return panel;
}
private static ChangeListener createChangeListener() {
// this is supposed to happen only on user tab selections
return e -> System.out.println("Handling user tab selection...");
}
}
Java 8
更改时都会触发
ChangeEvent
,您必须另外控制和检查所选选项卡索引(例如使用((JTabbedPane) event.getSource()).getSelectedIndex()
)才能确定选择是否实际更改。您可以实现这一点,例如通过自定义
ChangeListener
跟踪当前选定的选项卡并在选择更改时调用特定代码。