JPanels: the <div>s of the Java world? - java

Can JPanels be used in Java like <div>s get used in HTML? Is it ever consistent with good practice to have more than 1 JPanel in a JFrame for something other than CardLayout? (For example, if I had JPanel that contained a help/about button that was on the northern border of the content panel of the JFrame, and I used the one that contained the button to put some spacing in to force the button to be of a certain size...)
Specific case:
Suppose I am trying to make this: , and upon starting, I have a mock like this (thanks to some code for the button rendering I found elsewhere): . Would this case be good case to use multiple JFrames (like one would those HTML <div>s)? If not, when would be?

Based on your requirements, you don't "have" to use multiple panels, you can accomplish what you want from a single panel and a GridBagLayout, for example...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JButton helpButton = new JButton("?");
JTextField projectDirectory = new JTextField(20);
JTextField documentDirectory = new JTextField(20);
JButton projectButton = new JButton("Project");
JButton documentButton = new JButton("Document");
JButton continueButton = new JButton("Continue to files");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 1;
add(new JLabel("Project Directory"), gbc);
gbc.gridy++;
add(new JLabel("Documentation Directory"), gbc);
gbc.gridx = 1;
gbc.gridy = 1;
add(projectDirectory, gbc);
gbc.gridy++;
add(documentDirectory, gbc);
gbc.gridx = 2;
gbc.gridy = 0;
add(helpButton, gbc);
gbc.gridy++;
add(projectButton, gbc);
gbc.gridy++;
add(documentButton, gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(continueButton, gbc);
}
}
}
The main reasons I would use multiple panels is:
The layout was overly complex, it would allow me to break down the layout into individual requirements and focus more on the relationship between the groups
If I was focusing on separating the management into individual elements (such as the directory selection for example), where the panel could become a self contained unit of work, including the management and functionality, allowing to be a self contained and re-usable component
Compound Panels...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JButton helpButton = new JButton("?");
JButton continueButton = new JButton("Continue to files");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.EAST;
add(helpButton, gbc);
gbc.gridy++;
add(new FolderSelectionPane("Project Folder"), gbc);
gbc.gridy++;
add(new FolderSelectionPane("Documentation Folder"), gbc);
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridy++;
add(continueButton, gbc);
}
}
public class FolderSelectionPane extends JPanel {
public FolderSelectionPane(String label) {
JTextField projectDirectory = new JTextField(20);
JButton projectButton = new JButton("Folder");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(0, 2, 0, 2);
add(new JLabel(label), gbc);
gbc.gridx++;
add(projectDirectory, gbc);
gbc.gridx++;
add(projectButton, gbc);
}
}
}

Related

Align label and combo box in vertical instead of horizontal in java

How do I get my label and combo box to appear vertical instead of horizontal in java? I tried setting the layout to null but it hides the label.
public PetrolApplication()
{
setLayout(new FlowLayout());
add(label);
add(label2);
Combo1 = new JComboBox(Arraycities);
Combo1.setBounds(50, 50, 100, 20);
Use a different layout manager - see A Visual Guide to Layout Managers
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setBorder(new EmptyBorder(16, 16, 16, 16));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(4, 4, 4, 4);
gbc.anchor = GridBagConstraints.LINE_START;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add( new JLabel("I'm assuming you want something"), gbc);
gbc.anchor = GridBagConstraints.LINE_END;
gbc.gridy = 1;
gbc.gridwidth = 1;
add(new JLabel("Please make a selection"), gbc);
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<String>();
model.addElement("This is not what you are looking for");
model.addElement("This is something else");
model.addElement("Not what you think");
gbc.anchor = GridBagConstraints.LINE_START;
gbc.gridx++;
add(new JComboBox<String>(model));
}
}
}

In Java, is there a way to center a group of buttons with variable size(Using Swing)?

