3

I am building a simple GUI for a course assignment, but I am not getting the most out of it.

So this is my objective:

And I am getting this (it lacks of some elements like the button):

So the thing is, how do I code my layout to be tighter like in the goal pic?

Code below:

public class Panel1 extends JPanel{

    private JButton cancel = new JButton("Cancel");

    private JTextArea xTwin = new JTextArea(10, 30);
    private JTextArea xCousin = new JTextArea(10, 30);
    private JTextArea xSexy = new JTextArea(10, 30);
    private JTextField getT = new JTextField(5);
    private JTextField getC= new JTextField(5);
    private JTextField getS = new JTextField(5);

    private JLabel cnstT = new JLabel("How many twin primes do you want?");
    private JLabel cnstC = new JLabel("How many cousin primes do you want?");
    private JLabel cnstS = new JLabel("How many sexy primes do you want?");
    private JLabel msgTwin = new JLabel("Area primes 'twin' created");
    private JLabel msgCousin = new JLabel("Area primes 'cousin' created");
    private JLabel msgSexy = new JLabel("Area primes 'sexy' created");  
    private JLabel msgGUI = new JLabel("GUI created");

    public Panel1(){
        xTwin.setEditable(false);
        xCousin.setEditable(false);
        xSexy.setEditable(false);

        this.setLayout(new GridLayout(3, 1));
        JPanel p1 = new JPanel();
        JPanel p2 = new JPanel();
        JPanel p3 = new JPanel();

        p1.setLayout(new FlowLayout());
        p2.setLayout(new FlowLayout());
        p3.setLayout(new FlowLayout());

        p1.add(cnstT); p1.add(getT); p1.add(cnstC); p1.add(getC);
        p1.add(cnstS); p1.add(getS);
        p2.add(xTwin); p2.add(xCousin); p2.add(xSexy);
        p3.add(msgTwin); p3.add(msgCousin); p3.add(msgSexy);

        add(p1); add(p2); add(p3);
    }
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
fant0me
  • 201
  • 1
  • 3
  • 15
  • 2
    For the 3 panels in the middle you might create a factory method that accepts a `String` (the type of randoms) & potentially other things, like a `SpinnerNumberModel` - and returns a panel. Put those 3 panels in a single row `GridLayout`. Put that panel in the center of a `BorderLayout`. Add a panel to the `PAGE_START` with a `FlowLayout` for the button. Add a `JLabel` to the `PAGE_END` for the `GUI created` message. For more help, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/) of your best attempt at implementing that approach. – Andrew Thompson Jun 17 '16 at 12:08
  • 1
    @AndrewThompson is correct; the [example](http://stackoverflow.com/a/37885601/230513) below combines the factory and strategy patterns. – trashgod Jun 17 '16 at 15:57

3 Answers3

3

The below code should help you to progress.

        public Panel1(){
            xTwin.setEditable(false);
            xCousin.setEditable(false);
            xSexy.setEditable(false);

            xTwin.setBorder(new LineBorder(Color.red));
            xCousin.setBorder(new LineBorder(Color.green));
            xSexy.setBorder(new LineBorder(Color.blue));

            this.setLayout(new BorderLayout());
            JPanel panel = new JPanel(new GridLayout(1, 3));
            JPanel buttonPane = new JPanel(new FlowLayout());
            buttonPane.add(cancel);
            this.add(buttonPane,BorderLayout.NORTH);
            this.add(panel,BorderLayout.CENTER);



            JPanel p1 = new JPanel();
            JPanel p2 = new JPanel();
            JPanel p3 = new JPanel();

            p1.setLayout(new BorderLayout());
            p2.setLayout(new BorderLayout());
            p3.setLayout(new BorderLayout());

            JPanel twinPanel = new JPanel(new FlowLayout()); 
            twinPanel.add(cnstT);
            twinPanel.add(getT);
            p1.add(twinPanel, BorderLayout.NORTH);
            p1.add(xTwin, BorderLayout.CENTER);
            p1.add(msgTwin, BorderLayout.SOUTH);

            JPanel cousinPanel = new JPanel(new FlowLayout()); 


            cousinPanel.add(cnstC);
            cousinPanel.add(getC);
            p2.add(cousinPanel, BorderLayout.NORTH);
            p2.add(xCousin, BorderLayout.CENTER);
            p2.add(msgCousin, BorderLayout.SOUTH);


            JPanel sexyPanel = new JPanel(new FlowLayout()); 
            sexyPanel.add(cnstS);
            sexyPanel.add(getS);
            p3.add(sexyPanel, BorderLayout.NORTH);
            p3.add(xSexy, BorderLayout.CENTER);
            p3.add(msgSexy, BorderLayout.SOUTH);
            panel.add(p1);
            panel.add(p2);
            panel.add(p3);
        }

And this was the result.(Sorry about the borders)

enter image description here

Beniton Fernando
  • 1,533
  • 1
  • 14
  • 21
  • Thanks a lot for the code! It's been a quite useful guide on how to use the different Java layouts. I was certainly lost about using the GridLayout and BorderLayout. – fant0me Jun 19 '16 at 08:54
2

Because the the panels differ only in name and function, use the strategy pattern, seen here, to select the desired behavior at runtime. The example below illustrates an enum, each instance of which holds a display name and a function that takes an integer and returns a pair or integers: Function<Integer, Pair<Integer, Integer>>. The actual functions used are placeholders; you can substitute one of the approaches seen here.

image

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.util.function.Function;
import javafx.util.Pair;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.event.ChangeEvent;

/**
 * @see https://stackoverflow.com/a/37885601/230513
 */
public class StrategyTest {

    private enum Kind {
        TWIN((new Function<Integer, Pair<Integer, Integer>>() {
            @Override
            public Pair<Integer, Integer> apply(Integer i) {
                return new Pair<>(i, i + 2);
            }
        })),
        COUSIN((new Function<Integer, Pair<Integer, Integer>>() {
            @Override
            public Pair<Integer, Integer> apply(Integer i) {
                return new Pair<>(i, i + 4);
            }
        })),
        SEXY((new Function<Integer, Pair<Integer, Integer>>() {
            @Override
            public Pair<Integer, Integer> apply(Integer i) {
                return new Pair<>(i, i + 6);
            }
        }));
        String dsiplayName;
        Function<Integer, Pair<Integer, Integer>> function;

        private Kind(Function<Integer, Pair<Integer, Integer>> function) {
            this.dsiplayName = name().toLowerCase();
            this.function = function;
        }
    }

    private JPanel createPanel(Kind kind) {
        JPanel panel = new JPanel(new BorderLayout());
        JSpinner spinner = new JSpinner();
        JPanel top = new JPanel();
        top.add(new JLabel("How many " + kind.dsiplayName + " primes?"));
        top.add(spinner);
        panel.add(top, BorderLayout.PAGE_START);
        JTextArea textArea = new JTextArea(16, 20);
        panel.add(new JScrollPane(textArea));
        panel.add(new JLabel("Area for " + kind.dsiplayName + " primes.",
            JLabel.CENTER), BorderLayout.PAGE_END);
        spinner.addChangeListener((ChangeEvent e) -> {
            int i = (int) spinner.getValue();
            Pair<Integer, Integer> p = kind.function.apply(i);
            textArea.append(p.getKey() + ":" + p.getValue() + "\n");
        });
        return panel;
    }

    private void display() {
        JFrame f = new JFrame("StrategyTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLayout(new GridLayout(1, 0, 5, 5));
        for (Kind kind : Kind.values()) {
            f.add(createPanel(kind));
        }
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new StrategyTest()::display);
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Wow @trashgod, that's a quite easy-to-use and straightforward layout configuration than the typical one. Even I'm not yet in the loop about SW design patterns it's very interesting to see it applied! – fant0me Jun 19 '16 at 09:16
  • @flamenquino: As you pursue your studies, keep this pattern in mind when asked to compare two (or more) algorithms. – trashgod Jun 19 '16 at 15:39
1

Your problem is located in the following line of code

this.setLayout(new GridLayout(3, 1));

The GridLayout is meant to divide the GUI into regions of the same size, which means, the embedded components do not have their natural size e.g. being stretched...

Use a different Layoutmanager instead! There are sevaral variants fitting to your needs...

For further information about the Layoutmanagers and their intended functionality, visit this website

PrR3
  • 1,250
  • 1
  • 18
  • 26
  • Yes, I did not have a clear concept about how the Java layouts distribute the components. Thanks a lot! – fant0me Jun 19 '16 at 08:56