Java JList and list problems - java

I added list items to JList
numbersList.add("first example");
numbersList.add("second example");
numbersList.add("third example");
and when I add new text or number to field it would would be added into list and showed at JList. Here my code, I just want to make that when I push button new element appear at JList fullList from list numberList which has been added from textfield numberTxtFld.
p.s i have removed some unnecessary code.
package average;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
public class Surface extends JLabel{
private JTextField numberTxtFld;
private JLabel topLabel;
private JLabel sumLabel;
private JLabel avgLabel;
private JLabel maxLabel;
private JLabel minLabel;
private JLabel amountLabel;
private JLabel listLabel;
private JLabel resultLabel;
private JLabel sumAnswerFld;
private JLabel avgAnswerFld;
private JLabel maxAnswerFld;
private JLabel minAnswerFld;
private JLabel amountAnswerFld;
private JLabel fullListLabel;
private JList fullList;
final List<String> numbersList = new ArrayList<String>();
private JButton submitBtn;
private JButton closeBtn;
private JPanel panel;
private int arrayIndex = 0;// used for components adding into array
public Surface(){
panel = new JPanel();
panel.setBackground(Color.WHITE);
panel.setSize(300, 300);
panel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
topLabel = new JLabel("Enter your number and push submit");
gbc.gridwidth = 3;
gbc.gridx = 0; // column
gbc.gridy = 0; // row
panel.add(topLabel, gbc);
gbc.gridwidth = 1; // setting grid column with to default
fullListLabel = new JLabel("Full list");
gbc.gridx = 2;
gbc.gridy = 1;
panel.add(fullListLabel, gbc);
amountLabel = new JLabel("Amount");
gbc.gridx = 0;
gbc.gridy = 5;
panel.add(amountLabel, gbc);
amountAnswerFld = new JLabel("0");
gbc.gridx = 1;
gbc.gridy = 5;
panel.add(amountAnswerFld, gbc);
numberTxtFld = new JTextField();
numberTxtFld.setColumns(10);
gbc.gridx = 0;
gbc.gridy = 1;
panel.add(numberTxtFld, gbc);
submitBtn = new JButton("Submit");
gbc.gridx = 1;
gbc.gridy = 1;
submitBtn.addActionListener(
new ActionListener(){
#Override
public void actionPerformed(ActionEvent event) {
String text = numberTxtFld.getText();
numbersList.add(text);
}
}
);
panel.add(submitBtn, gbc);
numbersList.add("first example");
numbersList.add("second example");
numbersList.add("third example");
fullList = new JList(numbersList.toArray());
fullList.setVisibleRowCount(6);
fullList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
gbc.gridheight = 6;
gbc.gridx = 2;
gbc.gridy = 2;
panel.add(new JScrollPane(fullList), gbc);
gbc.gridheight = 1; // setting grid column with to default
add(panel);
}
}

You will need to create a ListModel. As what you are doing is very simple you can use the DefaultListModel.
you will need to declare
private DefaultListModel defaultListModel;
and instantiate it
defaultListModel = new DefaultListModel();
then attach it to your JList in the JLists constructor
fullList = new JList(defaultListModel);
you will then need to add your items to the defaultListModel, probably in a loop
for (Object o : numbersList) {
defaultListModel.addElement(o);
}
Finally in your action listener you now need to call the addElement method on the defaultListModel instead
String text = numberTxtFld.getText();
defaultListModel.add(text);
Then you should get everything to work as you desire plus all the update events are handled for you.

When you do this:
fullList = new JList(numbersList.toArray());
You are not magically attaching the JList to numbersList, you are simply populating the JList with the content of numbersList at that point, which, of course, does not include any items added later when your button is pressed.
You have at least three options:
The most basic solution is to explicitly add a new item to fullList in your submitBtn action listener. You have a number of options. You can just add the new item to fullList from submitBtn, which is simple and may be adequate from your application. To do this, make sure the list's model is a DefaultListModel, then you can use ((DefaultListModel)getModel()).addElement() to add an item.
DefaultListModel model = new DefaultListModel();
fullList.setModel(model);
// to add an element (during initial population, and action listener):
model.addElement("the element");
A more robust solution would be to completely repopulate fullList based on the current contents of numbersList, and do that from your action listener to resync the GUI to the data. This may not be desirable for other reasons, e.g. it may be unacceptable to clear the list first because of its effect on the current item selection, etc. Depends on your requirements. You could use JList's setListData() for this.
// any time you want to repopulate the list:
fullList.setListData(numbersList.toArray());
But bear in mind that this sets the list model to a read-only model, and you will not be able to use getModel().addElement() later.
An even more robust, and the generally preferred, solution is to implement a ListModel that reflects the contents of numbersList and assign that ListModel to your JList. This can lead to very clean code that lets you perform any operation you want on your list while keeping the GUI and data in sync. Rather than repost code here, you can find a simple implementation in the answer to this question.
Hope that helps.