I've been trying to make a GUI like this:
However, the difficult I've run into is that I need to make the text of the buttons variable- each button should present a different option, which can vary in text length. While this itself is not difficult, I've tried countless different things but I can't get the buttons to center despite their text length. Whatever I try, I always have one of these problems:
The buttons don't center (there's space left at the left but they exceed the window at the right)
For some reason, the Question and the Goodratio change location based on the button size
I have no clue left how to do this. Does anyone have some useful intuitions on what's the best way to do this? It would be much appreciated.
EDIT: Code of the constructor function(which doesn't center correctly), which I use to set the components, as requested:
public ButtonPannel(Test test)
{
super();
op1Button = new JButton("Option 1");
op2Button = new JButton("Option 2");
op3Button = new JButton("Option 3");
questionText = new JLabel("Question");
rightAndWrongAmount = new JLabel("rightAndWrongAmount");
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[]{30, 331, 0};
gridBagLayout.rowHeights = new int[]{16, 0, 134, 35, 16, 0};
gridBagLayout.columnWeights = new double[]{0.0, 0.0, Double.MIN_VALUE};
gridBagLayout.rowWeights = new double[]{0.0, 0.0, 1.0, 0.0, 0.0, Double.MIN_VALUE};
setLayout(gridBagLayout);
JPanel panel = new JPanel();
FlowLayout flowLayout = (FlowLayout) panel.getLayout();
op1Button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
GridBagConstraints gbc_lblQuestion = new GridBagConstraints();
gbc_lblQuestion.insets = new Insets(0, 0, 5, 0);
gbc_lblQuestion.gridx = 1;
gbc_lblQuestion.gridy = 1;
add(questionText, gbc_lblQuestion);
panel.add(op1Button);
panel.add(op2Button);
panel.add(op3Button);
GridBagConstraints gbc_panel = new GridBagConstraints();
gbc_panel.insets = new Insets(0, 0, 5, 0);
gbc_panel.gridx = 1;
gbc_panel.gridy = 3;
add(panel, gbc_panel);
GridBagConstraints gbc_lblNewLabel_1 = new GridBagConstraints();
gbc_lblNewLabel_1.gridx = 1;
gbc_lblNewLabel_1.gridy = 4;
add(rightAndWrongAmount, gbc_lblNewLabel_1);
op1Button.addActionListener(new InputHandler(test));
op1Button.setActionCommand("1");
op2Button.addActionListener(new InputHandler(test));
op2Button.setActionCommand("2");
op3Button.addActionListener(new InputHandler(test));
op3Button.setActionCommand("3");
}
The code is generated using WindowBuilder. The problem isn't so much in the code, but more which Layout to use etc.
Layouts are a little bit of black magic and trial and error. Very rarely will a single layout achieve exactly what you want, so you often need to resort to compound layouts (using multiple containers and layouts) to get what you want...
So, basically, this is made of a panel, with another panel holding the buttons (and another panel acting as the "pseudo" content to add space)
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel("Question"), gbc);
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
// This is just to act as some psudo context
add(new FillerPane(), gbc);
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
gbc.weighty = 0;
add(makeButtonPane(), gbc);
add(new JLabel("Goodratio"), gbc);
}
public JPanel makeButtonPane() {
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
panel.add(new JButton("Short"));
panel.add(new JButton("Long, long, long and lobng"));
panel.add(new JButton("In the middle"));
return panel;
}
}
public class FillerPane extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
"But I want the buttons to be the same size" I hear you ask, sure, change layouts...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel("Question"), gbc);
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
// This is just to act as some psudo context
add(new FillerPane(), gbc);
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
gbc.weighty = 0;
add(makeButtonPane(), gbc);
add(new JLabel("Goodratio"), gbc);
}
public JPanel makeButtonPane() {
JPanel panel = new JPanel(new GridLayout(1, 0));
panel.add(new JButton("Short"));
panel.add(new JButton("Long, long, long and lobng"));
panel.add(new JButton("In the middle"));
return panel;
}
}
public class FillerPane extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
You have to look at the layout and think about how each element relates to the others, in terms of what you want them to do, then find the layout managers which are going to help you achieve the end results and combine them together

GridBagLayout Not Working Properly?

