I have an array that fills in by the user. Then each element of this array will be a CheckBox. For example if the array has 6 elements, it must create 6 checkboxes.
This is how I tried to loop through the array and create the checkbox, but it only overwrite on one checkbox.
public static void main(String[] args) {
JFrame frame = new JFrame("Options");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
ArrayList<String> myArrayList = new ArrayList<String>();
myArrayList.add("checkbox 1");
myArrayList.add("checkbox 2");
myArrayList.add("checkbox 3");
myArrayList.add("checkbox 4");
myArrayList.add("checkbox 5");
for(String element : myArrayList){
JCheckBox box = new JCheckBox(element);
frame.add(box);
}
frame.setVisible(true);
}
It is important that I have the access to each single checkbox later, so I can specify for example if checkbox2 is selected, do this.
So is there any way to make these checkboxes dynamically according to the ArrayList's size?
Every time you add something new to the JFrame, it removes the thing that was previously in it.
You'll need to create a JPanel or some other container to hold the JCheckBoxes, and then put that inside the JFrame.
Also, you can keep track of the checkboxes in a List.
For instance:
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(BoxLayout.Y_AXIS, panel));
List<JCheckBox> checkboxes = new ArrayList<>();
for(String element : myArrayList) {
JCheckBox box = new JCheckBox(element);
checkboxes.add(box);
panel.add(box);
}
frame.add(panel);
The main problem is, you're adding all the check boxes to the same location on the frame.
A JFrame uses a BorderLayout by default. A BorderLayout allows a single component to be managed in each of its five available slots. Basically a BorderLayout will ignore all but the last component added to any of the slots
Instead, try changing the LayoutManager to something more useful, like FlowLayout or GridBagLayout depending on your needs
Take a look at Laying Out Components Within a Container for more details.
Depending on your needs, I might be tempered to fill the ArrayList with the JCheckBoxes instead of String or even a Map of some kind, to make it easier to link the text with the JCheckBox
Related
I have a JPanel. Inside Panel I have kept one JLabel and three JCheckBox.
I want to keep all the checkBox in one line after JLabel. Here is the sample code and some screenshots.
Output 1
Output 2
When i change to X_AXIS it is coming everything in one line and when i switch to Y_AXIS then it is coming new line means vertically.
But my requirement is all the checkbox should come next line means after JLabel.
JLabel should come in line and all the checkBox should come in one line.
public class CheckBoxWithJLabel {
public static void main(String[] args) {
JFrame f= new JFrame("CheckBox Example");
JPanel panel = new JPanel();
panel.setBounds(40,80,600,200);
JCheckBox chk_Embrodary=new JCheckBox("Embrodary");
JCheckBox chk_Cutting=new JCheckBox("Cutting");
JCheckBox cb_Sewing=new JCheckBox("Sewing");
panel.setLayout(new javax.swing.BoxLayout(panel, javax.swing.BoxLayout.X_AXIS));
JLabel lblHeader=new JLabel("Job Work Process Selection");
panel.add(lblHeader);
panel.add(chk_Embrodary);
panel.add(chk_Cutting);
panel.add(cb_Sewing);
f.add(panel);
f.setSize(600,400);
f.setLayout(null);
f.setVisible(true);
}
}
I want this output like
this
How to solve this problem?
I would highly suggest you to have a look through the Java Swing Tutorial, especially the Laying Out Components Within a Container section, since it seems you lack some basic understanding of how Swing and its Layout Managers are supposed to be used.
Regarding your problem:
Currently, you are using a single BoxLayout, which " puts components in a single row or column". You only want that behavior for your JCheckBoxes though, and not for your JLabel. Keeping this in mind, the solution is to split up your components and to not put all of them in a single JPanel. Doing this will grant you more flexibility in how you design your GUI, since you can use multiple layouts in different nested panels.
You could do something like this (explanation in the code comments):
public static void main(String[] args) {
JFrame f = new JFrame("CheckBox Example");
// add a Y_AXIS boxlayout to the JFrames contentpane
f.getContentPane().setLayout(new BoxLayout(f.getContentPane(), BoxLayout.Y_AXIS));
JCheckBox cbEmbrodary = new JCheckBox("Embrodary");
JCheckBox cbCutting = new JCheckBox("Cutting");
JCheckBox cbSewing = new JCheckBox("Sewing");
// no need to set the bounds, since the layoutmanagers will determine the size
JPanel labelPanel = new JPanel(); // default layout for JPanel is the FlowLayout
JLabel lblHeader = new JLabel("Job Work Process Selection");
labelPanel.add(lblHeader); // JPanel for the label done
// JPanel for the comboboxes with BoxLayout
JPanel cbPanel = new JPanel();
cbPanel.setLayout(new BoxLayout(cbPanel, BoxLayout.X_AXIS));
cbPanel.add(cbEmbrodary);
cbPanel.add(cbCutting);
cbPanel.add(cbSewing);
f.add(labelPanel);
f.add(cbPanel);
// No need to set the size of the JFrame, since the layoutmanagers will
// determine the size after pack()
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
Output:
Sidenotes:
Don't set fixed sizes via setSize() or setBounds() to your components. Swing is designed to be used with appropariate LayoutManagers, and if you do that, calling pack() on the JFrame before setting it visible will layout the components and determine their appropriate size. (Also, don't use null-layout for the same reasons)
If you need the JLabel to not be centered but left aligned, like in your screenshot, then use the following:
FlowLayout layout = (FlowLayout) labelPanel.getLayout();
layout.setAlignment(FlowLayout.LEFT);
I am adding JLabels from an Arraylist to a JPanel and they will only display if i set a layout on the panel but i want to set the location of the labels myself when i try panel = new JPanel(null); all labels are not displayed.
Frame:
public static void Frame(){
panel = new JPanel(null);
JFrame frame = new JFrame("New");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.pack();
frame.setSize(400,400);
frame.add(panel);
}
ArrayList iteration that adds labels to panel
private static void printArray() {
for(int i = 0; i < food.size(); i++){
component = new JLabel(new Food(food.get(i).getColor(),
food.get(i).getIconHeight(), food.get(i).getIconWidth(),
food.get(i).getLocationX(), food.get(i).getLocationY()));
panel.add(component);
component.setLocation(food.get(i).getLocationX(),
food.get(i).getLocationY());
}
}
I can see from Debug it is definitely getting the location information, so why is it not putting it in this location.
The reason to set layout as null is so i can update the position of the label so i can "move" it around with keyboard input
The first thing you need to do is understand what job the layout manager actually does, because if you're going to remove it, you're going to need to take over it's work.
Layout managers are responsible for determining both the size and position of the components. They do this through a variety of means, but can make use of the getPreferred/Minimum/MaximumSize methods of the components.
So this would suggest you need to make your own determinations about these values, for example...
component = new JLabel(new Food(food.get(i).getColor(),
food.get(i).getIconHeight(), food.get(i).getIconWidth(),
food.get(i).getLocationX(), food.get(i).getLocationY()));
component.setSize(component.getPreferredSize());
component.setLocation(food.get(i).getLocationX(), food.get(i).getLocationY());
I'd also recommend using the Key Bindings over KeyListener, it doesn't suffer from the same focus related issues
I'm trying to have painted into a JPanel (which is inside a ScrollPane), a bunch of labels and RadioButtons, dynamically. I receive an ArrayList with "Advice" objects, and I want to iterate over them to represent them in a way I have a label that describes them, and then, two radio buttons (to choose "Yes" or "No").
But at the moment, with this code at the JFrame's constructor, it's not properly working:
// My constructor
public CoachingFrame(AdvicesManager am) {
initComponents();
this.am = am;
// I set the layout for the inner panel (since ScrollPane doesn't allow BoxLayout)
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
// Iterate over the arraylist
for(int i=0;i<am.advices.size();i++){
//Add elements to the panel
panel.add(new JLabel( am.advices.get(i).getQuestion()));
ButtonGroup group = new ButtonGroup();
// Group the RadioButtons inside another panel, so I can use FlowLayout
JPanel buttonsPanel = new JPanel();
buttonsPanel.setLayout(new FlowLayout());
JRadioButton rad1 = new JRadioButton();
JRadioButton rad2 = new JRadioButton();
group.add(rad1);
group.add(rad2);
buttonsPanel.add(rad1);
buttonsPanel.add(rad2);
// Add the radiobuttons' panel to the main one, and revalidate
panel.add(buttonsPanel);
panel.revalidate();
}
// Finally, add the panel to the ScrollPane.
questions.add(panel);
}
I receive the arraylist correctly; I already checked that. The problem seems to be when painting the components.
Since I always use the NetBeans GUI creator, I'm not very used to add components via code. Can someone help me? I guess I'm missing something here.
edit: Note that "questions" is the ScrollPane object!
edit 2: This "questions" panel should have all those components painted: http://i.imgur.com/tXxROfn.png
As Kiheru said, ScrollPane doesn't allow views (like my JPanel) to be added with .add(), instead, I had to use .setViewportView(Component). Now it's working perfectly, thank you!
I am trying to iterate over a JList where each item contains:
JPanel - JLabel
Currently what i have is:
System.out.println("Reading all list items:");
System.out.println("-----------------------");
for (int i = 0; i < menuList.getModel().getSize(); i++) {
Object item = menuList.getModel().getElementAt(i);;
System.out.println("Item = " + item);
}
The output i get is:
Item =
javax.swing.JPanel[,0,0,0x0,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
Instead i want to access the text that is inside the JPanel.
How could this be done?
Edit:
This is how i add my JPanel to the JList
menuList = new JList(v);
v = new Vector <String> ();
menuList.setListData(v);
.....
// get our images
Icon pingImage = new javax.swing.ImageIcon(getClass().getResource("/resources/icnNew.png"));
// add the images to jlabels with text
JLabel pingLabel = new JLabel("Hi there", pingImage, JLabel.LEFT);
// create the corresponding panels
JPanel pingPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
// add the labels onto the panels
pingPanel.add(pingLabel);
v.add(pingPanel);
So the text i want to find is "Hi there"
Then what you need is to check for the elements inside that JPanel. I mean, a panel is a container of UI elements, that said, you need to check for the elements, once you checked for that you need to compare whether it is a label or not, if it is a label then you will be able to get the text of that label.
Can't you show us the code, probably could be easier if you provide the snippet.
I have a LinkedList of Components, each of which I would like to add into two different JTabbedPanes. For some reason, Swing is only letting me put each component into one or the other. The code I'm using is the following:
/* The two tab panes */
JTabbedPane leftTabs = new JTabbedPane();
JTabbedPane rightTabs = new JTabbedPane();
for (int i=0; i<tabPanes.size(); i++) {
rightTabs.add(tabPanes.get(i));
leftTabs.add(tabPanes.get(i));
}
Whichever add call I put last is the one that works; if I add to leftTabs last, then rightTabs ends up empty, and vice-versa.
Any ideas on how to get this working? Thanks!
A component can only have a single parent, so you can't add it to two different tabs.
However the model of the component can be shared. For example:
JTextField textField1 = new JTextField();
JTextField textField2 = new JTextField();
textField2.setDocument( textField1.getDocument() );
So somehow you to figure out how to share models, not the components.