Related

Java Swing - Change number of text fields based on a variable

I'd like to have a GUI that can adapt to user input, rather than making a different panel for each option.
The first panel has a number of buttons to choose from, each will bring you to the next panel that will contain text entry fields.
Option A: Has 2 components and should open a panel with 4 text fields.
Option B: Has 3 components and should open a panel with 6 text fields.
Specifically, option A is a recipe with two components, and option B is a recipe with 3 components. Each component has a lot number and an expiration date. So both panels will have the same two types of fields: lot number and expiration date. The number and names of components is what will change.
Can I have the same panel be able to adapt to a number of components sent to it based on which of the two options was selected? Or do I have to make two separate panels, one with 4 fields and one with 6?
Here's one idea:
Map<String, JTextField> fieldMap = new HashMap<String, JTextField>()
for(int i = 0; i < recipe.length; i++)
{
fieldMap.put("field" + i, new JTextField());
}
Idea derived from Creating a variable name using a String value
The code below addresses specifically your question statement, although I can't help thinking that you probably want something more generic, i.e. where there are more than two options. Also, the below code is only one possible implementation of your stated requirements.
The idea in the below code is to initially create all the required GUI components in a single container and simply change the visibility of the [optional] components depending on the selected option.
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 javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerDateModel;
public class Opciones implements ActionListener {
private JFrame frame;
private JLabel expiryThirdLabel;
private JLabel lotThirdLabel;
private JRadioButton twoRadioButton;
private JRadioButton threeRadioButton;
private JSpinner expiryFirstSpinner;
private JSpinner expirySecondSpinner;
private JSpinner expiryThirdSpinner;
private JTextField lotFirstTextField;
private JTextField lotSecondTextField;
private JTextField lotThirdTextField;
public void actionPerformed(ActionEvent event) {
Object src = event.getSource();
boolean flag;
if (twoRadioButton == src) {
flag = false;
}
else if (threeRadioButton == src) {
flag = true;
}
else {
flag = false;
JOptionPane.showMessageDialog(frame,
"Unrecognized source.",
"WARNING",
JOptionPane.WARNING_MESSAGE);
}
expiryThirdLabel.setVisible(flag);
expiryThirdSpinner.setVisible(flag);
lotThirdLabel.setVisible(flag);
lotThirdTextField.setVisible(flag);
frame.pack();
}
private void createAndDisplayGui() {
frame = new JFrame("Options");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createTopPanel(), BorderLayout.PAGE_START);
frame.add(createForm(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createForm() {
JPanel form = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.LINE_START;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets.bottom = 5;
gbc.insets.left = 5;
gbc.insets.right = 5;
gbc.insets.top = 5;
JLabel lotFirstLabel = new JLabel("Lot Number");
form.add(lotFirstLabel, gbc);
gbc.gridx = 1;
lotFirstTextField = new JTextField(6);
form.add(lotFirstTextField, gbc);
gbc.gridx = 2;
JLabel expiryFirstLabel = new JLabel("Expiry");
form.add(expiryFirstLabel, gbc);
gbc.gridx = 3;
expiryFirstSpinner = createSpinner();
form.add(expiryFirstSpinner, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
JLabel lotSecondLabel = new JLabel("Lot Number");
form.add(lotSecondLabel, gbc);
gbc.gridx = 1;
lotSecondTextField = new JTextField(6);
form.add(lotSecondTextField, gbc);
gbc.gridx = 2;
JLabel expirySecondLabel = new JLabel("Expiry");
form.add(expirySecondLabel, gbc);
gbc.gridx = 3;
expirySecondSpinner = createSpinner();
form.add(expirySecondSpinner, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
lotThirdLabel = new JLabel("Lot Number");
lotThirdLabel.setVisible(false);
form.add(lotThirdLabel, gbc);
gbc.gridx = 1;
lotThirdTextField = new JTextField(6);
lotThirdTextField.setVisible(false);
form.add(lotThirdTextField, gbc);
gbc.gridx = 2;
expiryThirdLabel = new JLabel("Expiry");
expiryThirdLabel.setVisible(false);
form.add(expiryThirdLabel, gbc);
gbc.gridx = 3;
expiryThirdSpinner = createSpinner();
expiryThirdSpinner.setVisible(false);
form.add(expiryThirdSpinner, gbc);
return form;
}
private JSpinner createSpinner() {
SpinnerDateModel sdm = new SpinnerDateModel();
JSpinner spinner = new JSpinner(sdm);
spinner.setEditor(new JSpinner.DateEditor(spinner, "MM/dd/yyyy")); // USA format
return spinner;
}
private JPanel createTopPanel() {
JPanel topPanel = new JPanel();
JLabel label = new JLabel("Number of Components");
topPanel.add(label);
ButtonGroup buttonGroup = new ButtonGroup();
twoRadioButton = new JRadioButton("Two");
twoRadioButton.addActionListener(this);
twoRadioButton.setSelected(true);
buttonGroup.add(twoRadioButton);
topPanel.add(twoRadioButton);
threeRadioButton = new JRadioButton("Three");
threeRadioButton.addActionListener(this);
buttonGroup.add(threeRadioButton);
topPanel.add(threeRadioButton);
return topPanel;
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new Opciones().createAndDisplayGui());
}
}
Initially, the GUI looks like this
And after selecting Three radio button
Refer to the following.
How to Use Buttons, Check Boxes, and Radio Buttons
How to Make Frames (Main Windows)
How to Use Spinners
How to Use GridBagLayout
How to Write an Action Listener

Java Swing: JScrollPane containing JTextArea filled with text gets very small when moved to 2nd monitor

I have a Java Swing GUI that consists of some JScrollPanes containing JTextAreas that get filled with data so that the scrollbars appear. Once the scrollbars appear, when I move the window to my second monitor, the JScrollPane gets very small so that I can no longer see the text it contains.
Example:
Here is the window on my main monitor with the JScrollPane filled with text:
Here is the window after I filled it with text and moved it to the second monitor:
Here is a small example program that demonstrates the problem:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class Main extends JFrame {
public Main() {
Test theGui = new Test();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(true);
add(theGui);
pack();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Main();
}
});
}
}
class Test extends JPanel {
private static final int PADDING = 3;
private JLabel label;
private JTextArea textarea;
private JScrollPane scrollpane;
private GridBagConstraints gbc;
public Test() {
super(new GridBagLayout());
label = new JLabel("Fill this text box with text so the scrollbars appear, then move the window to 2nd monitor:");
textarea = new JTextArea(10, 40);
scrollpane = new JScrollPane(textarea);
gbc = new GridBagConstraints();
gbc.gridheight = 1;
gbc.insets = new Insets(PADDING, PADDING, PADDING, PADDING);
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridwidth = 4;
gbc.gridx = 0;
gbc.gridy = 0;
add(label, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
add(scrollpane, gbc);
}
}
Note that the JScrollPane only gets very small when moving to the other monitor when it is filled with text. If there is no text in it, it seems to stay the right size.
My question is, how can I prevent the JScrollPane from getting very small when I move the window to my second monitor?
GridBagLayout will revert to the components minimumSize property when the available space for the component is less then the components preferredSize.
You can override this by using the GridBagConstraints, weightx/weighty properties, for example.
gbc.gridx = 0;
gbc.gridy = 1;
gbc.weightx = 1;
gbc.weighty = 1;
add(scrollpane, gbc);

Java Swing Component Resizing with GridBagLayout

I've been having trouble with my Java Swing GUI. First of all, I created a panel with the GridBagLayout on it and added all my labels to it. However, I also created a panel to the right of the other JPanel that adds in a button and 2 sliders which are suppose to like match with the labels.
The problem is that the JLabels are smaller than the components from the right of the other panel which, makes it look like this....
ex. water option -- JSLIDER (the jslider looks a lot bigger)
I tried to make the components larger by adding ipadx to a bigger value and also I've tried to set the grid width for the labels panel bigger, but nothing seems to work. It just doesn't respond.
Here is the code:
package gui;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
public class Options extends JFrame{
//water option (button changes text on or off)
//make a button listener
JSlider renderDistance;
JSlider grassDensity;
JButton waterToggleButton;
JLabel rdTitle;
JLabel gdTitle;
JLabel wtTitle;
JButton buttonClose;
static final int RD_MIN_VALUE = 0;
static final int RD_MAX_VALUE = 1000;
static final int RD_INIT_VALUE = 500;
static final int GD_MIN_VALUE = 0;
static final int GD_MAX_VALUE = 1000;
static final int GD_INIT_VALUE = 500;
public Options() {
this.setTitle("Settings");
this.setSize(getMaximumSize());
this.setLocationRelativeTo(null);
createView();
this.setVisible(true);
}
private void createView() {
//Making panels and adding them to window*
JPanel pOptions = new JPanel();
this.add(pOptions);
//These are for the labels that I added so people know which option they are using
JPanel pOptionLabels = new JPanel(new GridBagLayout());
pOptions.add(pOptionLabels);
//These are for the middle columns, the objects like button and slider
JPanel pOptionObjects = new JPanel(new GridBagLayout());
pOptions.add(pOptionObjects);
//Making panels and adding them to window*
//Initializing Objects*
GridBagConstraints gbcLabels = new GridBagConstraints();
GridBagConstraints gbcObjects = new GridBagConstraints();
renderDistance = new JSlider(RD_MIN_VALUE, RD_MAX_VALUE, RD_INIT_VALUE);
grassDensity = new JSlider(GD_MIN_VALUE, GD_MAX_VALUE, GD_INIT_VALUE);
waterToggleButton = new JButton("On");
rdTitle = new JLabel("Render Distance");
gdTitle = new JLabel("Grass Density");
wtTitle = new JLabel("Water Terrain Visibility");
//Initializing Objects*
//Giving objects some attributes using methods*
renderDistance.setMinorTickSpacing(100);
renderDistance.setMajorTickSpacing(500);
renderDistance.setPaintTicks(true);
renderDistance.setPaintLabels(true);
grassDensity.setMinorTickSpacing(100);
grassDensity.setMajorTickSpacing(500);
grassDensity.setPaintTicks(true);
grassDensity.setPaintLabels(true);
gbcLabels.gridx = 0;
gbcLabels.gridy = 0;
gbcLabels.anchor = GridBagConstraints.LINE_START;
gbcObjects.gridx = 0;
gbcObjects.gridy = 0;
waterToggleButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(waterToggleButton.getText().equals("Off")) {
waterToggleButton.setText("On");
}else {
waterToggleButton.setText("Off");
}
}
});
//Giving objects some attributes using methods*
//Add things to panel ex. p.add();
pOptionLabels.add(rdTitle, gbcLabels);
gbcLabels.gridy++;
pOptionLabels.add(gdTitle, gbcLabels);
gbcLabels.gridy++;
pOptionLabels.add(wtTitle, gbcLabels);
gbcObjects.gridx++;
pOptionObjects.add(renderDistance, gbcObjects);
gbcObjects.gridy++;
pOptionObjects.add(grassDensity, gbcObjects);
gbcObjects.gridy++;
pOptionObjects.add(waterToggleButton, gbcObjects);
}
public static void main(String[] args) {
new Options();
}
}
Change the way you are thinking. Instead of trying to layout all the labels and all the "other" components in separate containers, consider putting them all in the same container.
This way, when they are laid out, the layout calculations are made in relationship to all the components in a single context.
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
public class Options extends JFrame {
//water option (button changes text on or off)
//make a button listener
JSlider renderDistance;
JSlider grassDensity;
JButton waterToggleButton;
JLabel rdTitle;
JLabel gdTitle;
JLabel wtTitle;
JButton buttonClose;
static final int RD_MIN_VALUE = 0;
static final int RD_MAX_VALUE = 1000;
static final int RD_INIT_VALUE = 500;
static final int GD_MIN_VALUE = 0;
static final int GD_MAX_VALUE = 1000;
static final int GD_INIT_VALUE = 500;
public Options() {
this.setTitle("Settings");
createView();
pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
private void createView() {
//Making panels and adding them to window*
JPanel pOptions = new JPanel();
this.add(pOptions);
//These are for the labels that I added so people know which option they are using
JPanel pOptionLabels = new JPanel(new GridBagLayout());
pOptions.add(pOptionLabels);
GridBagConstraints gbc = new GridBagConstraints();
renderDistance = new JSlider(RD_MIN_VALUE, RD_MAX_VALUE, RD_INIT_VALUE);
grassDensity = new JSlider(GD_MIN_VALUE, GD_MAX_VALUE, GD_INIT_VALUE);
waterToggleButton = new JButton("On");
rdTitle = new JLabel("Render Distance");
gdTitle = new JLabel("Grass Density");
wtTitle = new JLabel("Water Terrain Visibility");
//Initializing Objects*
//Giving objects some attributes using methods*
renderDistance.setMinorTickSpacing(100);
renderDistance.setMajorTickSpacing(500);
renderDistance.setPaintTicks(true);
renderDistance.setPaintLabels(true);
grassDensity.setMinorTickSpacing(100);
grassDensity.setMajorTickSpacing(500);
grassDensity.setPaintTicks(true);
grassDensity.setPaintLabels(true);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.LINE_START;
gbc.insets = new Insets(2, 2, 2, 2);
waterToggleButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (waterToggleButton.getText().equals("Off")) {
waterToggleButton.setText("On");
} else {
waterToggleButton.setText("Off");
}
}
});
//Giving objects some attributes using methods*
//Add things to panel ex. p.add();
pOptionLabels.add(rdTitle, gbc);
gbc.gridy++;
pOptionLabels.add(gdTitle, gbc);
gbc.gridy++;
pOptionLabels.add(wtTitle, gbc);
gbc.gridx++;
gbc.gridy = 0;
pOptionLabels.add(renderDistance, gbc);
gbc.gridy++;
pOptionLabels.add(grassDensity, gbc);
gbc.gridy++;
pOptionLabels.add(waterToggleButton, gbc);
}
public static void main(String[] args) {
new Options();
}
}
What you are experiencing is technically correct since you have two JPanels with two separate instances of the GridBagLayout manager so the rows (and columns) in one layout manager have no information about the rows in the other.
A single GridBagLayout is the way to go if you plan to use JComponents inside them and create a table like appearance. You can later add others JPanels (with different layout managers or with more GridBagLayouts!) but INSIDE your main GridBagLayout JPanel.
GridBagLayout is a really powerful layout, I would recommend sticking with is and master it since it will help you layout things nicely (and fast) in the long run.
This is a great resource to learn more about the GridBagLayout:
https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
One small comment: IMO the GridBagLayout is not the best layout manager to use as the "root" layout container. I would instead recommend creating a "root" JPanel with a BorderLayout() and add your GridBagLayout JPanel to the center of the BorderLayout panel add(yourGridPanel, BorderLayout.CENTER) since the BorderLayout usually gives for free the ability for things to fill horizontally/vertically and will let you pack your window nicely at the center (with the possibility of adding more things later to the NORTH/SOUTH/EAST/WEST sides).
Good luck!

