It has been a while since I programmed with Java Swing, so I'm not an expert with all it's methods. Just to contextualize what I'm doing, I'm building an URCap UI that I'm using in a UR Cobot (That's basically a UI that allows me to control something installed to the robot like a gripper, for example) and for this UI I have to create around 64 CheckBoxes to be selected by the user and he can check one or more at the same time. So, following tutorial and other questions from StackOverflow I began by creating a list of CheckBoxes
private List<JCheckBox> checkBoxList = new ArrayList<JCheckBox>();
And I added each element of this list to a JPanel, then I added the panel to a JScrollPane, like this:
for (JCheckBox checkBox: checkBoxList) {
panel.add(checkBox);
}
scrollPane.add(panel);
This is the further that I could get after tirelessly search for help and testing codes that I found, and this logic should (I think) normally work, according to the people that provide them, but in my case, when I build it, the ScrollPane is showed in the GUI, but there's no checkbox, see the below image:
I'm not sure what is causing this problem, I don't know if I should use a list of CheckBoxes like this, just defining it as a List, but I tried a lot of different ways, using a JList, an Array JCheckBox[] and others, but they give me the same problem.
I know that besides this error, my code is working, because I tested the scrollPane using a single JCheckBox (see function createJobsPanel1()) and it's successfully rendering the checkbox:
This is my full code and to explain it breafly to you, you only have to focus on the functions createJobsPanelx()
, setIOCheckBoxItems()
and the global variables where I define my JCheckBox list. The funciont BuildUI()
only calls the others to build the UI.
Also, the setIOCheckBoxItems()
is called by another function that is placed in another class, but just to explain what it does, it sets the JCheckBox list elements to "1, 2, 3, 4, 5 ..." and so on.
package com.sigmaclermont.ploc2dMultObjDetect.impl;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JCheckBox;
import javax.swing.JScrollPane;
import javax.swing.plaf.metal.MetalCheckBoxIcon;
import com.ur.urcap.api.contribution.ContributionProvider;
import com.ur.urcap.api.contribution.ViewAPIProvider;
import com.ur.urcap.api.contribution.program.swing.SwingProgramNodeView;
public class Ploc2dProgramNodeView implements SwingProgramNodeView<Ploc2dProgramNodeContribution>{
private final ViewAPIProvider apiProvider;
public Ploc2dProgramNodeView(ViewAPIProvider apiProvider) {
this.apiProvider = apiProvider;
}
//private JCheckBox[] checkBoxList = new JCheckBox[64];
//private JCheckBox checkBoxOrig = new JCheckBox();
private List<JCheckBox> checkBoxList = new ArrayList<JCheckBox>();
@Override
public void buildUI(JPanel panel, ContributionProvider<Ploc2dProgramNodeContribution> provider) {
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(createDescription("Select the active Jobs:"));
panel.add(createJobsPanel2(checkBoxList));
}
/*public void setIOCheckBoxItem1(Integer item) {
checkBoxOrig.setText(Integer.toString(item));
checkBoxOrig.setIcon(new MetalCheckBoxIcon() {
protected int getControlSize() {return 30;}
});
checkBoxOrig.setFont(new java.awt.Font("Arial", Font.LAYOUT_LEFT_TO_RIGHT, 20));
}*/
public void setIOCheckBoxItem2(Integer[] items) {
for (Integer item: items) {
checkBoxList.add(new JCheckBox(Integer.toString(item+1)));
}
}
private Box createDescription(String desc) {
Box box = Box.createHorizontalBox();
box.setAlignmentX(Component.LEFT_ALIGNMENT);
JLabel label = new JLabel(desc);
box.add(label);
return box;
}
/*private Box createJobsPanel1(final JCheckBox checkBox) {
Box box = Box.createHorizontalBox();
box.setAlignmentX(Component.LEFT_ALIGNMENT);
JPanel panel = new JPanel();
panel.add(checkBox);
JScrollPane scrollPane = new JScrollPane(panel);
scrollPane.setPreferredSize(new Dimension(100,100));
scrollPane.setMaximumSize(scrollPane.getPreferredSize());
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
checkBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent arg0) {
// TODO Auto-generated method stub
}
});
box.add(scrollPane);
return box;
}*/
private Box createJobsPanel2(final List<JCheckBox> checkBoxList) {
Box box = Box.createHorizontalBox();
box.setAlignmentX(Component.LEFT_ALIGNMENT);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setPreferredSize(new Dimension(300,300));
scrollPane.setMaximumSize(scrollPane.getPreferredSize());
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(250,250));
panel.setMaximumSize(panel.getPreferredSize());
panel.setLayout(new GridLayout(8,1));
for (JCheckBox checkBox: checkBoxList) {
panel.add(checkBox);
}
scrollPane.add(panel);
for (JCheckBox checkBox: checkBoxList) {
checkBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent arg0) {
// TODO Auto-generated method stub
}
});
}
box.add(scrollPane);
return box;
}
}
I tried all types of solution, but none worked. I expect a ScrollPane containing 64 checkboxes with text from "1" to "64" where the user can select one or more.
EDIT: Here is the backend code that contains the openView() method, it calls the setIOCheckBoxItems() from the other code and passes the integer array from 1 to 64
package com.sigmaclermont.ploc2dMultObjDetect.impl;
import com.ur.urcap.api.contribution.ProgramNodeContribution;
import com.ur.urcap.api.contribution.program.ProgramAPIProvider;
import com.ur.urcap.api.domain.data.DataModel;
import com.ur.urcap.api.domain.script.ScriptWriter;
import com.ur.urcap.api.domain.undoredo.UndoRedoManager;
import com.ur.urcap.api.domain.undoredo.UndoableChanges;
public class Ploc2dProgramNodeContribution implements ProgramNodeContribution{
private final ProgramAPIProvider apiProvider;
private final Ploc2dProgramNodeView view;
private final DataModel model;
private final UndoRedoManager undoRedoManager;
public Ploc2dProgramNodeContribution(ProgramAPIProvider apiProvider, Ploc2dProgramNodeView view,
DataModel model) {
this.apiProvider = apiProvider;
this.view = view;
this.model = model;
this.undoRedoManager = this.apiProvider.getProgramAPI().getUndoRedoManager();
}
private Integer[] getOutputItems() {
Integer[] items = new Integer[64];
for(int i = 0; i<64; i++) {
items[i] = i;
}
return items;
}
@Override
public void openView() {
view.setIOCheckBoxItems(getOutputItems());
}
@Override
public void closeView() {
// TODO Auto-generated method stub
}
@Override
public String getTitle() {
return "Ploc2D MultiObj";
}
@Override
public boolean isDefined() {
// TODO Auto-generated method stub
return false;
}
@Override
public void generateScript(ScriptWriter writer) {
// TODO Auto-generated method stub
}
}
EDIT 2: I tried the answer given by Caps and it didn't solve my problem, but it did change something, now, instead of a grey area inside the scrollpane, the area is white, so the panel probably is inside the scrollpane. Here's the screenshot: