1

I'm trying to get two components,

    frame.getContentPane().setLayout(new MigLayout("", "[53px,grow][57px][grow]", "[23px][][][]"));

    JTextPane itemTitle = new JTextPane();
    frame.getContentPane().add(itemTitle,"cell 0 4,alignx left,aligny top");
    itemTitle.setVisible(true);
    itemTitle.setMinimumSize(new Dimension(50, 50));

    List choices = new List();
    frame.add(choices, "cell 0 4,alignx left,aligny top");
    choices.setVisible(true);

to be in the same place, but all the happens is this:

https://i.imgur.com/0O9A8tk.png

The two components highlighted at itemTitle and choices. My aim is to have the buttons above set one "setVisible" to true and the other to false. They would never both be true. How can I get two components in one cell at the same time? It also puts my above buttons out of place and I'm not too sure why. I put above the important code referring to the two components, I could put the full GUI code if you requested.

I found this: Fill Entire Cell With Two Components Using MigLayout However it is over years old and to be honest, I don't understand the solution. I'm sort of learning as I go, I've never used MigLayout before. Should I be using a different layout?

Thanks for any help

camickr
  • 321,443
  • 19
  • 166
  • 288

2 Answers2

0

to be in the same place... My aim is to have the buttons above set one "setVisible" to true and the other to false. They would never both be true

Then you should be using a JPanel that contains those two components. Then you use a Card Layout on that panel and use the CardLayout to determine which component is visible at any given time. This panel can be added to the panel using the MigLayout just like any other component.

List choices = new List();

Looks to me like you are using an AWT component. You should be using JList for a Swing application.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • Just out of interest, what's wrong with mixing AWT and Swing? Is it bad practice, or could it potentially get confusing with more advanced applications as I'd assume they have different methods/features? – UraniumFirecracker Aug 18 '14 at 21:49
0

Should I be using a different layout?

No, stick with MigLayout. You have chosen the right layout manager. I advice you to invest some time into learning this manager; create couple of smaller practical examples, learn the numerous constraints that this manager provides.

It also puts my above buttons out of place and I'm not too sure why.

MigLayout is a grid-based layout manager. (Its most important mode is.) The gap between the New and Open buttons is created because the highlighted components and the New button form a column. The column width is determined by the width of the largest cell. To bypass this, we can use the split constraint. (Often used in combination with span constraint.) In my example I use this technique to center two buttons above the currently visible label. If we are not sure about something in the layout, we can use the debug layout constraint which paints the lines of the grid and bounds of the components.

frame.getContentPane().setLayout(new MigLayout("", "[53px,grow][57px][grow]", "[23px][][][]"));

Do not set bounds in pixels. You are not utilizing of one of the most important advantages of this manager -- independence of resolution and DPI. Bounds in pixels are not portable. A 3px gap between buttons looks OK on a smaller screen but is not acceptable on a larger one. MigLayout provides several options to choose from including related and unrelated gaps, logical pixels, points, or centimeters.

itemTitle.setMinimumSize(new Dimension(50, 50));

Setting a minimum size of a component is usually not necessary. But if we need to do it, we have the wmin and wmax constraints. This should be done by the layout manager, not by code outside of it. The set(Minimum|Maximum|Preferred)size methods should be avoided. (With poorer managers, one cannot do without them, however.) And again, setting dimensions in pixels is not optimal.

Now we get to the solution. MigLayout has hidemode constraint to deal with your requirement. There are four hide modes. I assume that we need the hidemode 3, in which all invisible components do not participate in the layout.

package com.zetcode;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;


public class HidingComponentsEx extends JFrame {

    private ArrayList<JLabel> lbls;
    private int itemVisible = 0;

    public HidingComponentsEx() {

        initUI();
    }

    private void initUI() {

        createLabels();

        JButton prevBtn = new JButton("Previous");
        prevBtn.addActionListener(new PrevAction()); 

        JButton nextBtn = new JButton("Next");
        nextBtn.addActionListener(new NextAction());        

        JPanel pnl = new JPanel(new MigLayout("ins dialog"));

        pnl.add(prevBtn, "split 2, center");
        pnl.add(nextBtn, "wrap");

        for (JLabel lbl : lbls) {
            pnl.add(lbl, "cell 0 1, w 250lp, h 100lp, hidemode 3");
        }

        add(pnl);
        pack();

        setTitle("MigLayout example");
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        
    }

    private void createLabels() {

        lbls = new ArrayList<>();
        lbls.add(createLabel("North Sea"));
        lbls.add(createLabel("Ionian Sea"));
        lbls.add(createLabel("Norwegian Sea"));
        lbls.add(createLabel("Bering Sea"));
        lbls.add(createLabel("Dead Sea"));  
        lbls.get(itemVisible).setVisible(true);
    }

    private class NextAction extends AbstractAction {

        @Override
        public void actionPerformed(ActionEvent e) {

            lbls.get(itemVisible).setVisible(false);
            itemVisible++;

            if (itemVisible > 4) {
                itemVisible = 0;
            }

            lbls.get(itemVisible).setVisible(true);
        }
    }

    private class PrevAction extends AbstractAction {

        @Override
        public void actionPerformed(ActionEvent e) {

            lbls.get(itemVisible).setVisible(false);
            itemVisible--;

            if (itemVisible < 0) {
                itemVisible = 4;
            }

            lbls.get(itemVisible).setVisible(true);
        }
    }    

    private JLabel createLabel(String text) {

        JLabel lbl = new JLabel(text, JLabel.CENTER);
        lbl.setVisible(false);
        lbl.setBorder(BorderFactory.createEtchedBorder());

        return lbl;
    }


    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                HidingComponentsEx ex = new HidingComponentsEx();
                ex.setVisible(true);
            }
        });       
    }
}

Our example has two buttons and five labels. The buttons dynamically change their visibility.

MigLayout example

Jan Bodnar
  • 10,969
  • 6
  • 68
  • 77