positionnig myJTextField beside JComboBox

I want to creat a palet with many JComboBox. like that :
for(int x=0; x<MAX; x++){
box[x] = new JComboBox(new String[]{"op1", "op2", "op3");
}
at the right of each JComboBox i want to create many JTextField. So, in my palet i will have some think like that:
myJComboBox1 myJTextField
anotherJTextField
anotherJTextField
myJComboBox2 myJTextField
anotherJTextField
anotherJTextField
...
How can i do that please ? I tried by setBounds and other layout like FlowLayout and GridLayout but without success.
GridBagLayout is the best solution. However, if you are new to Swing, it might be a bit over complicated. In that case:
Use GridLayout(0, 2) for the main panel.
Wrap the combobox in a Panel with a border layout and add it to north. Add it to the main panel.
Use another panel with GridLayout(0,1) add your text fields to it and add it to the main panel.
and loop...
Adding sample code:
package snippet;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class BorderLayoutTest extends JFrame {
static private int MAX = 10 ;
public BorderLayoutTest() {
super(BorderLayoutTest.class.getName());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initComponents();
}
private void initComponents() {
setLayout(new GridLayout(0, 2));
for(int i = 0; i < MAX; i++) {
add(createComboPanel());
add(createPanelWithTextFields());
}
pack();
}
public Component createComboPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.add(new JComboBox<>(new String[] { "First Option", "Second Option", "Third Option" }), BorderLayout.NORTH);
return panel;
}
private Component createPanelWithTextFields() {
JPanel panel = new JPanel(new GridLayout(0, 1));
panel.add(new JTextField(30));
panel.add(new JTextField(30));
panel.add(new JTextField(30));
return panel;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override public void run() {
new BorderLayoutTest().setVisible(true);
}
});
}
}
Take a look at GridBagLayout. You can use your window like a table.
myPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
JLabel lbl = new JLabel("bla");
myPanel.add(lbl, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.weightx = 3;
JTextField tf = new JTextField();
myPanel.add(tf, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 1;
gbc.weightx = 3;
JTextField othertf = new JTextField();
myPanel.add(othertf, gbc);
You can even set weights and so on for the GridBagConstraints. It is completly adjusted as table. That will result in something like that:
label textfield
textfield
Just re-read the question. Just replace the JLabels with JComboBoxes and it answers your question a little bit better ;)

How do I use GridBagConstraints setRows and setColumns?

How do I use setRows and setColumns to change the amount of rows and columns in my window?
Here's a copy of my code and where I tried to implement the set rows and columns:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.awt.*;
#SuppressWarnings("unused")
public class GUI
{
public static void main(String[] args)
{
new GUI();
}
public GUI()
{
JFrame AG = new JFrame("Adventure Game");
AG.setExtendedState(JFrame.MAXIMIZED_BOTH);
AG.setResizable(true);
AG.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel p=new JPanel();
p.setLayout (new GridBagLayout());
AG.add(p);
GridBagConstraints GBC = new GridBagConstraints();
GridLayout.setRows(100);//heres the set rows<<<<<<<<<<<<<<<<<<<
GridLayout.setColumns(100);//heres the set columns<<<<<<<<<<<<<<<<<<<
AG.getContentPane().add(p, BorderLayout.NORTH);
JButton saveButton =new JButton("Save");
JButton loadButton =new JButton("Load");
JButton optionsButton = new JButton("Options");
JLabel textBox= new JLabel("Story line will go here.");
JLabel label11 = new JLabel("Test 1");
GBC.gridx = 0;
GBC.gridy = 1;
p.add(label11,GBC);
JLabel label12 = new JLabel("Test 2");
GBC.gridx = 0;
GBC.gridy = 2;
p.add(label12,GBC);
JLabel label13 = new JLabel("Test 3");
GBC.gridx = 0;
GBC.gridy = 3;
p.add(label13,GBC);
JLabel label14 = new JLabel("Test 4");
GBC.gridx = 0;
GBC.gridy = 5;
p.add(label14,GBC);
AG.setVisible(true);
}
}
GridBagConstraints work with the GridBagLayout, not the GridLayout. Your call to GridLayout doesn't do anything.
To set the rows and columns with GridBagConstraints, you need to use GBC.gridx = ...; and GBC.gridy = ...;
If you are trying to place gaps between your buttons, empty GridBag cells are not the way to do it; use the insets of your GridBagConstraints for that.
To make a component in a GridBagLayout disappear without the other components shifting around, place the button in a JPanel with a CardLayout, and make sure you add that JPanel to your GridBagLayout instead of the button:
private JButton optionalButton;
private void buildWindow() {
// ...
optionalButton = new JButton("Optional Action");
JPanel optionalButtonPanel = new JPanel(new CardLayout());
optionalButtonPanel.add(optionalButton, "BUTTON");
optionalButtonPanel.add(new JLabel(), "BLANK");
// ...
}
private void setOptionalButtonVisible(boolean visible) {
Container optionalButtonPanel = optionalButton.getParent();
CardLayout layout = (CardLayout) optionalButtonPanel.getLayout();
layout.show(optionalButtonPanel, visible ? "BUTTON" : "BLANK");
}
CardLayout always displays one and only one of its components, but it sizes its associated container to fit all the components, including the invisible ones.

Categories