我有 VTreePanel 类,它扩展自从JPanel扩展的CPanel。该类有一个 JSplitPane 对象,该对象分为两个区域:left&对。左侧包含树状菜单选择对象。在右侧,它包含 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中添加任何Tab。请看下面的截图:
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()方法,但根本没有显示任何标签。
任何人都知道如何解决这个问题?
答案 0 :(得分:1)
与UI的所有交互必须通过事件调度线程完成,没有例外......
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();
}
});
}
...
}
}