I am using a GridBagLayout for my components in a JFrame. I just started using it, and I keep confusing myself. What I want is; Patch notes in the top left, buttons (vertical) on the right, play button on the bottom. I'm not sure what the issue really is, but can you please help me organize this?
Here's my code:
package counter.main;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
public class HomeFrame {
private static JPanel panel;
private static JButton play = new JButton("Play");
private static JPanel p;
File patch = new File(Main.class.getResource("/counter/res/ResourceCounterPatchNotes.txt").getFile());
//private static JLabel text;
public static JLabel greet = new JLabel("", SwingConstants.CENTER);
static JFrame frame = new JFrame("Resource Counter - Home"); {
frame.setSize(800, 500);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.repaint();
frame.revalidate();
createView();
}
private void createView() {
setIcon();
panel = new JPanel();
frame.getContentPane().add(panel);
p = new JPanel();
frame.getContentPane().add(p);
p.setLayout(new FlowLayout(FlowLayout.CENTER, 400, 360));
play.setPreferredSize(new Dimension(200, 70));
p.add(play);
JPanel p2 = new JPanel();
frame.getContentPane().add(p2);
p2.setLayout(new GridBagLayout());
JButton button = new JButton(" Button ");
play.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
Thread.sleep(500);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
SelectionFrame.frame1.setVisible(true);
frame.setVisible(false);
}
});
JTextArea ta = new JTextArea();
p2.setBackground(Color.BLACK);
ta.setForeground(Color.WHITE);
ta.setFont(new Font("Lucida Sans", Font.PLAIN, 12));
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.insets = new Insets(-150, 5, 5, 30);
gbc.gridx = 0;
gbc.gridy = 0;
p2.add(ta, gbc);
gbc.gridx = 1;
gbc.gridy = 0;
p2.add(button, gbc);
/*gbc.anchor = GridBagConstraints.SOUTH;
gbc.gridx = 0;
gbc.gridy = 2;
p2.add(play, gbc);*/
try {
ta.read(new FileReader(patch), null);
ta.setEditable(false);
//p2.add(ta, BorderLayout.WEST);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
greet.setFont(new Font( "Dialog", Font.BOLD, 20));
frame.getContentPane().add(greet, BorderLayout.NORTH);
}
public void setIcon() {
frame.setIconImage(Toolkit.getDefaultToolkit().getImage(Main.class.getResource("/counter/res/Iron-Pickaxe-icon.png")));
}
}
Here is what I get:
Your code is a mess (sorry), I could spent a lot of time trying to unravel your compound layouts, but it would be easier to just start again. Not saying that you might not consider using a compound layout concept, but I think that's what's got you into such a mess to start with...
So I've basically create a simplified example of what I "guess" your description is asking for...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridheight = gbc.REMAINDER;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.BOTH;
JTextArea patch = new JTextArea(10, 20);
add(new JScrollPane(patch), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
for (int index = 0; index < 6; index++) {
add(new JButton("Button #" + index), gbc);
gbc.gridy++;
}
gbc.gridx = 1;
gbc.anchor = GridBagConstraints.SOUTH;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(new JButton("Play >"), gbc);
}
}
}
With layouts, it's best to start with pen and paper, group the elements you need to together (like the buttons down the right side for example) and devise a plan for how you might lay them out and prototype of view ideas...
Updated
1) How can I have it so that there is space between the TextArea and the buttons, and vertical space on the buttons? I tried using the Insets but I haven't arranged the numbers in a correct way yet.
insets is the correct way to go...
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(2, 8, 2, 4);
gbc.anchor = GridBagConstraints.NORTH;
for (int index = 0; index < 6; index++) {
core.add(new JButton("Button #" + index), gbc);
gbc.gridy++;
}
2) I would like the "Play" button at the center-bottom of the screen, and have it be larger
You "could" do this with GridBagLayout, but I decided not to, as it can cause some issues if you're not careful with how your setup the constraints for the other components, so instead, I used a combination of BorderLayout and GridBagLayout.
To make the "play" button larger, you could modify the font or adjust the button's margins...
playButton.setMargin(new Insets(12, 12, 12, 12));
depending on the effect you're after
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout(0, 4));
JPanel core = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridheight = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
JTextArea patch = new JTextArea(10, 20);
core.add(new JScrollPane(patch), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(2, 8, 2, 4);
gbc.anchor = GridBagConstraints.NORTH;
for (int index = 0; index < 6; index++) {
core.add(new JButton("Button #" + index), gbc);
gbc.gridy++;
}
add(core);
JButton playButton = new JButton("Play >");
playButton.setMargin(new Insets(12, 12, 12, 12));
add(playButton, BorderLayout.SOUTH);
}
}

Positioning elements in a JPanel of CardLayout

I'm having trouble positioning elements in a JPanel. I tried using GridBagLayout but that doesn't seem to make any of the parts of the panel GUI components move. What should I do?
panel.add(Label);
panel.add(TextField);
panel.add(Label);
panel.add(JChooser);
Nothing seems to help move these GUI elements. They just act like they are in a FlowLayout. What should I do? I'm using a CardLayout for another panel (that panel holds other panels like this one in it), but this panel, I need to align them to the left.
The Label and TextField need to be on the same line, but the Label and JChooser need to be on a different line.
Example:
SomeLabel : [ TextField ]
SomeLabel : [Chooser]
I hope I explained well enough.
Take a closer look at Laying Out Components Within a Container and How to Use GridBagLayout
GridBagLayout requires constraints, which define how and where a component will be positioned within the virtual grid maintained by it
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestLayout {
public static void main(String[] args) {
new TestLayout();
}
public TestLayout() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(4, 4, 4, 4);
add(new JLabel("SomeLabel :"), gbc);
gbc.gridy++;
add(new JLabel("SomeLabel :"), gbc);
gbc.gridx = 1;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.EAST;
gbc.fill = GridBagConstraints.BOTH;
add(new JTextField(10), gbc);
gbc.gridy++;
add(new JComboBox(new Object[]{"Puppies", "Kittens"}), gbc);
}
}
}
To set elements in JPanel use one of LayoutManagers.
If you want to set components free from location.
then use following to remove layout.
panel.setLayout(null);
After this you can call setBounds method to set bounds for component, or setLocation .
comp.setLocation(int left, int top);
comp.setBounds(int left, int top, int width, int height);

