Java 更改JTabbedPane中选定的选项卡;自动地;

Java 更改JTabbedPane中选定的选项卡;自动地;,java,swing,jtabbedpane,Java,Swing,Jtabbedpane,我第一次使用JavaSwing,我有一个无法解决的问题 我有一个带有3个选项卡的JTabbedPane,我需要在计算结束时“自动”切换到下一个选项卡,首先单击JButton(在其中一个选项卡内)。 我曾尝试使用setSelectedIndex(),但不起作用。 在JButton的ActionEvent之后,所选选项卡(在eclipse控制台中打印)已经更改,但在GUI中没有效果 是的,我尝试了validate(),revalidate()方法,甚至是repaint()方法,但都没有成功 这是我代

我第一次使用JavaSwing,我有一个无法解决的问题

我有一个带有3个选项卡的JTabbedPane,我需要在计算结束时“自动”切换到下一个选项卡,首先单击JButton(在其中一个选项卡内)。 我曾尝试使用
setSelectedIndex()
,但不起作用。 在JButton的
ActionEvent
之后,所选选项卡(在eclipse控制台中打印)已经更改,但在GUI中没有效果

是的,我尝试了
validate()
revalidate()
方法,甚至是
repaint()
方法,但都没有成功

这是我代码的一个例子

public类Tab1扩展了JPanel{
//单击此按钮时,计算开始
JButton btn=新JButton(“计算…”);
addActionListener(新的BtnListener());
添加(btn);
}
我将添加到JTabbedPane的JPanel示例

公共类窗口(){
私有JFrame;
公共窗口(){
init();
}
私有void init(){
frame=新的JFrame();
JTabbedPane tabbedPane=新的JTabbedPane(JTabbedPane.TOP);
JPanel tab1=新tab1();
JPanel tab2=新tab2();
JPanel tab3=新tab3();
tabbedPane.addTab(“tab1”,null,tab1,“tab1”);
addTab(“tab2”,null,tab2,“tab2”);
tabbedPane.addTab(“tab3”,null,tab3,“tab3”);
//添加()所有组件
}
}
我的窗口示例

公共类BtnListener实现ActionListener{
已执行的公共无效操作(操作事件){
//进行计算
//然后我需要切换到下一个选项卡(选项卡2)
}
}
还有我的听众

我希望你能理解我的问题。
请帮帮我,我真的不知道该怎么做才能让它工作,我需要这样做。

当你切换选项卡时,你不需要使用
revalidate()/repaint()
只需
setSelectedIndex()

以下是切换到下一个选项卡的示例:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;

public class TestFrame extends JFrame {

    public static void main(String... s) {
        new TestFrame();
    }

    private JTabbedPane tabs;

    public TestFrame() {
        init();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private void init() {
        tabs = new JTabbedPane();

        tabs.addTab("1", new Tab(1));
        tabs.addTab("2", new Tab(2));
        tabs.addTab("3", new Tab(3));
        add(tabs);
    }

    private class Tab extends JPanel {

        public Tab(int i) {
            JButton next = new JButton("next");
            next.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    int selectedIndex = tabs.getSelectedIndex();
                    int nextIndex = selectedIndex == tabs.getTabCount()-1 ? 0 : selectedIndex+1;
                    tabs.setSelectedIndex(nextIndex);
                }
            });
            add(new JLabel("tab " + i));
            add(next);
        }
    }

}
谢谢你的回答

我检查了我的代码,发现了一个实例问题。我正在更改窗口的另一个实例,而不是可见的实例。所以,当我修复这个问题时,更新起了作用


再次感谢。

更改侦听器类似于属性更改侦听器。更改侦听器在对象(通常是组件)上注册,但它可以是另一个对象,如模型,并且在对象发生更改时通知侦听器。与属性更改侦听器的最大区别在于,更改侦听器不会被通知已更改的内容,而只是通知源对象已更改。因此,当只需要知道对象以任何方式发生更改时,更改侦听器是最有用的

类似地,您需要在按钮(或状态切换按钮)上注册更改侦听器,以便在计算停止且按钮值更改时得到通知

//use some flag to determine when calculation process is actually finished
volatile boolean isCalculationEnds = true;  

button.addChangeListener((ChangeEvent e) -> {
 if (tabbedPane.getSelectedComponent() instanceof CustomPanel && isCalculationEnds) {
     //do something 
     }

 if (tabbedPane.getSelectedIndex()==1 && isCalculationEnds){
   //do something
 });

在这里阅读关于swing中的多线程的文章:寻求帮助。我认为,作者在EDT中进行了大量计算。这是他/她的错误。@Sergiymedvynsky也许你是对的。但正如在
BtnListener
listener计算然后切换中所述,这必须在一定的延迟下工作。