java - JTabbedPane中添加的选项卡不显示

标签 java multithreading swing tabs jtabbedpane

我有VTreePanel类,它从CPanel扩展,而CPanel又从JPanel扩展。该类有一个 JSplitPane 对象,该对象分为两个区域:左和右。左侧包含树形菜单选择对象。在右侧,它包含 JTabbedPane 对象。 VTreePanel类是这样的:

public final class VTreePanel extends CPanel
    implements ActionListener
{
    private JSplitPane centerSplitPane = new JSplitPane();

    private JTabbedPane tabbedPane;

    ...

    // GET method for the tabbedPane    
    public JTabbedPane getTabbedPane() {
        return tabbedPane;
    }

    // Constructor
    public VTreePanel(int WindowNo, boolean hasBar, boolean editable)
    {

        ...

        tabbedPane = new JTabbedPane();
        centerSplitPane.add(treePart, JSplitPane.LEFT);
        centerSplitPane.add(tabbedPane, JSplitPane.RIGHT);  // Look at this

        ...
    }

}

在构造函数中,我将树选择 (treePart) 和 JTabbedPane 对象 (tabbedPane) 添加到 JSplitPane 对象 (centerSplitPane) 中。我还没有将任何选项卡添加到 tabbedPane 中。看下面的截图:

http://i45.tinypic.com/2v3j0nl.jpg

那么当用户单击其中一个菜单时如何添加选项卡?

我有 AMenu 类,它实现了 PropertyChangeListener,当用户单击菜单时触发 propertyChange 方法:

public final class AMenu extends CFrame
    implements ActionListener, PropertyChangeListener, ChangeListener
{

    private VTreePanel treePanel = null;    // this is the VTreePanel object

    ...

    public void propertyChange(PropertyChangeEvent e)
    {
        ...

        // Here I pass the VTreePanel object as parameter to AMenuStartItem thread object
        (new AMenuStartItem(cmd, true, sta, this, treePanel)).start();
    }

}

您可以看到我有 VTreePanel 对象 (treePanel),并且我将 VTreePanel 对象作为参数传递给 AMenuStartItem 线程。 AMenuStartItem 包含执行在 JTabbedPane 中添加 Tab 的逻辑(请记住,JTabbedPane 对象 (tabbedPane) 位于 VTreePanel 中)。

这是AMenuStartItem线程类:

public class AMenuStartItem extends Thread implements ActionListener
{
    private VTreePanel m_vtreePanel;

    public AMenuStartItem (int ID, boolean isMenu, String name, AMenu menu, VTreePanel vtreepanel)
    {
        ...

        m_vtreePanel = vtreepanel;  // save the VTreePanel object
    }

    // The thread method that executed when thread is started
    public void run()
    {
        ...

        startWindow(0, cmd);

        ...
    }

    private void startWindow(int AD_Workbench_ID, int AD_Window_ID)
    {
        ...

        // Here I perform adding new tab
        m_vtreePanel.getTabbedPane().addTab(frame.getTitle(), frame.getAPanel());

        ...
    }

}

因此,getTabbedPane() 返回了 JTabbedPane 对象,并且执行了 addTab() 方法,但根本没有显示任何选项卡。

有人知道如何解决这个问题吗?

最佳答案

与 UI 的所有交互都必须通过事件调度线程完成,无一异常(exception)......

public class AMenuStartItem extends Thread implements ActionListener
{
    private VTreePanel m_vtreePanel;

    public AMenuStartItem (int ID, boolean isMenu, String name, AMenu menu, VTreePanel vtreepanel)
    {
        ...

        m_vtreePanel = vtreepanel;  // save the VTreePanel object
    }

    // The thread method that executed when thread is started
    public void run()
    {
        ...

        startWindow(0, cmd);

        ...
    }

    private void startWindow(final int AD_Workbench_ID, final int AD_Window_ID)
    {
        ...

        if (EventQueue.isDispatchingThread()) {
            // This is safe, we're in the EDT
            m_vtreePanel.getTabbedPane().addTab(frame.getTitle(), frame.getAPanel());
            m_vtreePanel.getTabbedPane().invalidate();
            m_vtreePanel.getTabbedPane().repaint();
        } else {
            // This is unsafe, we need to resync with the EDT
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    // Here I perform adding new tab
                    m_vtreePanel.getTabbedPane().addTab(frame.getTitle(), frame.getAPanel());
                    m_vtreePanel.getTabbedPane().invalidate();
                    m_vtreePanel.getTabbedPane().repaint();

                }
            });
        }

        ...
    }

}

关于java - JTabbedPane中添加的选项卡不显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12946819/

相关文章:

java - 如何在 Quartz 框架中以两小时为间隔安排一项工作

java - 为什么我的 if 语句 JAVA 总是得到错误的输出

c++ - 为 boost logger 设置线程名称

java - 如何使用 objectId 或 hashcode 对对象进行同步?

java - 访问 JFrame 组件

java - 测试字符串中的数字字符

python - 在Python中使用threading.Semaphore()

java - 如何在JTable中的特定位置插入一列

java - 如何从 Graphics g 获取像素颜色

java - 使用Java进行HDFS加密