Hello,
I am novice programmer and I am experimenting with swing. I created a scrollabe text area that seems to scroll great when I hold down a key for a long time. But, when I select a different tabbed pane and then come back to the pane containing the text area, I find that all objects in that pane have lost there shapes. What is the remedy for this problem? Please help, I have been stuck with this problem for a whole week. Thanks in advance.

Wouldn't it be better to but a JTextArea inside of a JScrollPane and then put the pane on your panel?

And what do you mean by your objects lose their shapes?

JTextArea is in a scrollpane which is in a tabbed pane. When I type, the text area scrolls to fit the text. The following is my code. Please copile it and invoke the run() method, that will make the gui visible. Then type something very lengthy so the text area scrolls horizontally. Then click on a different tab and come back to the tab containing the text area. You will see that all the gui objects have collapsed.

import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.border.*;
import javax.swing.event.*;
/**
 * Write a description of class AddBookFrame here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class AddBookFrame extends JFrame
{
    // instance variables - replace the example below with your own
    private JFrame rb;

    /**
     * Constructor for objects of class AddBookFrame
     */
    public AddBookFrame()
    {
        super("Address Book");
        //setSize(475, 400);
//        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        //******* start List Entry Pane ********
        String labels[] = {"Entry1", "Entry2", "Entry3", "Entry4", 
            "Entry5", "Entry6"};
        
        JPanel listEntryPane = new JPanel();
        
        
        DefaultListModel model = new DefaultListModel();
        for(String x : labels) {
            model.addElement(x);
        }
        JList entryList = new JList(model);
        entryList.setVisibleRowCount(4);
        
        JScrollPane entryListScrollpane = new JScrollPane(entryList,
            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        
        JButton viewEntryButt = new JButton("View");
        JButton eraseEntryFromGroupButt = new JButton("Erase Entry");
        
        listEntryPane.add(entryListScrollpane);
        listEntryPane.add(viewEntryButt);
        listEntryPane.add(eraseEntryFromGroupButt);        
        //******* end List Entry Pane ****************//
        
        
        //******* start Group Pane ***************//
        JPanel groupPane = new JPanel();
        
        JList groupList = new JList(model);
        groupList.setVisibleRowCount(4);
        
        JScrollPane groupListScrollPane = new JScrollPane(groupList,
            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            
        JButton viewListButt = new JButton("View List");
        JButton editGroupNameButt = new JButton("Edit Group Name");
        JButton eraseGroupButt = new JButton("Erase Group");
        
        groupPane.add(groupListScrollPane);
        groupPane.add(viewListButt);
        groupPane.add(editGroupNameButt);
        groupPane.add(eraseGroupButt);
        //****** end Group Pane ***********//
        
        //******** start ADD/EDIT entry pane **********//
        JPanel viewAddPane = new JPanel();
        viewAddPane.setLayout(new GridBagLayout());      
        
        
        final JTextField desigTxtField = new JTextField(20);
        final JTextArea detailsTxtArea = new JTextArea(8, 30);
        JButton editEntryButt = new JButton("Edit");
        
        JButton saveEntryButt = new JButton("Save");
        saveEntryButt.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    save(desigTxtField, detailsTxtArea);
                }
            });
        
        JButton eraseEntryButt = new JButton("Erase");
        
        JScrollPane viewAddScrollpane = new JScrollPane(detailsTxtArea,
            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            
        JScrollPane viewAddGListScrollpane = new JScrollPane(groupList, 
            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        
        addComponent(viewAddPane, new JLabel("Designation:"), 0, 0,
            1, 1, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE);
            
        addComponent(viewAddPane, desigTxtField, 1, 0, 3, 1, 
            GridBagConstraints.NORTHWEST, GridBagConstraints.NONE);
                
        
        addComponent(viewAddPane, new JLabel("Details:"), 0, 2,
            1, 1, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE);

        addComponent(viewAddPane, viewAddGListScrollpane, 4, 1, 3, 3,
            GridBagConstraints.NORTHWEST, GridBagConstraints.NONE);
       
        addComponent(viewAddPane, viewAddScrollpane, 1, 1,
             3, 3, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE);
        
        addComponent(viewAddPane, editEntryButt, 1, 5, 1, 1,
            GridBagConstraints.NORTHWEST, GridBagConstraints.NONE);
            
        addComponent(viewAddPane, saveEntryButt, 2, 5, 1, 1,
            GridBagConstraints.NORTHWEST, GridBagConstraints.NONE);
        
        addComponent(viewAddPane, eraseEntryButt, 3, 5, 1, 1,
             GridBagConstraints.NORTHWEST, GridBagConstraints.NONE);
              
        CheckListCellRenderer renderer = new CheckListCellRenderer();
        groupList.setCellRenderer(renderer);
        groupList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        
        //**************** end add view pane ************///
       
        JTabbedPane tabs = new JTabbedPane();
        tabs.addTab("List Entry", listEntryPane);
        tabs.addTab("View/Edit Entry", viewAddPane);
        tabs.addTab("Groups", groupPane);
               
        
        setContentPane(tabs);
    }
    
    private void addComponent(Container container, Component component,
        int gridx, int gridy, int gridwidth, int gridheight, int anchor,
        int fill) 
    {
        Insets insets = new Insets(2,2,2,2);
        GridBagConstraints gbc = new GridBagConstraints(gridx, gridy,
            gridwidth, gridheight, 1.0, 1.0, anchor, fill, insets, 0, 0);
        container.add(component, gbc);
    }
    public void run()
    {
        AddBookFrame rb = new AddBookFrame();
        rb.pack();
        rb.setVisible(true);
               
    }
    
  
  class CheckListCellRenderer extends JCheckBox
    implements ListCellRenderer
    {
        protected Border noFocusBorder = 
            new EmptyBorder(1, 1, 1, 1);
            
        public CheckListCellRenderer()
            {
                super();
                setOpaque(true);
                setBorder(noFocusBorder);
            }
            
        public Component getListCellRendererComponent(JList list, Object value, 
            int index, boolean isSelected, boolean cellHasFocus)
            {
                setText(value.toString());
                
                setBackground(isSelected ? list.getSelectionBackground() :
                    list.getBackground());
                    
                setForeground(isSelected ? list.getSelectionForeground() :
                    list.getForeground());
                    
                setFont(list.getFont());
                setBorder((cellHasFocus) ?
                UIManager.getBorder("List.focusCellHighlightBorder") :
                    noFocusBorder);
                
                return this;
            }
    }
    
    public void save(JTextField desigTxtField, JTextArea detailsTxtArea)
    {
        System.out.println(desigTxtField.getText());   
        System.out.println(detailsTxtArea.getText());
    }
}

