unable to add buttons vertically - java

I am writing a program where JButtons are added dynamically to a JPanel in a vertical fashion. (the buttons are stored in an arraylist)I have tried the following code by setting the JPanel to gridbaglayout.
for(int i = 0; i<listOfButtons.size();i++) {
c.gridx=0;
c.gridy=i;
leftButtonPanel.add(listOfButtons.get(i));
}
the result is the following
and after adding the buttons
I have also tried setting the JPanel to a gridlayout
leftButtonPanel.setLayout(new GridLayout(listOfButtons.size(),1));
for(int i = 0; i<listOfButtons.size();i++) {
leftButtonPanel.add(listOfButtons.get(i));
}
The buttons "see all" and "add" are all in the same listOfButtons arraylist. and the only way to add buttons into the panel is through that forloop. for some reasons the buttons still start off horizontally.

For GridBagLayout, don't forget, you need to supply the GridBagConstraints as well, otherwise it act a lot like a FlowLayout
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class SoTest {
public static void main(String[] args) {
new SoTest();
}
public SoTest() {
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() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
List<JButton> listOfButtons = new ArrayList<>(5);
for (int i = 0; i < 10; i++) {
listOfButtons.add(new JButton(Integer.toString(i)));
}
for (int i = 0; i < listOfButtons.size(); i++) {
add(listOfButtons.get(i), gbc);
}
}
}
}
At this point, I'm curious as to if you should be considering a JList instead

Related

How to change JButton size in JPanel which is "spread" at whole JFrame

