Components in JList are Hidden by White Square Thing Until Clicked

痞子三分冷 提交于 2020-01-16 16:50:24

问题


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":

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

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):

Any ideas?


回答1:


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.




回答2:


    mainGUI.pluginList.setViewportView(mainGUI.checkList); // pluginList is the JScrollPane.

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



来源:https://stackoverflow.com/questions/29997779/components-in-jlist-are-hidden-by-white-square-thing-until-clicked

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!