用Java创建Outlook样式用户界面?

时间:2010-02-18 13:41:10

标签: java user-interface

我希望在Java桌面应用程序中创建Outlook样式UI,在左侧窗格中显示上下文或节点列表,在右侧窗格中显示所选上下文。我该怎么做?

我正在寻找比“使用JFrame”更多的细节。教程或演练将是好的,或一些框架代码,或框架/库提供这种开箱即用的东西。

感谢。

修改

到目前为止我的(已编辑)代码:

UIPanel

public class UIPanel extends javax.swing.JPanel {

    private final JSplitPane splitPane;

    public UIPanel() {
        super(new BorderLayout());
        initComponents();

        JPanel contextPnl = new ContextPanel();
        JPanel treePnl = new NodePanel(contextPnl);

        this.splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
          true, new JScrollPane(treePnl), new JScrollPane(contextPnl));

        add(splitPane, BorderLayout.CENTER);

        //not sure I need these?
        splitPane.setVisible(true);
        treePnl.setVisible(true);
        contextPnl.setVisible(true);
}

NodePanel

public class NodePanel extends javax.swing.JPanel {

    JPanel _contextPanel;

    public NodePanel(JPanel contextPanel) {
        initComponents();
        _contextPanel = contextPanel;
        initialise();
    }

    private void initialise(){
        nodeTree.addTreeSelectionListener(getTreeListener());
    }

    private TreeSelectionListener getTreeListener(){
        return new TreeSelectionListener() {
            public void valueChanged(TreeSelectionEvent e) {
                DefaultMutableTreeNode node = (DefaultMutableTreeNode)
                               nodeTree.getLastSelectedPathComponent();
            // if nothing is selected
            if (node == null)
                return;

        // get selected node
        Object nodeInfo = node.getUserObject();

        CardLayout layout = (CardLayout) _contextPanel.getLayout();
        //layout.show(_contextPanel, "test"); //show context for selected node

        }
    };
}

ContextPanel

public class ContextPanel extends javax.swing.JPanel {

    JPanel _cards;
    final static String CONTEXT1 = "Context 1";
    final static String CONTEXT2 = "Context 2";
    JPanel _context1;
    JPanel _context2;


    public ContextPanel() {
        initComponents();
        intialiseContexts();
    }

    public void updateContext(String contextName){
        //TODO
    }

    private void intialiseContexts(){
        _context1 = new NodeContext();
        _context2 = new NodeContext();
        _cards = new JPanel(new CardLayout());
        _cards.add(_context1, CONTEXT1);
        _cards.add(_context2, CONTEXT2);
}

2 个答案:

答案 0 :(得分:3)

此处的关键概念是将JSplitPane定义为具有水平拆分的顶级Component。分割窗格的左侧成为“树”视图,而右侧是上下文面板。

诀窍是使用CardLayout作为上下文面板,并使用树面板的TreeSelectionListener注册JTree,这样无论何时选择树节点,CardLayout调用show方法以更新上下文面板当前显示的内容。您还需要将各种组件添加到上下文面板,以便使用此方法。

public class UIPanel extends JPanel {
  private static final String BLANK_CARD = "blank";
  private final JSplitPane splitPane;

  public UIPanel() {
    super(new BorderLayout());

    JPanel treePnl = createTreePanel();
    JPanel contextPnl = createContextPanel();

    this.splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
      true, new JScrollPane(treePnl), new JScrollPane(contextPnl));

    add(splitPane, BorderLayout.CENTER);
  }
}

编辑:使用示例

public class Main {
  public static void main(String[] args) {
    // Kick off code to build and display UI on Event Dispatch Thread.
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        JFrame frame = new JFrame("UIPanel Example");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());

        // Add UIPanel to JFrame.  Using CENTER layout means it will occupy all
        // available space.
        frame.add(new UIPanel(), BorderLayout.CENTER);

        // Explicitly set frame size.  Could use pack() instead.
        frame.setSize(800, 600);

        // Center frame on the primary display.
        frame.setLocationRelativeTo(null);

        // Finally make frame visible.
        frame.setVisible(true);
      }
    });
  }
}

其他建议

  • 我可以看到您为NodePanelContextPanel创建了单独的课程。鉴于这些类的简单性以及它们之间的紧密耦合,将所有UI组件直接嵌入UIPanel中并使用构建两个子面板的实用方法可能更有意义。如果您确实与NodePanel和ContextPanel保持联系,请尝试将其打包为私有而非公开。

  • CardLayout方法如果你有一个小的(ish)节点并且你事先知道它们(因此可以提前将它们相应的组件添加到CardLayout),效果很好。如果没有,您应该仅使用BorderLayout来考虑上下文面板,并且每当您点击某个节点时,只需将相关节点组件添加到BorderLayout.CENTER和调用面板的NodePanel位置即可。 revalidate()使其再次执行其布局。我之前使用过CardLayout的原因是它意味着我的节点只需要记住一条信息:卡片名称。但是,现在我想起来,我认为这种其他方法没有任何真正的劣势 - 实际上它可能更灵活。

答案 1 :(得分:0)

您可能希望使用像eclipse这样的平台作为起点。它为创建这些应用程序提供了非常丰富的环境,因此您无需从头开始创建所有内容。在线指南和帮助非常好,有几本关于这个主题的书。