So I have a problem,because mine JButtons are just too bige, I need to change their size to be for eg small rectangles or squares. Right now they look like piano keys.
This is my paste.Could you guys help? :)
I tried SetSize or SetDimension or all the methods available but it did not work out. And I haven't found relevant topic here at overflow. What do you think?
package sg;
import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class SG extends JFrame {
JPanel pn1;
JPanel pn2;
JPanel pn3;
JPanel pn4;
JButton[] buttony = new JButton[12];
JButton start;
SG() {
super();
setSize(1000, 900);
setResizable(false);
pn1 = new JPanel();
pn2 = new JPanel();
pn1.setLayout(new GridBagLayout());
pn2.setLayout(new GridLayout(2,6));
start = new JButton("Start");
start.addActionListener(new B1());
pn1.add(start);
for (int i = 0; i < 12; i++) {
buttony[i] = new JButton(Integer.toString(i + 1));
buttony[i].setSize(10, 10);
pn2.add(buttony[i]);
}
add(pn1,BorderLayout.NORTH);
add(pn2,BorderLayout.CENTER);
}
public static void main(String[] args) {
SG adam = new SG();
adam.setVisible(true);
}
private class B1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
Random s = new Random();
int a = s.nextInt(5);
System.out.println(a);
}
}
}
Add pn2 to another JPanel and then set that panel to the JFrame using setContentPane.
The complete code is as follows:
import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class SG extends JFrame {
JPanel pn1;
JPanel pn2;
JPanel pn3;
JPanel pn4;
JButton[] buttony = new JButton[12];
JButton start;
SG() {
super();
setSize(1000, 900);
setResizable(false);
pn1 = new JPanel();
pn2 = new JPanel();
JPanel contentPane = new JPanel();
pn1.setLayout(new GridBagLayout());
pn2.setLayout(new GridLayout(2, 6));
start = new JButton("Start");
start.addActionListener(new B1());
pn1.add(start);
for (int i = 0; i < 12; i++) {
buttony[i] = new JButton(Integer.toString(i + 1));
buttony[i].setSize(10, 10);
pn2.add(buttony[i]);
}
contentPane.add(pn2);
setContentPane(contentPane);
add(pn1, BorderLayout.NORTH);
add(pn2, BorderLayout.CENTER);
}
public static void main(String[] args) {
SG adam = new SG();
adam.setVisible(true);
}
private class B1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
Random s = new Random();
int a = s.nextInt(5);
System.out.println(a);
}
}
}
If you want to use GridBagLayout, be sure to read this page:
https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
which suggests defining constraints before adding elements.
My choice is MigLayout. Google it and check 5+ versions.
The default size of a component, is barely defined by setSize(), because layout managers often use it to define the dimensions of each components to resize them, so your effort will almost always be overwritten. If you want, try setPreferedSize(), setMinimumSize() and setMaximumSize().
About the topic of Swing, StackOverFlow has plenty of questions related. Try searching tag swing. Also, the Oracle guide is a must-read: https://docs.oracle.com/javase/tutorial/uiswing/TOC.html. And each layout manager has its own documentation. Like Miglayout. http://www.miglayout.com/
Be patient. Several month of time is required to get an rough idea of all this.
GUI components such as JButton need to be placed in a container. JPanel is a container. Containers have an associated layout manager. The layout manager determines the size and location of the components within the container. The GridLayout divides the container into a grid of equal sized cells and places exactly one component in each cell. In the code you posted, each cell contains exactly one JButton, hence each button has the same size. Explicitly setting the JButton size will not help because GridLayout ignores it.
Therefore you need to use a layout manager that is appropriate for your needs. You want to lay out your JButtons in a grid but have each JButton displayed with its preferred size. An appropriate layout manger for this is GridBagLayout. It lays out the components in a grid but sizes each component according to its preferred size.
The following code is a rewrite of the code you posted, because I felt that starting from scratch would be more beneficial to you than patching the code you posted. In the below code, I am using GridBagLayout to lay out the grid of JButtons.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class SG1 implements ActionListener, Runnable {
private static final int NUMBER_OF_BUTTONS = 12;
private static final String START = "Start";
private JButton[] buttons;
private JFrame frame;
private JTextField textField;
public SG1() {
buttons = new JButton[NUMBER_OF_BUTTONS];
}
#Override // java.awt.event.ActionListener
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
switch (actionCommand) {
case START:
Random s = new Random();
int a = s.nextInt(5);
textField.setText(String.valueOf(a));
break;
default:
JOptionPane.showMessageDialog(frame,
actionCommand,
"Unhandled",
JOptionPane.WARNING_MESSAGE);
}
}
#Override // java.lang.Runnable
public void run() {
createAndShowGui();
}
private void createAndShowGui() {
frame = new JFrame("SG1");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createTextFieldPanel(), BorderLayout.PAGE_START);
frame.add(createButtonsPanel(), BorderLayout.CENTER);
frame.add(createStartButtonPanel(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets.top = 3;
gbc.insets.right = 3;
gbc.insets.left = 3;
gbc.insets.bottom = 3;
for (int i = 0; i < NUMBER_OF_BUTTONS; i++) {
buttons[i] = new JButton(String.format("%02d", (i + 1)));
buttonsPanel.add(buttons[i], gbc);
gbc.gridx++;
if (gbc.gridx > (NUMBER_OF_BUTTONS / 2) - 1) {
gbc.gridx = 0;
gbc.gridy++;
}
}
return buttonsPanel;
}
private JPanel createStartButtonPanel() {
JPanel startButtonPanel = new JPanel();
JButton startButton = new JButton(START);
System.out.println(startButton.getFont());
startButton.addActionListener(this);
startButtonPanel.add(startButton);
return startButtonPanel;
}
private JPanel createTextFieldPanel() {
JPanel textFieldPanel = new JPanel();
textField = new JTextField(10);
textFieldPanel.add(textField);
return textFieldPanel;
}
public static void main(String[] args) {
EventQueue.invokeLater(new SG1());
}
}
I suggest you thoroughly study the above code and if there are parts you don't understand, then search the Internet for explanations. You will find many examples for each part of it.
For learning Swing in general, I recommend the online tutorial Creating a GUI With JFC/Swing. I also recommend the book Core JFC (2nd Edition) by Kim Topley

Trying to put buttons on the bottom of the screen

So after a day of studying layout managers and reading some swing refrences, this is what i come up with...
import java.awt.*;
import javax.swing.*;
public class Flags {
public static void startup() {
GridLayout Layout = new GridLayout(6,4);
JFrame menu = new JFrame("Flag Menu");
menu.setResizable(false);
menu.setSize(600,400);
JButton tailand = new JButton("Tailand");
JButton norway = new JButton("Norway");
JPanel panel = new JPanel();
panel.setLayout(Layout);
panel.add(norway);
panel.add(tailand);
menu.add(panel);
panel.setBackground(Color.LIGHT_GRAY);
tailand.setBackground(Color.WHITE);
norway.setBackground(Color.WHITE);
menu.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
menu.setLocationRelativeTo(null);
;
menu.setVisible(true);
}
}
The problem is that i want my buttons to start at the bottom left and be equally spaced between the 4 other buttons i want to make.
There's a number of ways you "might" achieve this and the solution will ultimately depend on what you are trying to achieve.
Personally, I'd start with GridBagLayout - while not the friendliness of layout managers, it is by far the most flexible.
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Flags {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Flags().startup();
}
});
}
public static void startup() {
GridLayout Layout = new GridLayout(6, 4);
JFrame menu = new JFrame("Flag Menu");
// menu.setResizable(false);
// menu.setSize(600, 400);
menu.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton tailand = new JButton("Tailand");
JButton norway = new JButton("Norway");
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weighty = 1;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.anchor = GridBagConstraints.SOUTH;
panel.add(norway, gbc);
gbc.weighty = 0;
panel.add(tailand, gbc);
menu.add(panel);
panel.setBackground(Color.LIGHT_GRAY);
tailand.setBackground(Color.WHITE);
norway.setBackground(Color.WHITE);
menu.pack();
menu.setLocationRelativeTo(null);
menu.setVisible(true);
}
}
Another choice might be to use compound layouts, so that the "button" panel is placed at the SOUTH position of a BorderLayout and the "content" placed in the CENTER

Set the size of JButton to the length and width of the label

I am working on adding buttons to a button panel to be more familiar with java.swing class. Is there a way to set the size of JButton to the length and width of the button label?
Similar to setting height and width view in the xml file to wrap_content or match_parent.Setting a View or Layouts size based on either it's contents or the parent's dimensions rather than explicitly specifying a dimension.
android:layout_width="wrap_content"
android:layout_height="match_parent"
Is there a way to set the size of JButton to the length and width of the button label using button.setPreferredSize() without explicitly specifying the dimension?
button = new JButton[buttonName.length];
RadioButtonAction radioButtonEventO=new RadioButtonAction(); //O for operation
buttonPanelS=new JPanel();
buttonPanelS.setLayout(new GridLayout(4,1));
for(int i=0; i<buttonName.length;i++){
button[i]=new JButton(buttonName[i]);
button[i].setMargin(new Insets(0,0,0,0));
button[i].addActionListener(radioButtonEventO);
//button[i].setPreferredSize();
buttonPanelS.add(button[i]);
}
operationPanel.add(buttonPanelS);
I'm not 100% I understand, but GridLayout will, by design, size the all the components to occupy the available space of the container, evenly.
It sounds more like what you're after is GridBagLayout...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
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());
JButton[] button = new JButton[5];
JPanel buttonPanelS = new JPanel();
buttonPanelS.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
for (int i = 0; i < 5; i++) {
button[i] = new JButton(random());
button[i].setMargin(new Insets(0, 0, 0, 0));
buttonPanelS.add(button[i], gbc);
}
add(buttonPanelS);
}
private Random rnd = new Random();
public String random() {
int length = rnd.nextInt(20) + 1;
StringBuilder sb = new StringBuilder(length);
for (int index = 0; index < length; index++) {
sb.append(('a' + rnd.nextInt(52)));
}
return sb.toString();
}
}
}
If that's not what you're after either, then consider providing a drawing, to better illustrate your question

How to get 2 JPanels within 1 JPanel, resizable, with fixed proportion?

Let's say a JFrame contains just 1 JPanel. This JPanel is divided into 2 JPanels occupying accordingly 0.75 and 0.25 of the JFrame height. I want all of this to be resizable along with the window size.
I have no idea how to do this in Java.
I'm a newbie to Java. I've read a bit about layouts, but all I can see is how to set preferred size in constructor (ceasing to resize when this number is reached) or some fixed sizes obtained through setting borders.
JFrame with a BorderLayout, onto that, add a JPanel with a GridBagLayout. Add your other two panels onto this.
See Laying Out Components Within a Container and How to Use GridBagLayout for more details
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
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.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 0.75;
JPanel top = new JPanel(new GridBagLayout());
top.add(new JLabel("Top"));
top.setBackground(Color.RED);
add(top, gbc);
gbc.gridy++;
gbc.weighty = 0.25;
JPanel bottom = new JPanel(new GridBagLayout());
bottom.add(new JLabel("Bottom"));
bottom.setBackground(Color.BLUE);
add(bottom, gbc);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}

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