8

问题:我有一个从解析的 ArrayList 创建列表的方法。我设法在 GUI 中显示列表,没有滚动条。但是,我无法将其设置为仅显示 ArrayList 的大小。这意味着,如果大小为 6,则显示的列表中应该只有 6 行。下面是我正在使用的代码。我尝试visibleRowCount如下设置,但它不起作用。我尝试打印出结果,它表明进行了更改。

private void createSuggestionList(ArrayList<String> str) {
    int visibleRowCount = str.size();
    System.out.println("visibleRowCount " + visibleRowCount);
    listForSuggestion = new JList(str.toArray());
    listForSuggestion.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    listForSuggestion.setSelectedIndex(0);
    listForSuggestion.setVisibleRowCount(visibleRowCount);
    System.out.println(listForSuggestion.getVisibleRowCount());
    listScrollPane = new JScrollPane(listForSuggestion);
    MouseListener mouseListener = new MouseAdapter() {

        @Override
        public void mouseClicked(MouseEvent mouseEvent) {
            JList theList = (JList) mouseEvent.getSource();
            if (mouseEvent.getClickCount() == 2) {
                int index = theList.locationToIndex(mouseEvent.getPoint());
                if (index >= 0) {
                    Object o = theList.getModel().getElementAt(index);
                    System.out.println("Double-clicked on: " + o.toString());
                }
            }
        }
    };
    listForSuggestion.addMouseListener(mouseListener);
    textPane.add(listScrollPane);
    repaint();
}

总结一下:我希望 JList 显示的行数与解析后的 ArrayList 的大小一样多而没有滚动条

这是问题的图片:

清单 1

这是其他 2 个的链接,因为图片分辨率很大,我担心它会扭曲视图:

JList 1 & JList 2

JList 1和2图片清楚地显示了它。JList 显示空行,我不希望它发生。

有任何想法吗?请帮忙。谢谢。如果我没有正确表达我的问题,请让我知道是否需要问题图片。

--

编辑:

JScrollPane scrollPane = new JScrollPane(textPane);
scrollPane.setPreferredSize(new Dimension(200, 200));

//Create the text area for the status log and configure it.
changeLog = new JTextArea(5, 30);
changeLog.setEditable(false);
JScrollPane scrollPaneForLog = new JScrollPane(changeLog);

//Create a split pane for the change log and the text area.
JSplitPane splitPane = new JSplitPane(
        JSplitPane.VERTICAL_SPLIT,
        scrollPane, scrollPaneForLog);
splitPane.setOneTouchExpandable(true);

//Create the status area.
JPanel statusPane = new JPanel(new GridLayout(1, 1));
CaretListenerLabel caretListenerLabel =
        new CaretListenerLabel("Caret Status");
statusPane.add(caretListenerLabel);

//Add the components.
getContentPane().add(splitPane, BorderLayout.CENTER);
getContentPane().add(statusPane, BorderLayout.PAGE_END);

如果有帮助,如何将 textPane 包含到容器中

另一个编辑:

public void showSuggestionList(JScrollPane pane, Rectangle caretCoords) {
    pane.setVisible(false);
    pane.setBounds(caretCoords.x - 5, caretCoords.y + 25, 400, 250);
    pane.setVisible(true);
    repaint();
}

showSuggestionList() 被称为我的 CaretListener,以在插入符号移动时显示 JScrollPane。

4

2 回答 2

2

我怀疑这textPane是问题的布局管理。据我listForSuggestions所知,如果尊重首选尺寸,则不应占用比显示这些项目更多的空间。

所以JTextPaneis a Container,也就是可以给它添加子组件。但是这些子组件是如何布局的呢?这取决于当前使用的布局管理器。如果布局管理器尊重listForSuggestios我认为你应该没问题的首选尺寸。不过不确定。

从我所见,您只需实例化 a 即可获得“空布局” JTextPane,这意味着除非您明确设置另一个布局管理器,否则您需要自己处理子组件的放置/调整大小。

你可以尝试做类似的事情

Dimension dim = listForSuggestions.getPreferredSize();
listForSuggestions.setBounds(xPos, yPos, dim.getWidth(), dim.getHeight());

这是一个完整的例子

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

import javax.swing.*;


public class FrameTest {

    public static void main(String[] args) {
        JFrame f = new JFrame("Frame Test");


        ArrayList<String> str = new ArrayList<String>();
        for (int i = 0; i < 20; i++)
            str.add("number " + i);

        JTextPane tp = new JTextPane();


        int visibleRowCount = str.size();
        System.out.println("visibleRowCount " + visibleRowCount);
        JList listForSuggestion = new JList(str.toArray());
        listForSuggestion.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        listForSuggestion.setSelectedIndex(0);
        listForSuggestion.setVisibleRowCount(5);
        System.out.println(listForSuggestion.getVisibleRowCount());
        JScrollPane listScrollPane = new JScrollPane(listForSuggestion);
        MouseListener mouseListener = new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent mouseEvent) {
                JList theList = (JList) mouseEvent.getSource();
                if (mouseEvent.getClickCount() == 2) {
                    int index = theList.locationToIndex(mouseEvent.getPoint());
                    if (index >= 0) {
                        Object o = theList.getModel().getElementAt(index);
                        System.out.println("Double-clicked on: " + o.toString());
                    }
                }
            }
        };
        listForSuggestion.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLACK));
        listForSuggestion.addMouseListener(mouseListener);
        Dimension dim = listForSuggestion.getPreferredSize();
        listForSuggestion.setBounds(20, 20, (int) dim.getWidth(), (int) dim.getHeight());

        tp.add(listForSuggestion);

        f.add(tp);
        f.setSize(400, 400);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);

    }
}

我认为最优雅的方法是滚动你自己的布局管理器。(实际上很简单。)然后textPane.add(list),你不做,而是做textPane.add(list, YourLayoutManager.POPUP_LIST)。布局管理器然后记住list应该根据它的首选大小布局的事实,并在它的 - 方法中相应地布局它layoutContainer。(如果你给它附加YourLayoutManager的引用JTextPane,你甚至可以让它布局list在当前插入符号位置的右边。)

于 2010-04-30T07:34:58.140 回答
1

如果您是动态(通过代码)填充列表,那么不使用滚动条是个坏主意。对于 20 个列表项,它可能会像你想要的那样工作,但想象一下,一旦你需要使用更多数据——比如 2000,会发生什么。你的 GUI 将被破坏。

于 2010-04-30T07:32:00.660 回答