java - JList 中的组件被白色方 block 隐藏,直到单击为止

标签 java swing user-interface jlist jcheckbox

在我一直从事的一个项目中,我注意到 JScrollPane 中的所有 JList 项目都是隐藏的,直到单击 JScrollPane/JList 为止。奇怪的是它没有完全覆盖。有一个带有透明边框的白色盒子,它散布在整个物体上,覆盖了所有边缘上除少数像素之外的所有像素。

图片:

正如你所看到的,中间有一个白色的 block - 注意粉红色的“边框”:

before click

现在,一旦我点击那个白色框,它就会消失:

after click

我知道洋红色看起来很糟糕,但我用它来形成对比。

这引出了我的问题:如何摆脱那个令人讨厌的白框?

这是我的代码:

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);
}

十个是我的 JCheckBoxList 类。

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;
        }
    }
}

然后是我的滚动 Pane ,其中具有以下设置(使用 Intelliji IDEA UI 设计器):

pluginList - JScrollPane

有什么想法吗?

最佳答案

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

在我看来,您正在动态地将组件添加到可见的 GUI 中。

当你这样做时,基本代码是:

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

您应该在执行上述代码之前设置visibleRowCount()。

另外:

  1. Swing 组件默认可见,因此您不需要 setVisible(true)
  2. 您可能需要考虑使用一列 JTable,因为它已经支持复选框渲染器和编辑器。

编辑:

我上面给你的解决方案是通用的解决方案。滚动 Pane 不同,您应该只向视口(viewport)添加一个组件。

根据您不正确的解决方案,您应该使用:

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

仅发布几行随机代码的问题是我们不知道代码的完整上下文。我没有意识到“pluginList”实际上是一个滚动 Pane 。通常变量名称中会有scroll 或scrollpane。

关于java - JList 中的组件被白色方 block 隐藏,直到单击为止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29997779/

相关文章:

Java JFrame 拒绝刷新

css - 没有 "breaking"复制和粘贴的智能报价?

预测语言偏好的 Android/iOS API/机制

Java:Netbeans 中的 JLayeredPane

java - 使用具有公共(public)数据源的多个 JComboBox

jquery - Python 脚本的 Web (Django) 中的 GUI

java - JDBC 创建表

java - 无法获取页面的完整 HTML,它会在某个点停止

java - 如何从在线 UML 模型生成 Java?

java - 未 stub 调用的 native 类型的返回值