使用JTabbedPane,我想在选择新选项卡的更改生效之前立即捕捉这一时刻并执行操作。它类似于摆动组件的焦点丢失事件。目的是在更改选项卡时将几个JTextField的文本保存到外部文件中,因此每次用户单击其他选项卡时,当前选项卡的值都会写入外部文件。
我一直在使用ChangeListener跟踪标签的更改,但还没有找到一种方法来完成我需要的工作。在下一个简单的例子中如何实现它的任何想法?
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class TabSample {
static void add(JTabbedPane tabbedPane, String label) {
JButton button = new JButton(label);
tabbedPane.addTab(label, button);
}
public static void main(String args[]) {
JFrame frame = new JFrame("TabSample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTabbedPane tabbedPane = new JTabbedPane();
String titles[] = { "Geometry", "Materials", "Analysis"};
for (int i = 0, n = titles.length; i < n; i++) {
add(tabbedPane, titles[i]);
}
ChangeListener changeListener = new ChangeListener() {
public void stateChanged(ChangeEvent changeEvent) {
JTabbedPane sourceTabbedPane = (JTabbedPane) changeEvent.getSource();
int index = sourceTabbedPane.getSelectedIndex();
System.out.println("Tab changed to: " + sourceTabbedPane.getTitleAt(index));
}
};
tabbedPane.addChangeListener(changeListener);
frame.add(tabbedPane, BorderLayout.CENTER);
frame.setSize(400, 150);
frame.setVisible(true);
}
}
答案 0 :(得分:4)
一种可能的方式,并且我不能100%确定这是否可以接受,而是为JTabbedPane创建自己的模型,JTabbedPane是一个实现SingleSelectionModel的模型(检查SingleSelectionModel API),这会覆盖setSelectedIndex(int index)
方法,我非常确定Swing在告知JTabbedPane更改标签时使用的方法。如果您创建一个从DefaultSingleSelectionModel扩展的类,一个实现上述接口并覆盖此方法的具体类,您可以在调用super方法之前进行方法调用,从而进行GUI调用< em>在标签更改之前。例如,您的setSelectedIndex
方法可能如下所示:
@Override
public void setSelectedIndex(int index) {
if (activated) {
String text = String.format("Before change, old index: %d; new index: %d", super.getSelectedIndex(), index);
JOptionPane.showMessageDialog(gui, text);
}
super.setSelectedIndex(index);
}
使用上面的代码可以实现如下:
import java.awt.BorderLayout;
import java.awt.Component;
import javax.swing.DefaultSingleSelectionModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class TabSample {
static void add(JTabbedPane tabbedPane, String label) {
JButton button = new JButton(label);
tabbedPane.addTab(label, button);
}
public static void main(String args[]) {
JFrame frame = new JFrame("TabSample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MySingleSelectionModel selectionModel = new MySingleSelectionModel(frame);
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.setModel(selectionModel);
String titles[] = { "Geometry", "Materials", "Analysis"};
for (int i = 0, n = titles.length; i < n; i++) {
add(tabbedPane, titles[i]);
}
ChangeListener changeListener = new ChangeListener() {
public void stateChanged(ChangeEvent changeEvent) {
JTabbedPane sourceTabbedPane = (JTabbedPane) changeEvent.getSource();
int index = sourceTabbedPane.getSelectedIndex();
System.out.println("Tab changed to: " + sourceTabbedPane.getTitleAt(index));
}
};
tabbedPane.addChangeListener(changeListener);
frame.add(tabbedPane, BorderLayout.CENTER);
frame.setSize(400, 150);
frame.setVisible(true);
selectionModel.setActivated(true);
}
private static class MySingleSelectionModel extends DefaultSingleSelectionModel {
private Component gui;
private boolean activated = false;
public MySingleSelectionModel(Component gui) {
this.gui = gui;
}
public void setActivated(boolean activated) {
this.activated = activated;
}
@Override
public void setSelectedIndex(int index) {
if (activated) {
String text = String.format("Before change, old index: %d; new index: %d",
super.getSelectedIndex(), index);
JOptionPane.showMessageDialog(gui, text);
}
super.setSelectedIndex(index);
}
}
}
请注意,我使用布尔字段activated
来激活行为更改,以便它不会在GUI创建时触发。在显示GUI后,我在模型上调用setActivated(true)
。
关于你的编辑:
目标是在更改选项卡时将几个JTextField的文本保存到外部文件中,因此每次用户单击其他选项卡时,当前选项卡的值都会写入外部文件。
我应该知道,毕竟这是一个XY Problem,在最好的解决方案是使用完全不同的方法时,你会问如何解决特定的代码问题。将来,请提供原始问题的所有相关信息,以便我们避免浪费时间使用不必要的解决方案。
事实上,在选项卡更改之前,实际上不需要执行任何操作,因为在选项卡更改时获取数据是完全正常的。你的解决方案是使用ChangeListener,并且不需要通过我上面发布的体操。