简体   繁体   中英

How to automatically organize and resize a JFrame according to content in Java swing application

I am planning to create an application that requires the user to input data in several fields, however some of the fields may not always be used. The guy for whom I will develop this program wants to be able to select every time which of the fields he is going to use. I thought of the following (but I am not really sure how to do it):

First, display a list of all the fields available and a checkbox to select each of them. Then, having a JFrame with all of the fields ready, and based in the user's choice, lay out the form suppressing the unused fields and removing any gap that may appear. (I thought about using setvisible() for the components of the frame and then finding a way to eliminate gaps between them that would appear when hiding the elements that won't be needed). But I don't think this is the most effective way to do it. There is no need to say the frame should look well organized and esthetic. I am open to suggestions, and thank you in advance.

I will be using netbeans design mode for this, if it makes any difference.

http://docs.oracle.com/javase/6/docs/api/java/awt/Window.html#pack ()

JFrame has a pack() method that will resize the window to fit its contents.

As always with layout requirements, the task is to find a suitable LayoutManager and then let it do its work: which is to figure out how to distribute the available space depending on component visibility. With that, your job boils down to toggle the visibility and lean back.

Most core managers simply ignore hidden components (which may or may not be what you want). Advanced managers can be configured full range - from handle exactly the same way as visible components to ignore. Fi MigLayout (my personal favorite at the moment), has a hidemode with 4 levels (same way, size component to 0,0, size components to 0,0 and zero all gaps around, ignore completely)

Below is a quick example to play with: try different permutations of hidemode with hiding the label for the textfield along with the textField to see the different behaviour.

// hidemode 3 == ignore in layout
// hidemode 2 == zero size and zero gaps
// hidemode 1 == zero size
// hidemode 0 == same as visible
MigLayout layout = new MigLayout("wrap 2, hidemode 3");
JComponent content = new JPanel(layout);
JPopupMenu popup = new JPopupMenu();
for (int i = 0; i < 5; i++) {
    JTextField field = new JTextField("field " + i, 20);
    field.setName(field.getText());
    JLabel label = new JLabel("Label " + i);
    label.setLabelFor(field);
    content.add(label);
    content.add(field);
    popup.add(new JCheckBoxMenuItem(new ToggleVisibilityAction(field, true)));
}
content.setComponentPopupMenu(popup);

// action to toggle the visibility of a target component
// optionally w/out its label
public static class ToggleVisibilityAction extends AbstractAction {

    private JComponent target;
    private boolean hideLabel;

    public ToggleVisibilityAction(JComponent comp, boolean hideLabel) {
        super(comp.getName());
        this.target = comp;
        this.hideLabel = hideLabel;
        putValue(SELECTED_KEY, target.isVisible());
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        boolean visible = (boolean) getValue(SELECTED_KEY);
        target.setVisible(visible);
        if (hideLabel && target.getClientProperty("labeledBy") instanceof JComponent) {
            ((Component) target.getClientProperty("labeledBy")).setVisible(visible);
        }
        target.getParent().revalidate();
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM