I have a panel, in which I want the content to displayed vertically. To do that, I'm using this line of code:
rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.Y_AXIS));
As I'm using textfields, then I would like them to take up one line. But by using the line of code specified above, textfields inside the panel get maximized and when I change the window size, the size of the textfield changes accordingly. I also tried removing it, but then the contents inside the panel get displayed horizontally and won't fit inside the panel.
Here is the image of the result:
And here is the code where the content of the panel gets created:
//Creates the form for data and button to save it.
final TextField name;
final TextField eMail;
final TextField dateOfBirth;
final TextField address;
JLabel nameLabel = new JLabel("Name:");
name = new TextField ();
JLabel eMailLabel = new JLabel("E-mail:");
eMail = new TextField ();
JLabel dateOfBirthLabel = new JLabel("Date of birth:");
dateOfBirth = new TextField ();
JLabel addressLabel = new JLabel("Address:");
address = new TextField ();
rightPanel.add(nameLabel);
rightPanel.add(name);
rightPanel.add(eMailLabel);
rightPanel.add(eMail);
rightPanel.add(dateOfBirthLabel);
rightPanel.add(dateOfBirth);
rightPanel.add(addressLabel);
rightPanel.add(address);
rightPanel.add(Box.createRigidArea(new Dimension(20, 20)));
JButton save = new JButton("Save");
rightPanel.add(save);
You need to fill the rest of the panel with something, use swing.Box
import javax.swing.Box;
rightPanel.add(Box.createVerticalGlue());
put the box in the position where you want the space to apear
More on that subject http://docs.oracle.com/javase/tutorial/uiswing/layout/box.html#filler
You also need to limit maximum height of the input boxes (for each input call - create method probably):
input.setMaximumSize(new Dimension(Integer.MAX_VALUE, input.getMinimumSize().height));
You can put your panel in the NORTH part of a BorderLayout -- in the EAST or CENTER parts of a BorderLayout, the panel stretches up/down, but not in the North. And, of course, you can put it in its own JPanel with that BorderLayout, and then put THAT JPanel in another layout however you want.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.HeadlessException;
import java.awt.TextField;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class RightPanel extends JFrame
{
TextField name;
TextField eMail;
TextField dateOfBirth;
TextField address;
JPanel rightPanel = new JPanel();
public static void main(String[] args)
{
RightPanel rp = new RightPanel();
rp.createUI();
rp.setVisible(true);
}
public void createUI()
{
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
//Creates the form for data and button to save it.
JLabel nameLabel = new JLabel("Name:");
name = new TextField ();
JLabel eMailLabel = new JLabel("E-mail:");
eMail = new TextField ();
JLabel dateOfBirthLabel = new JLabel("Date of birth:");
dateOfBirth = new TextField ();
JLabel addressLabel = new JLabel("Address:");
address = new TextField ();
rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.PAGE_AXIS));
rightPanel.add(nameLabel);
rightPanel.add(name);
rightPanel.add(eMailLabel);
rightPanel.add(eMail);
rightPanel.add(dateOfBirthLabel);
rightPanel.add(dateOfBirth);
rightPanel.add(addressLabel);
rightPanel.add(address);
rightPanel.add(Box.createRigidArea(new Dimension(20, 20)));
JButton save = new JButton("Save");
rightPanel.add(save);
JPanel doNotStretchPanel = new JPanel();
doNotStretchPanel.setLayout(new BorderLayout());
doNotStretchPanel.add(rightPanel, BorderLayout.NORTH);
this.add(doNotStretchPanel, BorderLayout.EAST);
pack();
}
}
Related
I am trying to make my own little game in Java as a personal excercise however I am finding a lot of issues using BoxLayout's in Java Swing.
So I have a basic MVC application and I need two buttons at the top both "New Game" and "Submit" to both be on the same line in the GUI. I have found out that I can use glue to do this however all of the guides I have found on it, do not work. Am I missing something obvious here?
This is my view code (my GUI):
package mvc;
import java.awt.*;
import java.awt.event.ActionListener;
import java.util.Map;
import java.util.Set;
import javax.swing.*;
public class View extends JFrame {
//User input Characters
private JTextField firstChar = new JTextField(1);
private JTextField secondChar = new JTextField(1);
private JTextField thirdChar = new JTextField(1);
private JTextField fourthChar = new JTextField(1);
private JTextField fifthChar = new JTextField(1);
//Displays on GUI
private JButton submitButton = new JButton("Submit");
private JButton newButton = new JButton("New Game");
View() {
JPanel gamePanel = new JPanel();
gamePanel.setLayout(new BoxLayout(gamePanel, BoxLayout.Y_AXIS));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600, 200);
gamePanel.add(submitButton);
gamePanel.add(Box.createHorizontalGlue());
gamePanel.add(newButton);
gamePanel.add(firstChar);
gamePanel.add(secondChar);
gamePanel.add(thirdChar);
gamePanel.add(fourthChar);
gamePanel.add(fifthChar);
this.add(gamePanel);
}
}
Any help would be massively appreciated!
I have tried using glue and rigid area's to solve this however neither worked. I am expecting both buttons to be on the same line in my GUI
You use Boxlayout, that according to https://docs.oracle.com/en/java/javase/17/docs/api/java.desktop/javax/swing/BoxLayout.html
A layout manager that allows multiple components to be laid out either vertically or horizontally.
In your case it is vertical, and I never used Glue so I am not even aware whether it can change that behaviour.
But you can for sure put the two buttons in an extra panel and add that to your gamePanel, like so:
JPanel buttonBar = new JPanel();
buttonBar.setLayout(new FlowLayout());
buttonBar.add(submitButton);
buttonBar.add(newButton);
gamePanel.add(buttonBar);
BoxLayout can either lay out the components along the X_AXIS or along the Y_AXIS. You cannot mix this two layout directions with a single BoxLayout.
One way to solve your problem is to wrap both buttons in a JPanel and use a BoxLayout(.., BoxLayout.X_AXIS) to lay out this button panel.
You would then add the button panel as the first element of the gamePanel:
package mvc;
import java.awt.*;
import java.awt.event.ActionListener;
import java.util.Map;
import java.util.Set;
import javax.swing.*;
public class View extends JFrame {
//User input Characters
private JTextField firstChar = new JTextField(1);
private JTextField secondChar = new JTextField(1);
private JTextField thirdChar = new JTextField(1);
private JTextField fourthChar = new JTextField(1);
private JTextField fifthChar = new JTextField(1);
//Displays on GUI
private JButton submitButton = new JButton("Submit");
private JButton newButton = new JButton("New Game");
View() {
JPanel gamePanel = new JPanel();
gamePanel.setLayout(new BoxLayout(gamePanel, BoxLayout.Y_AXIS));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600, 200);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
buttonPanel.add(submitButton);
buttonPanel.add(Box.createHorizontalGlue());
buttonPanel.add(newButton);
gamePanel.add(buttonPanel);
gamePanel.add(firstChar);
gamePanel.add(secondChar);
gamePanel.add(thirdChar);
gamePanel.add(fourthChar);
gamePanel.add(fifthChar);
this.add(gamePanel);
}
}
I am trying to make the interface of a program using Java Swing. I have a container where I add 3 JPanels with some components. The problem is that when I expand the frame all those 3 JPanels come on the first row one next to another.
Here is my code:
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SpringLayout;
import javax.swing.border.LineBorder;
public class GraphicRefact extends JFrame {
private Container container;
private JButton button2;
private JButton button1;
private JTextField textField01;
private JLabel label01;
private JButton button03;
private JButton button04;
private JTextField textField03;
private JLabel label03;
private JButton button02;
private JButton button01;
private JTextField textField02;
private JLabel label02;
public static void main(String[] args) {
new GraphicRefact();
}
public GraphicRefact() {
initializeComponents();
setTitle("Title");
setSize(500, 150);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
container = new JPanel();
JPanel panel01 = new JPanel();
panel01.add(label01);
panel01.add(textField01);
panel01.add(button2);
panel01.add(button1);
panel01.setBorder(new LineBorder(Color.BLACK, 3));
container.add(panel01);
JPanel panel02 = new JPanel();
panel02.add(label02);
panel02.add(textField02);
panel02.add(button02);
panel02.add(button01);
container.add(panel02);
JPanel panel03 = new JPanel();
panel03.add(label03);
panel03.add(textField03);
panel03.add(button03);
panel03.add(button04);
container.add(panel03);
add(container);
}
private void initializeComponents() {
button1 = new JButton("Open");
button2 = new JButton("Close");
textField01 = new JTextField("Choose the path...");
label01 = new JLabel("Choose File: ");
button01 = new JButton("Button01");
button02 = new JButton("Button02");
textField02 = new JTextField("Choose the path...");
label02 = new JLabel("Choose Dir:");
button03 = new JButton("Button03");
button04 = new JButton("Button03");
textField03 = new JTextField("Choose the path...");
label03 = new JLabel("Choose Dir:");
}
}
Here is how the program looks before and after I expand the frame.
Before:
After:
So, even after I expand the frame, I want the program to leave those 3 JPanels on the middle of cotainer.
Thank you!
You can set the gridLayout and put those elements inside.
JPanel jp = new JPanel();
GridLayout gl = new GridLayout(3,4); //3 rows, 4 columns
jp.setLayout(gl);
After you do this, just put your elements inside layout, by order.
jp.add(label1);
jp.add(button1);
//etc...
You have to use a proper LayoutManager. Look at the examples there. BoxLayout seems to be what you want.
I can't see where you have defined any positions for anything, if you need to read how that's done you can start here
Positioning a JPanel in a JFrame at specific position
The inbuilt layout manger of java swing are not that useful.
You should use this
frame.setLayout(null);
component.setLocation(x, y);
frame.add(component);
So this problem is really giving me a headache because for some reason last night when i was working on it, my code ran perfectly and my textfields would show up without a problem...
Go to bed, wake up, time to work on it again aaaaaand bam. Now my JtextFields only show up when i highlight them or click them or something...I was wondering what could be wrong?
My code is really just messy and crappy at this point while i figure out a better way to design my program...
I thought it was just eclipse but netbeans is giving me the same issue.
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.awt.*;
import javax.swing.border.*;
public class DiffuserCalc {
//create the class data fields
private double Qts;
private double Qes;
private double Vas;
JFrame ProgramBounds = new JFrame();
JLabel label1= new JLabel("Qts");
JLabel label2= new JLabel("Qes");
JLabel label3= new JLabel("Fs");
JLabel label4= new JLabel("BL");
JLabel label5= new JLabel("Xmax");
JLabel label6= new JLabel("Fs");
JLabel label7= new JLabel("Vas");
JLabel label8= new JLabel("Diameter");
JLabel label9= new JLabel("Pmax (RMS)");
JTextField QtsParam = new JTextField("Value");
JTextField QesParam = new JTextField("Value");
JTextField FsParam = new JTextField(" ");
JTextField BLParam = new JTextField(" ");
JTextField XmaxParam = new JTextField(" ");
Font myFont = new Font("Tahoma", Font.BOLD, 20);
DiffuserCalc()
{
ProgramBounds.setTitle("Box Designer");
JPanel ParameterMenu = new JPanel();
JPanel FieldInputs = new JPanel();
ParameterMenu.setBounds(30, 0, 1180, 120);
FieldInputs.setBounds(0,0, 1280, 720);
ProgramBounds.add(ParameterMenu);
ProgramBounds.add(FieldInputs);
ProgramBounds.setSize(1280,720);
// LAYOUT
ParameterMenu.setLayout(new FlowLayout(FlowLayout.CENTER, 60, 10));
FieldInputs.setLayout(null);
Border lineBdr = BorderFactory.createLineBorder(Color.BLACK);
Border BlackBorder = BorderFactory.createTitledBorder(lineBdr, " T/S Parameters ", TitledBorder.CENTER, TitledBorder.TOP, myFont, Color.black);
//FIELD PROPERTIES
label1.setFont(myFont);
label2.setFont(myFont);
label3.setFont(myFont);
label4.setFont(myFont);
label5.setFont(myFont);
label6.setFont(myFont);
label7.setFont(myFont);
label8.setFont(myFont);
label9.setFont(myFont);
// PARAMETER BOUNDS
int XLoc = 150;
int YLoc = 70;
QtsParam.setBounds(XLoc, YLoc, 40, 20);
QesParam.setBounds(XLoc+95, YLoc, 40, 20);
FsParam.setBounds(XLoc+190, YLoc, 40, 20);
// ADD FIELDS
ParameterMenu.add(label1);
ParameterMenu.add(label2);
ParameterMenu.add(label3);
ParameterMenu.add(label4);
ParameterMenu.add(label5);
ParameterMenu.add(label6);
ParameterMenu.add(label7);
ParameterMenu.add(label8);
ParameterMenu.add(label9);
ParameterMenu.setBorder(BlackBorder);
FieldInputs.add(QtsParam);
FieldInputs.add(QesParam);
FieldInputs.add(FsParam);
FieldInputs.add(BLParam);
FieldInputs.add(XmaxParam);
// set everything proper
QtsParam.requestFocus();
ParameterMenu.setVisible(true);
FieldInputs.setVisible(true);
ProgramBounds.setVisible(true);
}
public double BoxDimension(int x, int y)
{
return x;
}
public static void main(String[] args) {
DiffuserCalc MainProgram = new DiffuserCalc();
}
}
Your code only sets the bounds for 3 text fields but you add 5 text fields to the panel.
Don't use a null layout!!!
Use a proper layout manager and then you don't have to worry about making mistakes like this.
Also, follow Java naming conventions. Variable names do NOT start with an upper case character.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.FlowLayout;
import java.awt.Font;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
public class DiffuserCalc {
//create the class data fields
private double qts;
private double qes;
private double vas;
private JFrame programBounds = new JFrame();
private JLabel label1= new JLabel("Qts");
private JLabel label2= new JLabel("Qes");
private JLabel label3= new JLabel("Fs");
private JLabel label4= new JLabel("BL");
private JLabel label5= new JLabel("Xmax");
private JLabel label6= new JLabel("Fs");
private JLabel label7= new JLabel("Vas");
private JLabel label8= new JLabel("Diameter");
private JLabel label9= new JLabel("Pmax (RMS)");
private JTextField qtsParam = new JTextField("Value");
private JTextField qesParam = new JTextField("Value");
private JTextField fsParam = new JTextField("");
private JTextField bLParam = new JTextField("");
private JTextField xmaxParam = new JTextField("");
private Font myFont = new Font("Tahoma", Font.BOLD, 20);
DiffuserCalc()
{
programBounds.setTitle("Box Designer");
JPanel parameterMenu = new JPanel();
JPanel labelPanel = new JPanel();
JPanel fieldInputs = new JPanel();
// LAYOUT
programBounds.setLayout(new BorderLayout());
parameterMenu.setLayout(new BorderLayout());
fieldInputs.setLayout(new FlowLayout(FlowLayout.LEFT));
fieldInputs.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
labelPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
labelPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
programBounds.add(parameterMenu, BorderLayout.NORTH);
parameterMenu.add(labelPanel, BorderLayout.NORTH);
parameterMenu.add(fieldInputs, BorderLayout.SOUTH);
// programBounds.add(fieldInputs);
programBounds.setSize(1280,720);
Border lineBdr = BorderFactory.createLineBorder(Color.BLACK);
Border BlackBorder = BorderFactory.createTitledBorder(lineBdr, " T/S Parameters ", TitledBorder.CENTER, TitledBorder.TOP, myFont, Color.black);
//FIELD PROPERTIES
label1.setFont(myFont);
label2.setFont(myFont);
label3.setFont(myFont);
label4.setFont(myFont);
label5.setFont(myFont);
label6.setFont(myFont);
label7.setFont(myFont);
label8.setFont(myFont);
label9.setFont(myFont);
// ADD FIELDS
labelPanel.add(label1);
labelPanel.add(label2);
labelPanel.add(label3);
labelPanel.add(label4);
labelPanel.add(label5);
labelPanel.add(label6);
labelPanel.add(label7);
labelPanel.add(label8);
labelPanel.add(label9);
parameterMenu.setBorder(BlackBorder);
qtsParam.setColumns(3);
fieldInputs.add(qtsParam);
qesParam.setColumns(3);
fieldInputs.add(qesParam);
fsParam.setColumns(2);
fieldInputs.add(fsParam);
bLParam.setColumns(2);
fieldInputs.add(bLParam);
xmaxParam.setColumns(2);
fieldInputs.add(xmaxParam);
// set everything proper
qtsParam.requestFocus();
programBounds.pack();
programBounds.setVisible(true);
}
public double BoxDimension(int x, int y)
{
return x;
}
public static void main(String[] args) {
DiffuserCalc MainProgram = new DiffuserCalc();
}
}
So I rewrote the class for you to be more according to the Java style standard. Next not using a Layout manager is asking for trouble. And even though your requirements are like you say it's still better to put the effort to use a Layout manager as you'll keep running into problems like these. Read more about layout managers here. Furthermore don't call setVisible on JPanels that you added to a frame. When you call setVisible on the JFrame it will call setVisible on all of it child components.
Next call the method setColumns on the JTextField instead of initializing it with spaces for more consistent and predictable behaviour.
i have made a panel/GUI using BlueJ with multiple JLabels and Entry boxes along with a button, however when i execute it the labels appear next to each other and the Confirm button appears on the same row as the last entry box, ive tried changing the coordinates in the code however it doesnt make a difference, how would i go about having each label next to its own entry box and my confirm button at the bottom of the application ?
My code is below:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Log extends JFrame {
public static void main(String[] args){
Log frameTable1= new Log();
}
JPanel panel = new JPanel();
JLabel name = new JLabel("Name", JLabel.LEFT);
JTextField FullName = new JTextField(15);
JPanel panel1 = new JPanel();
JLabel address = new JLabel("Address", JLabel.LEFT);
JTextField Address1line = new JTextField(15);
JTextField postcode = new JTextField(15);
JTextField Destination = new JTextField(15);
JTextField Date = new JTextField(15);
JTextField MilesTravelling = new JTextField(15);
JButton Confirm = new JButton("Confirm");
Log(){
super("Customer GUI");
setSize(300,400);
setLocation(400,250);
panel.setLayout(new FlowLayout());
FullName.setBounds(70,30,150,20);
Address1line.setBounds(70,80,150,20);
postcode.setBounds(70,130,150,20);
Destination.setBounds(70,180,150,20);
Date.setBounds(70,230,150,20);
MilesTravelling.setBounds(70,280,150,20);
Confirm.setBounds(105,290,80,40);
name.setBounds(40,30,150,20);
address.setBounds(40, 80, 150, 20);
getContentPane().add(name);
getContentPane().add(panel);
panel.add(name);
getContentPane().add(address);
getContentPane().add(panel);
panel.add(address);
panel.add(FullName);
panel.add(Address1line);
panel.add(postcode);
panel.add(Destination);
panel.add(Date);
panel.add(MilesTravelling);
panel.add(Confirm);
getContentPane().add(panel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
}
Thankyou
I am creating a GUI using BlueJ - Java, i have made the entry boxes however i cant seem to add a label to go either above each one or to the left. Could anyone help me out and tell me where im going wrong ? My code is below:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Log extends JFrame {
public static void main(String[] args){
Log frameTabel = new Log();
}
JButton Confirm = new JButton("Confirm");
JPanel panel = new JPanel();
JLabel label1 = new JLabel("Name", JLabel.RIGHT);
JTextField FullName = new JTextField(15);
JTextField Address1line = new JTextField(15);
JTextField postcode = new JTextField(15);
JTextField Destination = new JTextField(15);
JTextField Date = new JTextField(15);
JTextField MilesTravelling = new JTextField(15);
JLabel lblMsg = new JLabel ("Name",JLabel.LEFT);
Log(){
super("Customer GUI");
setSize(300,400);
setLocation(400,250);
panel.setLayout(null);
FullName.setBounds(70,30,150,20);
Address1line.setBounds(70,80,150,20);
postcode.setBounds(70,130,150,20);
Destination.setBounds(70,180,150,20);
Date.setBounds(70,230,150,20);
MilesTravelling.setBounds(70,280,150,20);
Confirm.setBounds(105,320,80,20);
panel.add(lblMsg);
panel.add(Confirm);
panel.add(FullName);
panel.add(Address1line);
panel.add(postcode);
panel.add(Destination);
panel.add(Date);
panel.add(MilesTravelling);
getContentPane().add(label1);
getContentPane().add(panel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
}
JFrames ContentPane uses BorderLayout, BorderLayout has 5th areas and only one JComponent can be placed in the one of areas
.
getContentPane().add(label1); //JFrames CENTER area
getContentPane().add(panel);
then last added JComponent can be visible
.
getContentPane().add(panel);
suggestions don't to use NullLayout and Log frameTabel = new Log(); should be wrapped into invokeLater (Swing GUI should be created and intialized on EventDispatchThread), more to see in Oracle tutorial Initial Thread