I have attached before, during and after pictures which will help explain what I am trying to say. There is no need for you to go through the code.

Attachments after.gif 8.53 KB before.gif 15.66 KB during.gif 15.81 KB

I'm pretty sure its the way you're working with the GridBagLayout. If i saw correctly there isn't any FILL on any of the components.

Now if you resize your frame larger the components will reappear.

First off, I would recommend that each tabs JPanel be its own class. That should make things a little easier to read inside of your main frame.

Second. Using gridwidth and gridheight tends to be troublesome. I would recommend looking at ways to use everything as a gridwidth and gridheight of 1. Use gridx, gridy, weight and fill to get the effect that you're looking for.

For instance, the labels the textfield, textarea and listbox all go into one JPanel and then have the buttons at the bottom go into their own JPanel. Then place both of those JPanels into another JPanel that has the top jpanel will weightx of 1, weighty of 1, fill of both. The bottom panel would only have a wieghtx of 1, fill of both.

Swing gui building is all about Panels inside of other Panels and all the layouts are set to GridBagLayout.

Thank you for your prompt responses. I changed the the gridbagconstraints to .BOTH. You will see the result in the attached pics. Is there a way to make the objects retain there shapes?

Why do you want the objects to span only one cell? What are the benefits?

Do proffesional programmers write the code for java gui? Or do they use some kind of software to drag and drop objects on to the frame?

Attachments after.gif 13.06 KB before.gif 13.64 KB

Well, my guess is what is happening is that not only is fill set to both. But weighty is set to 1 for all the components. You really only want weighty to be set to 1 for your textarea.

BTW i would recommend getting rid of the addComponent method that was written and set all GridBagConstraints rules where you create the component and then add the component to your panel. It makes it very clear at what you're doing for each component.

What are the benefits of spanning multiple cells?

Spanning multiple cells can cause many headaches down the road. For example, lets say you need to add another button to the bottom of the page. Now the textarea is going to have to span 4 grids instead of 3. So now you have to make 2 code changes. If the top components were in their own panel and the buttons were in their own panel, you would only need to make one code change. What if you want to have dynamically build panels? That can really cause a mess with having to calculate what is where and how many grids a component spans, etc...

I would consider myself a professional Swing developer and I've used both GUI development tools and written entire GUIs by hand. Just like with WYSIWYG html editors.... Hand written code is FAR superior to generated code.

This article has been dead for over six months. Start a new discussion instead.