-1

I am trying to create a JFrame with bunch of Jbuttons on it,. 40 in the middle, in rows of 4, and 6 Jbuttons in a vertical line going down the left side. The problem is, the fifth Jbutton down the side buttons appears behind all the others, and takes up the entire window. I ave no idea where this comes from, because I never set JButton's size to be that big, or to fit the screen.

import javax.swing.*;
public class Buttons {

static JButton[][] middle = new JButton [10][4]; //middle buttons
static JButton[] colours = new JButton[6]; //colour buttons


public static void main (String arg[]) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(600,700);

    int xcor = 100; //x coordinate
    int ycor = 5; //y coordinate

    //middle buttons
    for (int y = 0; y<10; y++) {
        for (int x = 0; x<4; x++) {
            middle[y][x] = new JButton();
            middle[y][x].setBounds(xcor, ycor, 100, 60);
            middle[y][x].setVisible(true);
            frame.getContentPane().add(middle[y][x]);

            xcor+=100;
        }
        xcor=100;
        ycor+=60;
    }

    //colour buttons 
    ycor=65;
    for (int y = 0; y<5; y++){
        colours[y] = new JButton();
        colours[y].setBounds(5, ycor, 90, 60);

        switch (y) {
        case 0: colours[y].setText("Red");
        break;
        case 1: colours[y].setText("Blue");
        break;
        case 2: colours[y].setText("Green");
        break;
        case 3: colours[y].setText("Yellow");
        break;
        case 4: colours[y].setText("Purple");
        break;
        case 5: colours[y].setText("Black");
        break;
        }
        colours[y].setVisible(true);
        frame.getContentPane().add(colours[y]);

        ycor += 60;
    }
    frame.setVisible(true);
}

enter image description here

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • You do realise that the frame is using a `BorderLayout` by default? – MadProgrammer Jan 13 '14 at 22:51
  • No. Pardon my ignorance, I'm a new programmer, what does that do? – user3192075 Jan 13 '14 at 22:54
  • I set the layout to null and that solved the problem. Thank you :) – user3192075 Jan 13 '14 at 23:00
  • 2
    *"I set the layout to null and that solved the problem."* Congratulations. You've just exchanged one small problem for at least 5 large ones. Java GUIs might have to work on a number of platforms, on different screen resolutions & using different PLAFs. As such they are not conducive to exact placement of components. To organize the components for a robust GUI, instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556), along with layout padding & borders for [white space](http://stackoverflow.com/q/17874717/418556). – Andrew Thompson Jan 13 '14 at 23:06
  • `colours[y].setText("Red");` ..this might be better suited to a `JColorChooser`. See [How to Use Color Choosers](http://docs.oracle.com/javase/tutorial/uiswing/components/colorchooser.html) for details. – Andrew Thompson Jan 13 '14 at 23:08

2 Answers2

3

This layout can be achieved by using two instances of GridLayout (the one on the left would be a single column grid layout, while the right could be a GridLayout(0,4)) each in a JPanel. Those two panels might then have an EmptyBorder set, and be added to the LINE_START and CENTER of a BorderLayout.

Like this:

enter image description here

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.*;

public class Buttons {

    private JButton[][] middle = new JButton[10][4]; //middle buttons
    private JButton[] colours = new JButton[6]; //colour buttons

    Buttons() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // unnecessary, just lay it out and call pack()!
        //frame.setSize(600, 700);

        Insets zeroMargin = new Insets(0, 0, 0, 0);
        BufferedImage bi = new BufferedImage(
                50, 30, BufferedImage.TYPE_INT_ARGB);

        JPanel middlePanel = new JPanel(new GridLayout(0, 4));
        middlePanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        frame.add(middlePanel, BorderLayout.CENTER);

        //middle buttons
        for (int y = 0; y < 10; y++) {
            for (int x = 0; x < 4; x++) {
                JButton b = new JButton();
                middle[y][x] = b;
                b.setMargin(zeroMargin);
                b.setIcon(new ImageIcon(bi));
                middlePanel.add(b);
            }
        }

        JPanel colorButtons = new JPanel(new GridLayout(0, 1));
        JPanel colorButtonsConstrain = new JPanel(new FlowLayout());
        colorButtons.setBorder(new EmptyBorder(65, 5, 5, 0));
        colorButtonsConstrain.add(colorButtons);
        frame.add(colorButtonsConstrain, BorderLayout.LINE_START);
        Color[] colors = {
            Color.RED, Color.BLUE, Color.GREEN,
            Color.YELLOW, Color.MAGENTA.darker(), Color.BLACK
        };
        // colour buttons
        for (int y = 0; y < colors.length; y++) {
            JButton b = new JButton();
            b.setMargin(zeroMargin);
            b.setIcon(new ImageIcon(bi));
            colours[y] = b;
            b.setBackground(colors[y]);
            colorButtons.add(b);
        }

        frame.pack();
        frame.setMinimumSize(frame.getSize());
        frame.setVisible(true);
    }

    public static void main(String arg[]) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                new Buttons();
            }
        };
        SwingUtilities.invokeLater(r);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
0

Setting the layout to null (frame.setLayout(null);) can solve this specific problem, but will introduce more problems. Making a custom LayoutManager would be a better solution.

The Guy with The Hat
  • 10,836
  • 8
  • 57
  • 75
  • 1
    *"..Making a custom `LayoutManager` would be a better solution."* Better yes, but unnecessary. See the image. It can be achieved by using two instances of `GridLayout` (the one on the left would be a single column grid layout, while the right could be a `GridLayout(0,4)`) each in a `JPanel`. Those two panels might then have an `EmptyBorder` set, and be added to the `LINE_START` and `CENTER` of a `BorderLayout`. – Andrew Thompson Jan 13 '14 at 23:16
  • E.G. as seen in my answer. – Andrew Thompson Jan 13 '14 at 23:53