I am coding a contact list application in eclipse using Java Swing.
How can I get a simple table layout that contains just columns and rows?
I don't want row or column labels.
Something like this:
first name: john
middle name: franklin
last name: doe
Where the names would be editable text boxes etc.
What's the best component to use?
I will also have buttons below the text fields.
Currently I have a JFrame which is running correctly. It pulls up a window that has my menu options correct. But when I try to do this:
myFrame.setLayout(new GridLayout(6, 2));
I get an error. I would like to have a grid layout of two columns and 5 rows (maybe 6).
I want to have a label on the left column, and a text box on the right column.
then two buttons at the bottom, centered.
You'd better of breaking your fields and controls (buttons) into separate panels, this allows you to supply different layout managers for each.
I'd start with a base JPanel using a BorderLayout.
Onto this, I'd add the "fields" panel at the CENTER position and the controls (buttons) at the SOUTH position.
For the fields, I'd use a GridBagLayout, but I'm picky like that, and for the controls panel I'd probably use a FlowLayout (unless you have access to a nice ButtonLayout manager ;))
This means you could end up with something like
UPDATED with code sample
public class FormPanel extends JPanel {
private JTextField fldFirstName;
private JTextField fldMiddleName;
private JTextField fldLastName;
private JTextField fldDateOfBirth;
private JTextField fldEMail;
private JButton okButton;
private JButton cancelButton;
public FormPanel() {
setLayout(new BorderLayout());
add(createFieldsPane());
add(createButtonsPane(), BorderLayout.SOUTH);
}
public JPanel createButtonsPane() {
JPanel panel = new JPanel(new FlowLayout());
panel.add((okButton = createButton("Ok")));
panel.add((cancelButton = createButton("Cancel")));
return panel;
}
protected JButton createButton(String text) {
return new JButton(text);
}
public JPanel createFieldsPane() {
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(2, 2, 2, 2);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
panel.add(createLabel("First Name:"), gbc);
gbc.gridy++;
panel.add(createLabel("Middle Name:"), gbc);
gbc.gridy++;
panel.add(createLabel("Last Name:"), gbc);
gbc.gridy++;
panel.add(createLabel("Date of Birth:"), gbc);
gbc.gridy++;
panel.add(createLabel("EMail:"), gbc);
gbc.gridy = 0;
gbc.gridx++;
gbc.weightx = 1;
panel.add((fldFirstName = createField()), gbc);
gbc.gridy++;
panel.add((fldLastName = createField()), gbc);
gbc.gridy++;
panel.add((fldMiddleName = createField()), gbc);
gbc.gridy++;
panel.add((fldDateOfBirth = createField()), gbc);
gbc.gridy++;
panel.add((fldEMail = createField()), gbc);
JPanel filler = new JPanel();
filler.setOpaque(false);
gbc.gridy++;
gbc.weightx = 1;
gbc.weighty = 1;
panel.add(filler, gbc);
return panel;
}
protected JLabel createLabel(String text) {
return new JLabel(text);
}
protected JTextField createField() {
JTextField field = new JTextField(12);
return field;
}
}
Related
I am trying to make a login page but unfortunately my formPanel's border is so out of bounds. Here in the pic you can see the titled border is way out. I need it to be more around my panel with login form:
I see that when creating this formPanel it is that big and the border just surround it. I tried with setPrefferedSize but its not working. How can I fix it?
Here is my code:
public class LoginPanel extends JPanel {
private JLabel title;
public LoginPanel() {
this.setBackground(new Color(0, 128, 43));
this.setBorder(new EmptyBorder(10, 10, 10, 10));
this.setLayout(new BorderLayout());
//adding the title
title = new JLabel("<html><h1><strong><i>Krisko Beatz Quiz</i></strong></h1><hr></html>");
title.setForeground(Color.BLACK);
JPanel titlePanel = new JPanel();
titlePanel.setBackground(new Color(0, 128, 43));
titlePanel.add(title);
this.add(titlePanel, BorderLayout.PAGE_START);
//creating the login form
JPanel formPanel = new JPanel(new GridBagLayout());
formPanel.setBackground(new Color(0, 128, 43));
//gbc
GridBagConstraints gbc = new GridBagConstraints();
//gbc for username
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(5, 0, 0, 0);
JLabel username = new JLabel("Username: ");
username.setForeground(Color.BLACK);
formPanel.add(username, gbc);
//gbc for textfield
gbc.gridx = 1;
gbc.gridy = 0;
JTextField usernameField = new JTextField(10);
formPanel.add(usernameField, gbc);
//gbc for pass
gbc.gridx = 0;
gbc.gridy = 1;
JLabel password = new JLabel("Password: ");
password.setForeground(Color.BLACK);
formPanel.add(password, gbc);
//gbc for pass field
gbc.gridx = 1;
gbc.gridy = 1;
JPasswordField passField = new JPasswordField(10);
formPanel.add(passField, gbc);
//gbc for button
gbc.gridx = 1;
gbc.gridy = 2;
gbc.gridwidth = 2;
gbc.anchor = GridBagConstraints.PAGE_END;
JButton loginButton = new JButton("Login");
formPanel.add(loginButton, gbc);
//add border to the form panel
TitledBorder title = BorderFactory.createTitledBorder("Login");
formPanel.setBorder(title);
this.add(formPanel, BorderLayout.CENTER);
}
}
I tried with setPrefferedSize but its not working.
Don't try to manage the preferredSize of a component.
I would guess the problem is that you are using setSize(...) instead of pack().
You should be using pack() AFTER all the components have been added to the frame. Then all the components will be displayed at their preferred size.
Edit:
I originally misread your question and changed my original answer. The point in my original answer of using the "wrapper" panel is to give extra space to the wrapper panel, while keeping the "formPanel" at a fixed size. This way the titled border will remain around the formPanel even as the frame size is changed.
So again the basic approach for this type of solution is:
JPanel wrapper = new JPanel( new GridBagLayout() );
wrapper.add(formPanel, new GridBagConstraints());
this.add(wrapper, BorderLayout.CENTER);
//this.add(formPanel, BorderLayout.CENTER);
I took your LoginPanel class as is, and wrote a Main class around it to start the GUI.
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new LoginPanel());
frame.pack();
frame.setVisible(true);
});
}
}
Especially note, I did no explicit setting of the size, only a pack() call which resizes everything to its preferred size according to your layout.
The resulting layout looks perfectly fine to me.
So the conclusion is: Your LoginPanel is fine, but probably there is something wrong in your other code which you didn't post here.
Using GridbagLayout, I'm trying to display a JTable. Here's my code (simplified). The jpanel code that I'll put is shown after a button click.
My Panel :
optionspane = new JPanel();
optionspane.setLayout(new GridBagLayout());
optionspane.setBounds(0, 0, myframe.getWidth(), myframe.getHeight());
My Panel's Children :
GridBagConstraints dgbc=new GridBagConstraints();
dgbc.gridx=0;
dgbc.gridy=0;
dgbc.weightx = 1.0;
dgbc.weighty = 1.0;
dgbc.anchor=GridBagConstraints.CENTER;
dgbc.fill=GridBagConstraints.BOTH;
dgbc.insets=new Insets(5,10,10,5);
datapane.add(ServiceInterface.eighthpanel(), dgbc);
dgbc.gridx=0;
dgbc.gridy=1;
gbc.anchor=GridBagConstraints.SOUTH;
dgbc.fill=GridBagConstraints.BOTH;
dgbc.insets=new Insets(5,0,5,5);
datapane.add(ServiceInterface.ninethpanel(), dgbc);
Here is the panel method that contains the JPanel :
public static JPanel eighthpanel() throws IOException{
pane.setLayout(new GridBagLayout());
GridBagConstraints gbc=new GridBagConstraints();
pane.setBorder(BorderFactory.createLineBorder(Color.BLACK));
JLabel datawelcome=new JLabel("Please Enter the QoS values'");
datawelcome.setFont(new Font("Ubuntu", Font.BOLD, 16));
gbc.gridx = 0;
gbc.gridy = 1;
gbc.fill=GridBagConstraints.BOTH;
gbc.fill=GridBagConstraints.REMAINDER;
gbc.insets=new Insets(10,20,10,20);
pane.add(datawelcome, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
gbc.weightx=1;
gbc.weightx=1;
gbc.fill=GridBagConstraints.BOTH;
gbc.fill=GridBagConstraints.REMAINDER;
gbc.insets=new Insets(10,20,10,20);
//pane.add(new JScrollPane(displayJTable), gbc);
pane.add(myscrol, gbc);
return pane;
}
Here is how I fill my JTable (inside a button listener):
mytableclass=new Mytable();
displayJTable = new JTable(myModel);
displayJTable.getColumnModel().getColumn(0).setPreferredWidth(60);
displayJTable.setPreferredScrollableViewportSize(new Dimension(525,250));
displayJTable.setFillsViewportHeight(true);
displayJTable.setLocation(5,5);
myscrol.add(displayJTable);
myscrol.getViewport().setViewPosition(new Point(0,0));
myscrol.setPreferredSize(new Dimension(600,400));
principalpane.setVisible(false);
datapane.setVisible(true);
}
}});
I resolved my problem. I added an other panel (default layout) and I added the scrollPane to this panel inside the button.actionlistener.
I think because of the Static characteristic of the gridbaglayout.
I'm coding a small project for my high school class but I have run into a bit of an issue now that I'm working with frames. I'm trying to find the easiest and most efficient way to arrange the contents of a panel in java 7 (Note: this means SpringUtilities is not an option)
For the arrangement of each item I wanted it to have the option to type in your name at the top and then have 3 buttons in the same row below the name box
and the code I have so far is
private static void userInterface(){
//Declare and assign variables
final String[] options = {"Lvl 1", "Lvl 2", "Lvl 3"};
int optionsAmt = options.length;
//Create the panel used to make the user interface
JPanel panel = new JPanel(new SpringLayout());
//Create the name box
JTextField tf = new JTextField(10);
JLabel l = new JLabel("Name: ");
l.setLabelFor(tf);
panel.add(l);
panel.add(tf);
//Create 3 buttons with corresponding values of String options
for(int a = 0; a < optionsAmt; a++){
JButton b = new JButton(options[a]);
panel.add(new JLabel());
panel.add(b);
}
//Layout the panel
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.pack();
f.setTitle("Number Game");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
"Easy" is a relative term, for example, you could do something like...
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridLayout(2, 1));
JPanel fieldPane = new JPanel();
fieldPane.add(new JTextField(10));
add(fieldPane);
JPanel buttonPane = new JPanel();
buttonPane.add(new JButton("1"));
buttonPane.add(new JButton("2"));
buttonPane.add(new JButton("3"));
add(buttonPane);
}
}
or something like...
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = 3;
gbc.gridx = 0;
gbc.gridy = 0;
add(new JTextField(10), gbc);
gbc.gridwidth = 1;
gbc.gridy = 1;
add(new JButton("1"), gbc);
gbc.gridx++;
add(new JButton("2"), gbc);
gbc.gridx++;
add(new JButton("3"), gbc);
}
}
Both are easy, both do the job, but which you would use would depend greatly on what you want to achieve...
Take a look at Laying Out Components Within a Container for more details
Why are the JLabel, JTextField and JButton components on the FieldBox panel not displaying?
Please let me know if I can add anything to this question to make it more answerable!
The field box (one of which is created for each of several instance fields):
public class FieldBox extends javax.swing.JPanel {
JLabel label;
JTextField textField;
public FieldBox() {
setBackground(Color.RED);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
label = new JLabel();
gbc.gridx = 0;
gbc.gridy = 0;
add(label,gbc);
textField = new JTextField();
gbc.gridx = 1;
gbc.gridy = 0;
add(textField, gbc);
JButton editBtn = new JButton("edit");
gbc.gridx = 2;
gbc.gridy = 0;
add(editBtn, gbc);
JButton saveBtn = new JButton ("save");
gbc.gridx = 3;
gbc.gridy = 0;
add(saveBtn, gbc);
label.setVisible(true);
label.setBackground(Color.yellow);
setVisible(true);
initComponents();
}
The panel onto which the boxes are added: (the panel appears. I know this panel loads because I can see its background. I can also see the "tit" JLabel, which I'm using for testing. Also, when I load the boxes onto it using a gridLayout (as shown below), I see the background of one of the boxes, but none of its contents are displayed, and also there should be three boxes shown but I only see one. Using a GridBagLayout
public class ShowBook extends javax.swing.JPanel {
public ShowBook(Book b) {
setLayout(new GridLayout(1,6));
setBackground(Color.GREEN);
String[] fieldTitles = {"title", "catalog", "publisher" };
JLabel tit = new JLabel("tit");
add(tit);
for (String s : fieldTitles){
FieldBox fb = new FieldBox();
fb.label.setText(s + ": ");
fb.textField.setText(getField(b, s));
System.out.println("in text field" + fb.textField.getText());
fb.revalidate();
fb.setVisible(true);
add (fb);
}
revalidate();
setVisible(true);
}
The panel onto which the ShowBook panel (above) is added. This panel also contains a listbox, which lists books in the collection, and a button to launch a ShowBook panel with the selected book as parameter.
public class ShowLib extends javax.swing.JPanel {
/**
* Creates new form ShowLib
*/
public ShowLib(Library l) {
setLayout(new BorderLayout()) ;
setBackground(Color.WHITE);
JPanel listPanel = new JPanel();
listPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
final JList bookList = new JList();
bookList.setVisible(true);
bookList.setPreferredSize(new Dimension(150, 600));
bookList.setBackground(Color.yellow);
DefaultListModel dlm = new DefaultListModel();
for (Book b : l.libList){
dlm.addElement(b);
}
bookList.setModel(dlm);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = gbc.BOTH;
listPanel.add(bookList, gbc);
JButton showBtn = new JButton("show");
gbc.gridy = gbc.RELATIVE;
listPanel.add(showBtn, gbc);
showBtn.addActionListener(new ActionListener () {
#Override
public void actionPerformed(ActionEvent e){
Book b = (Book) bookList.getSelectedValue();
ShowBook db = new ShowBook (b);
System.out.println("Clicked");
add (db, BorderLayout.CENTER);
revalidate();
}
});
revalidate();
setVisible(true);
add(listPanel, BorderLayout.WEST);
}
Where the ShowLib panel is added to the main JFrame. I know this works because that panel displays properly
void showLib() {
ShowLib sl = new ShowLib(l);
sl.setVisible(true);
setContentPane(sl);
revalidate();
// this.revalidate();
// this.pack();
System.out.println("showlibClicked");
}
The problem was the line initComponents(); at the bottom of the FieldBox class.
Lesson learned: If you're not using NetBeans visual GUI editor, GET RID OF THIS LINE!
I have the structure as you can see in the picture.
For both panels, GridBagLayout is used.
The problem is that the text field inside the scrollpane is not entirely visible.
The parent panel stretches only for the buttons to become visible, but when the scroll bar appears, it just overlap with the text field.
Is there an easy solution to fix this (don't want to deal with setting custom / preferred / minimum heights)?
Panel structure :
Problem :
Ok, here is an SSCCE
public class Main {
JFrame frame;
private JPanel mainPanel;
private JButton button1;
private JButton button2;
private JTextField someTextTextField;
public static void main(String[] args) {
Main main = new Main();
main.show();
}
private void show() {
frame = new JFrame("Frame");
frame.setContentPane(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
{
$$$setupUI$$$();
}
/**
* Method generated by IntelliJ IDEA GUI Designer
* >>> IMPORTANT!! <<<
* DO NOT edit this method OR call it in your code!
*
* #noinspection ALL
*/
private void $$$setupUI$$$() {
mainPanel = new JPanel();
mainPanel.setLayout(new GridBagLayout());
mainPanel.setPreferredSize(new Dimension(209, 30));
final JPanel panel1 = new JPanel();
panel1.setLayout(new GridBagLayout());
GridBagConstraints gbc;
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.weightx = 0.5;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.BOTH;
mainPanel.add(panel1, gbc);
button1 = new JButton();
button1.setText("Button");
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
panel1.add(button1, gbc);
button2 = new JButton();
button2.setText("Button");
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
panel1.add(button2, gbc);
final JScrollPane scrollPane1 = new JScrollPane();
scrollPane1.setAlignmentX(0.0f);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 0.5;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.BOTH;
mainPanel.add(scrollPane1, gbc);
someTextTextField = new JTextField();
someTextTextField.setText("some text");
scrollPane1.setViewportView(someTextTextField);
}
/**
* #noinspection ALL
*/
public JComponent $$$getRootComponent$$$() {
return mainPanel;
}
}
Try and use a JTextArea instead of a JTextField. And if you don't want to set custom/preferred/minimum sizes, you can use the JTextArea.setRows(int rows) method. I hope that helps.