tags:

views:

1114

answers:

3

I want to make a component to occupy the maximumAvailableHeight of the Container. In the code that I have pasted below for example, I have made the root frame to be 800,600. I want to set the height/width of only that frame (and I do not want to try and pixelify its children). If I run this, I see a badly aligned UI.

Firstly, I want a panel (that is inside the root frame) to take up the 100% height of frame (in this case 800px minus that little space it takes for painting the frame title).

Secondly, inside the panel I have a tree and text area. I want both of them to take 100% height and let the tree take 30% and textArea take 70% width (if the tree is expanded to 10 levels then I am ok with ScrollPane).

Understand that this is easiest to achieve in HTML. Just say height=100% and width to be 30% etc and we are done. Does someone know if this can be done in Swing? (I can achieve this by setting pixel heights and layout manager but I am looking for the cleanest solution to set percentage heights and widths.)

package com.ekanathk.logger.gui;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;

public class TestFrame extends JFrame {
    public TestFrame() {
     super("Top Frame");
     setDefaultCloseOperation(EXIT_ON_CLOSE);
     JPanel panel = new JPanel();
     JTree env = getEnvironmentTree();
     env.expandRow(0);
     panel.add(new JScrollPane(env));
     panel.add(new JTextArea("Some contents"));
     getContentPane().add(panel);
     setSize(800, 600);
     SwingUtil.centerComponentOnScreen(this);
     setVisible(true);
    }

    private JTree getEnvironmentTree() {
     DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
     JTree tree = new JTree(root);
     DefaultMutableTreeNode one = new DefaultMutableTreeNode("One");
     root.add(one);
     one.add(new DefaultMutableTreeNode("under one.1"));
     one.add(new DefaultMutableTreeNode("under one.2"));
     root.add(new DefaultMutableTreeNode("two"));
     root.add(new DefaultMutableTreeNode("three"));
     return tree;
    }

    public static void main(String[] args) {
     new TestFrame();
    }
}
A: 

This uses GridBagLayout to do sort of what you want. You might play around with setMinimumSize and setPreferedSize of your components.

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;

public class TestFrame extends JFrame {
    private static final long serialVersionUID = 1L;

    public TestFrame()  {
        super("Top Frame");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        JPanel panel = new JPanel(new GridBagLayout());

        JTree env = getEnvironmentTree();
        env.expandRow(0);

        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.BOTH;
        c.weightx=.7;
        c.weighty=1;

        c.gridx=0;
        c.gridy=0;
        c.gridheight=1;
        c.gridwidth=7;
        panel.add(new JScrollPane(env),c);

        c.weightx=.3;
        c.gridx=7;
        c.gridy=0;
        c.gridheight=1;
        c.gridwidth=GridBagConstraints.REMAINDER;
        panel.add(new JTextArea("Some contents"),c);

        add(panel);
        setSize(800, 600);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private JTree getEnvironmentTree() {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
        JTree tree = new JTree(root);
        DefaultMutableTreeNode one = new DefaultMutableTreeNode("One");
        root.add(one);
        one.add(new DefaultMutableTreeNode("under one.1"));
        one.add(new DefaultMutableTreeNode("under one.2"));
        root.add(new DefaultMutableTreeNode("two"));
        root.add(new DefaultMutableTreeNode("three"));
        return tree;
    }

    public static void main(String[] args) {
        new TestFrame();
    }
}
KitsuneYMG
I did use this solution and it started off well. But in my actual application, the right pane is not just a text area (It is actually a JTabbedPane with potentially 10+ tabs). When the texts in the tree were long the alignment got screwed (I have to setMaximumSize I think, which I dont want). I used
Calm Storm
TableLayout as prescribed in http://java.sun.com/products/jfc/tsc/articles/tablelayout/ and the code worked like a charm :)panel.setLayout(new TableLayout(new double[][]{{0.3, 0.7}, {TableLayout.FILL}}));panel.add(p1, "0,0");panel.add(p2, "1,0");
Calm Storm
Did you try the spring layout solution I posted (currently) below? It has the advantage that it seems to resize better than this one.
KitsuneYMG
A: 

There are a number of layout managers that would accomplish this--GridLayout (1x1 grid), GridBagLayout, perhaps BorderLayout.

Michael Brewer-Davis
A: 

Here is another approach using SpringLayout. I couldn't get Spring.width and Spring.height to work so I used a more verbose way

import java.awt.BorderLayout;
import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.Spring;
import javax.swing.SpringLayout;
import javax.swing.tree.DefaultMutableTreeNode;

public class TestFrame extends JFrame {
    private static final long serialVersionUID = 1L;

    public TestFrame()  {
        super("Top Frame");
        setDefaultCloseOperation(EXIT_ON_CLOSE);        
        SpringLayout layout = new SpringLayout();
        JTree env = getEnvironmentTree();
        env.expandRow(0);
        JPanel contentPane = new JPanel(layout);
        contentPane.setLayout(layout);
        JScrollPane treePane = new JScrollPane(env);
        JTextArea area = new JTextArea("Some contents");
        contentPane.add(treePane);
        contentPane.add(area);        
        setLayout(new BorderLayout());
        add(contentPane);
        setSize(800, 600);

        SpringLayout.Constraints  cons;
        cons = layout.getConstraints(treePane);
        cons.setX(Spring.constant(0));
        cons.setY(Spring.constant(0));
        cons.setWidth(Spring.scale(layout.getConstraint(SpringLayout.EAST, contentPane), .7f));
        cons.setHeight(layout.getConstraint(SpringLayout.SOUTH, contentPane));

        cons = layout.getConstraints(area);
        cons.setX(layout.getConstraint(SpringLayout.EAST, treePane));
        cons.setY(Spring.constant(0));
        cons.setWidth(Spring.scale(layout.getConstraint(SpringLayout.EAST, contentPane), .3f));
        cons.setHeight(layout.getConstraint(SpringLayout.SOUTH, contentPane));
        setPreferredSize(getSize());
        setLocationRelativeTo(null);
        pack();
        setVisible(true);
    }

    private JTree getEnvironmentTree() {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
        JTree tree = new JTree(root);
        DefaultMutableTreeNode one = new DefaultMutableTreeNode("One");
        root.add(one);
        one.add(new DefaultMutableTreeNode("under one.1"));
        one.add(new DefaultMutableTreeNode("under one.2"));
        root.add(new DefaultMutableTreeNode("two"));
        root.add(new DefaultMutableTreeNode("three"));
        return tree;
    }

    public static void main(String[] args) {
        new TestFrame();
    }
}
KitsuneYMG