0

In a project I've been working on, I noticed that all the JList items in my JScrollPane are hidden until the JScrollPane/JList has been clicked. The weird part is it's not completely covered. There's this white box with a transparent border that spreads out over the whole thing, covering all but a few pixels on all edges.

Pictures:

As you can see, there is this white block in the middle - notice the pink "border":

before click

Now, once I click that white box, it goes away:

after click

I know the magenta looks horrible, but I'm using it for contrast.

Which leads me to my question: how do I get rid of that obnoxious white box?

Here is my code:

public static void listJars(File f)
{
    JCheckBox firstBox = null;
    DefaultListModel<JCheckBox> model = new DefaultListModel<>();
    if(mainGUI.checkList != null)
    {
        //System.out.println("Already exists lol: " + mainGUI.checkList.getName());
        mainGUI.pluginList.remove(mainGUI.checkList);
    }
    //mainGUI.pluginList.repaint();

    File[] files = new File(f.getPath()).listFiles();
    if (files != null)
    {
        for (File file : files)
        {
            if (file.getName().endsWith(".jar") || file.getName().endsWith("._jar"))
            {
                JCheckBox cb = new JCheckBox(file.getName());

                if(firstBox == null)
                {
                    firstBox = cb;
                }

                cb.setSelected(file.getName().endsWith(".jar"));
                cb.setVisible(true);
                cb.setText(file.getName());
                model.addElement(cb);
                cb.repaint();
            }
        }
    }

    JCheckBoxList jCheckBoxList = new JCheckBoxList(model, mainGUI.textField1.getText());
    jCheckBoxList.setName("pluginCheckboxList");
    jCheckBoxList.setSize(mainGUI.pluginList.getSize());
    mainGUI.pluginList.add(jCheckBoxList);
    mainGUI.checkList = jCheckBoxList;
    jCheckBoxList.setVisible(true);
    jCheckBoxList.setVisibleRowCount(10);
}

And ten there's my JCheckBoxList class.

package Components;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;

@SuppressWarnings("serial")
public class JCheckBoxList extends JList<JCheckBox>
{
    protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
    protected String lastPath;

    public JCheckBoxList(final String lastPath)
    {
        this.lastPath = lastPath;
        setCellRenderer(new CellRenderer());
        setBackground(Color.magenta);
        addMouseListener(new MouseAdapter()
        {
            public void mousePressed(MouseEvent e)
            {
                int index = locationToIndex(e.getPoint());
                if (index != -1)
                {
                    JCheckBox checkBox = getModel().getElementAt(index);
                    checkBox.setSelected(!checkBox.isSelected());
                    repaint();

                    final String oldname = checkBox.getText();
                    if (!checkBox.isSelected())
                    {
                        checkBox.setName(checkBox.getText().substring(0, checkBox.getText().length() - 4) + "._jar");
                    }
                    else
                    {
                        checkBox.setName(checkBox.getText().substring(0, checkBox.getText().length() - 5) + ".jar");
                    }
                    System.out.println("Changed! Sel: " + checkBox.isSelected() + ", Name: " + checkBox.getName());
                    checkBox.setText(checkBox.getName());
                    String base = new File(lastPath).getParent() + "/plugins/";
                    boolean rename = new File(base + oldname).renameTo(new File(base + checkBox.getText()));
                }
            }
        });
        setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    }

    public JCheckBoxList(ListModel<JCheckBox> model, String lastPath)
    {
        this(lastPath);
        setModel(model);
    }

    protected class CellRenderer implements ListCellRenderer<JCheckBox>
    {
        public Component getListCellRendererComponent(
                JList<? extends JCheckBox> list, JCheckBox value, int index,
                boolean isSelected, boolean cellHasFocus)
        {
            //Drawing checkbox, change the appearance here
            value.setBackground(isSelected ? getSelectionBackground()
                    : getBackground());
            value.setForeground(isSelected ? getSelectionForeground()
                    : getForeground());
            value.setEnabled(isEnabled());
            value.setFont(getFont());
            value.setFocusPainted(false);
            value.setBorderPainted(true);
            value.setBorder(BorderFactory.createEmptyBorder(0, 10, 5, 0));
            return value;
        }
    }
}

And then there's my scroll pane, which has these settings (using the Intelliji IDEA UI designer):

pluginList - JScrollPane

Any ideas?

mKorbel
  • 109,525
  • 20
  • 134
  • 319
ColonelHedgehog
  • 438
  • 3
  • 18
  • 1
    For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example) or [SSCCE](http://www.sscce.org/) (Short, Self Contained, Correct Example). – Andrew Thompson May 02 '15 at 02:44

2 Answers2

2
mainGUI.pluginList.add(jCheckBoxList);
mainGUI.checkList = jCheckBoxList;
jCheckBoxList.setVisible(true);
jCheckBoxList.setVisibleRowCount(10);

Looks to me like you are dynamically adding components to a visible GUI.

When you do this the basic code is:

panel.add(...);
panel.revalidate();
panel.repaint();

You should set the visibleRowCount() before the above code is executed.

Also:

  1. Swing components are visible by default so you don't need the setVisible(true).
  2. You may want to consider using a one column JTable since it already supports a checkbox renderer and editor.

Edit:

The solution I gave you above is the general solution. A scroll pane is different, you should only ever add a component to the viewport.

Based on your incorrect solution you should be using:

//mainGUI.pluginList.add(jCheckBoxList);
mainGUI.pluginList.setViewportView(jCheckBoxList);

The problem with posting only a few random lines of code is that we don't know the full context of the code. I did not realize "pluginList" was actually a scrollpane. Usually the variable name will have scroll or scrollpane in the name.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • I'll try this out. The reason why I'm using a JCheckboxList is because I might eventually need to use something else. – ColonelHedgehog May 02 '15 at 02:51
  • `The reason why I'm using a JCheckboxList is because I might eventually need to use something else` - that makes even less sense. Why would you spend time creating a custom component you won't even use. Keep the code simple. – camickr May 02 '15 at 02:53
  • Sorry, what I meant was a JCheckboxList is because it provides the flexibility I might need in the future. Wording failed. – ColonelHedgehog May 02 '15 at 02:58
0
    mainGUI.pluginList.setViewportView(mainGUI.checkList); // pluginList is the JScrollPane.

Do that, and it fixes everything! Put it in with my listJars method.

ColonelHedgehog
  • 438
  • 3
  • 18
  • Hence why I made an edit of my own... I realized the error I made and updated it soon afterwards. – ColonelHedgehog May 02 '15 at 17:34
  • 1
    Removed the down vote because you removed the incorrect solution. However looking at your code I still don't like that you access the components using "mainGUI.checkList". Your code just creates the JList, so why not use the JList variable. Also, you should not be accessing components directly. You should have methods like mainGUI.getList() or mainGUI.getScrollPane(). Also you don't need to create a new JList. You can use the JList.setModel(...) method to update the JList. Finally you should not be using the remove(...) method to remove the list from the scrollpane. – camickr May 02 '15 at 18:12
  • Thanks, sounds good. I'm new to the JSwing style and best practices therein. – ColonelHedgehog May 02 '15 at 18:20