Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The key concept here is to define a <code>JSplitPane</code> as your top-level <code>Component</code> with a horizontal split. The left-hand side of the split pane becomes your "tree" view while the right-side is the context panel.</p> <p>The trick is to use <code>CardLayout</code> for your context panel and to register a <code>TreeSelectionListener</code> with the tree panel's <code>JTree</code> so that whenever a tree node is selected, the <code>CardLayout</code>'s <code>show</code> method is called in order to update what the context panel is currently showing. You will also need to add the various Components to the context panel in order for this approach to work.</p> <pre><code>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); } } </code></pre> <p><strong>EDIT: Example Usage</strong></p> <pre><code>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); } }); } } </code></pre> <p><strong>Additional Advice</strong></p> <ul> <li><p>I can see you've created separate classes for your <code>NodePanel</code> and <code>ContextPanel</code>. Given the simplicity of these classes and how tightly coupled they are it probably makes more sense to embed all the UI components directly within <code>UIPanel</code> and have utility methods that build the two sub-panels. If you do keep with NodePanel and ContextPanel try to make them package private rather than public.</p></li> <li><p>The <code>CardLayout</code> approach works well if you have a small(ish) number of nodes and you know them in advance (and hence can add their corresponding Components to the CardLayout in advance). If not, you should consider your context panel simply using <code>BorderLayout</code> and, whenever you click on a node you simply add the relevant node component to the <code>BorderLayout.CENTER</code> position of the <code>NodePanel</code> and call panel.<code>revalidate()</code> to cause it to perform its layout again. The reason I've used CardLayout in the past is that it means my nodes only need to remember one piece of information: The card name. However, now I think of it I don't see any real disadvantage with this other approach - In fact it's probably more flexible.</p></li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload