Add a Component to two different JTabbedPanes - java

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.

Related

Netbeans - storing GUI components made with GUI Builder in an array

Say I have n numbered components, e.g. n jPanels called panel1, panel2, ..., paneln, that were created using Netbeans' GUI Builder. As far as I'm aware the GUI Builder doesn't allow me to store components in an array when creating them, which means if I wanted to modify them during execution I'd have to do something like
jPanel[] panels = new jPanel[n];
panels[1] = panel1;
panels[2] = panel2;
.
.
.
panels[n] = paneln;
for(int i = 0; i < n; i++) {
//Do stuff with panels[i]
}
Is there some other way to do this without having to drop the Builder and create the interface from scratch?
Add this in your code:
List<JPanel> myPanels = new ArrayList<>();
private JPanel getNewPanel()
{
JPanel panel=new JPanel();
myPanels.add(panel);
return panel;
}
Then in the Netbeans GUI builder:
Using ctrl-click select all the panels you want to access via
myPanels
In the Code tab of the Properties window, set the Custom Creation Code to: getNewPanel();

Adding components via code

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!

jpanel cannot make gridlayout with 7 rows and 2 cols

i want to ask if anything goes wrong with my code. i've set my frame with borderlayout . and on the center part, i want to use gridlayout with 7rows and 2 cols inside them.
paneltengah= new JPanel();
paneltengah.setLayout(new GridLayout(7,2));
labelname = new JLabel(lbl_name,SwingConstants.LEFT);
labelusername = new JLabel(lbl_username,SwingConstants.LEFT);
labelpassword = new JLabel(lbl_password,SwingConstants.LEFT);
labelgender = new JLabel(lbl_gender,SwingConstants.LEFT);
labelemail = new JLabel(lbl_email,SwingConstants.LEFT);
labelhobby = new JLabel(lbl_hobby,SwingConstants.LEFT);
labelrole = new JLabel(lbl_role,SwingConstants.LEFT);
textname = new JTextField(20);
textusername = new JTextField(20);
textpassword = new JPasswordField(20);
textemail = new JTextField(20);
comboboxhobby = new JComboBox();
comboboxrole = new JComboBox();
radiobuttonmale = new JRadioButton("Male");
radiobuttonfemale = new JRadioButton("Female");
ButtonGroup btngroup = new ButtonGroup();
btngroup.add(radiobuttonmale);
btngroup.add(radiobuttonfemale);
paneltengah.add(labelname);
paneltengah.add(labelusername);
paneltengah.add(labelpassword);
paneltengah.add(labelgender);
paneltengah.add(labelemail);
paneltengah.add(labelrole);
paneltengah.add(labelhobby);
//// paneltengah.add(textname); when i open this, the layout become awkward
//// paneltengah.add(textusername);
//// paneltengah.add(textpassword);
//// paneltengah.add(radiobuttonmale);
//// paneltengah.add(radiobuttonfemale);
//// paneltengah.add(comboboxhobby);
//// paneltengah.add(comboboxrole);
pane.add(paneltengah, BorderLayout.CENTER);
the following pictures is shown without opening the comment
the following picture is shown with uncomment
what is wrong with my code ?
First of all, a GridLayout sizes all components evenly in its associated Container, which explains why your labels and fields are all the same size. For example, if you had a JTextArea 200 columns × 20 lines in your JPanel, then even the tiniest label would occupy that huge a space as well!
Next, according to the GridLayout Javadoc, when a GridLayout instance is constructed with two non-zero arguments, the number of rows gets fixed and the number of columns is adjusted according to the number of components put into the parent Container.
What I suggest is using a BorderLayout to set up your main form layout. Put your title at NORTH and keep the CENTER for your labels and fields (your current JPanel).
For your labels and fields, the simplest solution might be using a GridLayout(0, 2) (fixed number of columns). But all your components will still be equally sized.
If you need more control over the size of your components (e.g., fields wider than labels), then I suggest using another layout manager such as GridBagLayout. I know it's more complex to manage but using a GridBagLayout formatting preview utility should help. Such a program may be named something like GridBagLab (I know David Geary's book Graphic Java volume 2 — Swing features one on its companion CD).
There is also a GridBagLayout tutorial at https://www.youtube.com/watch?v=Ts5fsHXIuvI.

How to create JCheckBox for elements of an ArrayList

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

When recalling a JPanel instance creating method, the panel overlaps the previous one. How can I stop this?

Probably an easy fix, but Would be wonderful if someone can help me through this!
SO I have a method which creates a panel and also adds it to the JFrame.
The problem is, I want to keep recalling the method with slightly different text.
Although it does recall, it creates a new instance of it overtop of the previous one instead of replacing it.
}public void lyricPrinter(){
System.out.println(lyrics);
JTextArea textarea = new JTextArea(lyrics);
textarea.setBackground(Color.LIGHT_GRAY);
textarea.setEditable(false);
//JLabel textarea = new JLabel("not sure what this is...");
//textarea.setText("<html>"+lyrics+"</html>");
JScrollPane scroll = new JScrollPane (textarea,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
//GUI.frame.remove(scroll);
GUI.frame.add(scroll);
GUI.frame.setVisible(true);
Every time the method runs, you are creating a new panel. In order to prevent this, you need to create only 1 instance of Panel Class, so that when the method runs, work will be done on same panel.
1-) Define Panel instance as local variable int your class.
2-) Instantiate the Panel in your "lyricPrinter" Method
3-) Immediately After, destroy the panel components using .removeAll()
It should work.
For your example;
JScrollPane scroll; //-->> somewhere in your class
public void lyricPrinter(){
System.out.println(lyrics);
JTextArea textarea = new JTextArea(lyrics);
textarea.setBackground(Color.LIGHT_GRAY);
textarea.setEditable(false);
//JLabel textarea = new JLabel("not sure what this is...");
//textarea.setText("<html>"+lyrics+"</html>");
**scroll = new JScrollPane (textarea,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scroll.removeAll();**
//GUI.frame.remove(scroll);
GUI.frame.add(scroll);
GUI.frame.setVisible(true);

Categories

Resources