Fire stateChanged event on JTabbedPane

我们两清 提交于 2019-12-01 23:18:07

I found the real reason of my problem.

It was the thread problem, not the animation itself. I was calling setSelectedIndex outside EDT so my JTabbedPane was updated instantly and then the animation from EDT was performed.

The anserw is:

public void setSelectedTab(final int tab) throws InterruptedException, InvocationTargetException{
    if(!SwingUtilities.isEventDispatchThread()){
        SwingUtilities.invokeAndWait(new Runnable() {
            @Override
            public void run() {
                animatedTabbedPane.setSelectedIndex(tab);
            }
        });
    }
    else
        animatedTabbedPane.setSelectedIndex(tab);
}

Changing tabs inside EDT doesn't couse unwanted flash anymore.

One approach would be to add an AncestorListener to each tab's content. Let the listener trigger the desired effect as the tab is added to or removed from visibility.

import java.awt.EventQueue;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;

/**
 * @see http://stackoverflow.com/a/17993449/230513
 */
public class Test {

    private void display() {
        JFrame f = new JFrame("Test");
        final JTabbedPane jtp = new JTabbedPane();
        jtp.add("One", createPanel());
        jtp.add("Two", createPanel());
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(jtp);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private JPanel createPanel() {
        JPanel panel = new JPanel();
        final JLabel label = new JLabel(new Date().toString());
        panel.add(label);
        panel.addAncestorListener(new AncestorListener() {
            @Override
            public void ancestorAdded(AncestorEvent event) {
                // start animation
                label.setText(new Date().toString());
            }

            @Override
            public void ancestorRemoved(AncestorEvent event) {
                // stop animation
            }

            @Override
            public void ancestorMoved(AncestorEvent event) {
            }
        });
        return panel;
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test().display();
            }
        });
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!