GUI: JButton Covering almost the entire screen

I have encountered a problem whilst working the JFrame's, and JButtons. I am trying to center my JButton, however when I do so, it covers almost the entire screen. Any idea's on what's causing this?
Here is a picture on how it looks :
And here is my code :
package character;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
/**
* Created by Niknea on 6/28/14.
*/
public class characterSelector{
JFrame cselectorButtons, clogo;
JLabel logo, characterName, label;
JButton male, female;
public characterSelector(){
this.createCharacterSelector();
}
public void createCharacterSelector() {
try {
label = new JLabel(new ImageIcon(ImageIO.read(getClass()
.getResource("/resources/Grass_Background.jpg"))));
cselectorButtons = new JFrame("SupremeSoccer");
logo = new JLabel(new ImageIcon(ImageIO.read(this.getClass().getResource("/resources/Character_Selector_Image.png"))));
characterName = new JLabel("<Character Name>");
characterName.setFont(new Font(characterName.getFont().getName(),
Font.HANGING_BASELINE, 50));
/*
Buttons
*/
male = new JButton("Male");
////******************////
//// END OF BUTTONS ////
////****************////
cselectorButtons.add(logo);
cselectorButtons.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cselectorButtons.setContentPane(label);
cselectorButtons.setLayout(new BorderLayout());
cselectorButtons.add(logo, BorderLayout.NORTH);
cselectorButtons.add(male, BorderLayout.CENTER);
cselectorButtons.pack();
cselectorButtons.setLocationRelativeTo(null);
cselectorButtons.setVisible(true);
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
Thanks again.
Any idea's on what's causing this?
This is the default behaviour of BorderLayout. The component at the CENTER position will occupy the maximum amount of space the is available from the parent component, when the other (NORTH, SOUTH, EAST, WEST) positions have been taken into account
Depending on what you are trying to achieve you might consider creating another JPanel (set it's opaque state to false so it's transparent) and use something like GridLayout or GridBagLayout instead.
Take a look at A Visual Guide to Layout Managers for some more ideas
Updated
So based on your linked code, I changed
part2 = new JPanel();
to
part2 = new JPanel(new java.awt.GridBagLayout());
And got...
Updated with additional example
Start by breaking down your requirements into individual containers and focus on the layout requirements for each individual, then build them all back into a single container.
This will make changing them later much easier and also make controlling them much easier...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ExampleLayout {
public static void main(String[] args) {
new ExampleLayout();
}
public ExampleLayout() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private HeaderPane header;
private ScorePane score;
private CharacterSelectionPane characterSelection;
public TestPane() {
setLayout(new BorderLayout());
JLabel background = new JLabel();
try {
BufferedImage img = ImageIO.read(getClass().getResource("/Grass.jpg"));
background.setIcon(new ImageIcon(img));
} catch (IOException ex) {
ex.printStackTrace();
}
add(background);
background.setLayout(new GridBagLayout());
header = new HeaderPane();
score = new ScorePane();
characterSelection = new CharacterSelectionPane();
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.BOTH;
background.add(header, gbc);
background.add(score, gbc);
gbc.weighty = 1;
background.add(characterSelection, gbc);
}
}
public class HeaderPane extends JPanel {
public HeaderPane() {
setLayout(new BorderLayout());
JLabel label = new JLabel("Character Selection");
label.setForeground(Color.WHITE);
label.setFont(label.getFont().deriveFont(Font.BOLD, 48f));
label.setHorizontalAlignment(JLabel.CENTER);
add(label);
setOpaque(false);
}
}
public class ScorePane extends JPanel {
public ScorePane() {
JLabel label = new JLabel("[-][-[]-][-]");
label.setForeground(Color.YELLOW);
add(label);
setOpaque(false);
}
}
public class CharacterSelectionPane extends JPanel {
private JButton btMale;
private JButton btFemale;
private JTextField tfName;
private JButton btContinue;
public CharacterSelectionPane() {
setOpaque(false);
setLayout(new GridBagLayout());
btMale = new JButton("Male");
btFemale = new JButton("Female");
btContinue = new JButton("Continue");
tfName = new JTextField(10);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(4, 4, 4, 4);
gbc.fill = GridBagConstraints.HORIZONTAL;
add(btMale, gbc);
gbc.gridx++;
add(btFemale, gbc);
gbc.gridx = 0;
gbc.gridy++;
add(new JLabel("Name:"), gbc);
gbc.gridx++;
add(tfName, gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(btContinue, gbc);
}
}
}
Use a BoxLayout or (easier) GridBagLayout for the bottom area, as seen in this answer.

Categories

Resources