Reputation: 21
This is the picture I am trying to replicate
This is what I have (didn't add icon images yet)
I can't seem to find a solution, been staring at it for quite some time.
I am trying to replicate the following picture, using GridLayout
for the buttons and the figure out the rest on my own using Java Swing. Furthermore, I've added my buttons into a JPanel
and now I'm trying to add spacing between the panel and the pane.
This is what I have, how can I go about it?
super(title);
this.setLayout(new BoxLayout(this.getContentPane(), BoxLayout.PAGE_AXIS));
Container pane = this.getContentPane();
JButton b1 = new JButton();
b1.setBackground(Color.white);
JButton b2 = new JButton();
b2.setBackground(Color.white);
JButton b3 = new JButton();
b3.setBackground(Color.white);
JButton b4 = new JButton();
b4.setBackground(Color.white);
JButton b5 = new JButton();
b5.setBackground(Color.white);
JButton b6 = new JButton();
b6.setBackground(Color.white);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(2,3,10,10));
panel.setBackground(Color.black);
panel.add(b1);
panel.add(b2);
panel.add(b3);
panel.add(b4);
panel.add(b5);
panel.add(b6);
pane.add(panel);
this.setSize(500,500);
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
Upvotes: 2
Views: 1565
Reputation: 51559
Here's a little demonstration I whipped up.
All Swing applications must start with a call to the SwingUtilities
invokeLater
method. This method ensures that all Swing components are created and executed on the Event Dispatch Thread.
You don't set the size of the JFrame
and try and make the Swing components fit. You let the JFrame
pack with all the Swing components.
You create a GridLayout
JPanel
inside of a FlowLayout
JPanel
. The FlowLayout
JPanel
uses an empty border of the appropriate size.
I used the image the OP provided to get the icons.
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class EmptySpaceDemo implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new EmptySpaceDemo());
}
private Image[] images;
public EmptySpaceDemo() {
this.images = createImages();
}
private Image[] createImages() {
BufferedImage image = readImage();
Image[] images = new Image[6];
images[0] = image.getSubimage(155, 113, 110, 90);
images[1] = image.getSubimage(276, 113, 110, 90);
images[2] = image.getSubimage(155, 217, 110, 90);
images[3] = image.getSubimage(276, 217, 110, 90);
images[4] = image.getSubimage(155, 321, 110, 90);
images[5] = image.getSubimage(276, 321, 110, 90);
return images;
}
@Override
public void run() {
JFrame frame = new JFrame("Empty Space Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new FlowLayout());
panel.setBackground(Color.BLACK);
panel.setBorder(BorderFactory.createEmptyBorder(40, 100, 40, 100));
JPanel innerPanel = new JPanel(new GridLayout(0, 2, 10, 10));
innerPanel.setBackground(Color.BLACK);
for (int i = 0; i < images.length; i++) {
JButton button = new JButton(new ImageIcon(images[i]));
innerPanel.add(button);
}
panel.add(innerPanel);
return panel;
}
private BufferedImage readImage() {
try {
return ImageIO.read(getClass().getResourceAsStream("/icons.png"));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Upvotes: 2
Reputation: 388
The easiest way to do it would be to add an empty border to your JPanel (see this post on empty borders):
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3, 2, 10, 10));
// ...
panel.setBorder(new EmptyBorder(50, 50, 50, 50));
Another good approach (depending always on your application needs), if you have the JButton preferred size set, would be to have the main JPanel's grid layout set to have two columns and one row, with another JPanel inside each column. Adding to the interior JPanels a BoxLayout in Y_AXIS mode and aligning the buttons with setAlignmentX() would work great too (note this approach wouldn't center the JButtons vertically) (see How to use BoxLayout):
public class MyFrame extends JFrame {
private String title = "Title";
public MyFrame(){
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridLayout(1,2,10,10));
JPanel rightPanel = new JPanel();
rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.Y_AXIS));
JPanel leftPanel = new JPanel();
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS));
mainPanel.add(leftPanel);
mainPanel.add(rightPanel);
JButton b1 = new JButton();
b1.setBackground(Color.white);
//b1.setIcon(new ImageIcon(img1));
b1.setAlignmentX(Component.RIGHT_ALIGNMENT);
leftPanel.add(b1);
JButton b2 = new JButton();
b2.setBackground(Color.white);
//b2.setIcon(new ImageIcon(img2));
b2.setAlignmentX(Component.RIGHT_ALIGNMENT);
leftPanel.add(b2);
JButton b3 = new JButton();
b3.setBackground(Color.white);
//b3.setIcon(new ImageIcon(img3));
b3.setAlignmentX(Component.RIGHT_ALIGNMENT);
leftPanel.add(b3);
JButton b4 = new JButton();
b4.setBackground(Color.white);
//b4.setIcon(new ImageIcon(img4));
b4.setAlignmentX(Component.LEFT_ALIGNMENT);
rightPanel.add(b4);
JButton b5 = new JButton();
b5.setBackground(Color.white);
//b5.setIcon(new ImageIcon(img5));
b5.setAlignmentX(Component.LEFT_ALIGNMENT);
rightPanel.add(b5);
JButton b6 = new JButton();
b6.setBackground(Color.white);
//b6.setIcon(new ImageIcon(img6));
b6.setAlignmentX(Component.LEFT_ALIGNMENT);
rightPanel.add(b6);
add(mainPanel); //Adding our mainPanel to the contentPane of the JFrame
this.setSize(500,500); //or pack();
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setTitle(title);
this.setVisible(true);
}
}
Upvotes: 2