简体   繁体   中英

How to make a Blank JList at a specified size? Without empty elements

I am trying to create a BLANK JList for the user to see befor elements are added. Over all what is happening is I am using JFileChooser to select txt documents to be added to a list, then the vowels in each txt document are counted and displayed in the other list. The list must be visible before the user selects anything and the list must be blank. Yes there are two empty JList but obviously if I can get help with one the other is easy. So far nowhere on the internet touches on this particular subject.

Setting row count(visible) does not work, nor setsize(). Unless I am using it wrong. Please explain with examples. Thanks in advance!

An example below: 示例布局

Code:

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;

import javax.swing.*;

public class VowelCounterApp extends JFrame implements ActionListener 
{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    JPanel panel1 = new JPanel();
    JPanel panel2 = new JPanel();
    JScrollPane scrollPane = new JScrollPane();
    JList selectList =  new JList();
    JList showList = new JList();
    JFileChooser fileChooser = new JFileChooser();
    JButton addFiles = new JButton("Add Files");
    JButton process = new JButton("Process");
    JButton clear = new JButton("Clear");
    JButton help = new JButton("Help");


    public VowelCounterApp()
    {
        JFrame appWindow = new JFrame("Vowel Counter");

        appWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        appWindow.setSize(1500, 600);

        appWindow.setLayout(new BorderLayout());

        appWindow.setVisible(true);

        appWindow.add(panel1, BorderLayout.WEST);
        appWindow.add(panel2, BorderLayout.EAST);


        panel1.add(selectList);
        selectList.add(scrollPane);
        panel2.add(showList);
        showList.add(scrollPane);



    }

    public void actionPerformed(ActionEvent e)
    {

    }

    public static void main(String[] args)
    {
        new VowelCounterApp();
    }

}

The JList API will show you two key methods:

  1. public void setVisibleRowCount(int rowCount)
  2. public void setPrototypeCellValue(E prototype)

So simply give your list an adequate row visible count and an adequately long enough prototype value, and then its enclosing JScrollPane's viewport will automatically size its viewport accordingly.

For example:

import java.awt.GridLayout;
import javax.swing.*;

public class JListExample extends JPanel {
    private JList<String> list1 = new JList<>();
    private JList<String> list2 = new JList<>();

    public JListExample() {
        list1.setVisibleRowCount(20);
        list2.setVisibleRowCount(20);
        list1.setPrototypeCellValue(String.format("%60s", ""));
        list2.setPrototypeCellValue(String.format("%60s", ""));

        setLayout(new GridLayout(1, 2));
        add(new JScrollPane(list1));
        add(new JScrollPane(list2));
    }

    private static void createAndShowGui() {
        JListExample mainPanel = new JListExample();

        JFrame frame = new JFrame("JList Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

Or better to avoid "magic" numbers:

public class JListExample extends JPanel {
    private static final int LIST_ROW_COUNT = 20;
    private static final int LIST_CHAR_WIDTH = 80;
    private static final String LIST_PROTOTYPE = "%" + LIST_CHAR_WIDTH + "s";
    private JList<String> list1 = new JList<>();
    private JList<String> list2 = new JList<>();

    public JListExample() {
        list1.setVisibleRowCount(LIST_ROW_COUNT);
        list2.setVisibleRowCount(LIST_ROW_COUNT);
        list1.setPrototypeCellValue(String.format(LIST_PROTOTYPE, ""));
        list2.setPrototypeCellValue(String.format(LIST_PROTOTYPE, ""));

Here, now you can see the lists better by my wrapping them and their JScrollPane in a JPanel that uses a TitledBorder:

import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.*;

public class JListExample extends JPanel {
    private static final int LIST_ROW_COUNT = 20;
    private static final int LIST_CHAR_WIDTH = 80;
    private static final String LIST_PROTOTYPE = "%" + LIST_CHAR_WIDTH + "s";
    private JList<String> list1 = new JList<>();
    private JList<String> list2 = new JList<>();

    public JListExample() {
        list1.setVisibleRowCount(LIST_ROW_COUNT);
        list2.setVisibleRowCount(LIST_ROW_COUNT);
        list1.setPrototypeCellValue(String.format(LIST_PROTOTYPE, ""));
        list2.setPrototypeCellValue(String.format(LIST_PROTOTYPE, ""));

        setLayout(new GridLayout(1, 2));
        add(createListWrapper(list1, "JList 1"));
        add(createListWrapper(list2, "JList 2"));
    }

    private JComponent createListWrapper(JList<String> list, String title) {
        JScrollPane scrollPane = new JScrollPane(list);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        JPanel wrapperPanel = new JPanel(new BorderLayout());
        wrapperPanel.add(scrollPane);
        wrapperPanel.setBorder(BorderFactory.createTitledBorder(title));
        return wrapperPanel;
    }

    private static void createAndShowGui() {
        JListExample mainPanel = new JListExample();

        JFrame frame = new JFrame("JList Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

Edit
As MadProgrammer states in comment:

I'd also be careful with prototypeCellValue, unless the value matches the expected length of your data, it could truncate your data when it's displayed, just need to be careful

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM