Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set the amount of rows JList show (Java)

Tags:

java

swing

jlist

Problem: I have a method that creates a list from the parsed ArrayList. I manage to show the list in the GUI, without scrollbar. However, I am having problem setting it to show only the size of ArrayList. Meaning, say if the size is 6, there should only be 6 rows in the shown List. Below is the code that I am using. I tried setting the visibleRowCount as below but it does not work. I tried printing out the result and it shows that the change is made.

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

To summarize: I want the JList to show as many rows as the size of the parsed ArrayList, without a scrollbar.

Here is the picture of the problem:

jlist 1

Here's the link to the other 2 as the picture resolution is quite big I'm scared it will distort the view:

JList 1 & JList 2

The JList 1 and 2 pictures shows it clearly. The JList displays empty rows, which I do not want it to happen.

Any ideas? Please help. Thanks. Please let me know if a picture of the problem is needed in case I did not phrase my question correctly.

--

Edit:

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

How the textPane is included into the container, if that helps

Another edit:

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() is being called my CaretListener, to show the JScrollPane when the caret moves.

like image 654
Alex Cheng Avatar asked Apr 30 '10 07:04

Alex Cheng


People also ask

Which method of JList class returns the number of rows visible?

You can use getFirstVisibleIndex and getLastVisibleIndex methods of JList to calculate number of items it displays when visible. If size of viewport in scroll pane changes then the number of visible rows will also change.

Which method is used to set the selection mode for the JList?

The selection mode can be changed on the selection model directly, or via JList 's cover method.

What is JList in Java?

JList is part of Java Swing package . JList is a component that displays a set of Objects and allows the user to select one or more items . JList inherits JComponent class.


2 Answers

I suspect it's the layout-management of textPane that is the issue. From what I can see, the listForSuggestions should not occupy more space than it needs to display those items, if it's preferred size is respected.

So the JTextPane is a Container, that is, you can add subcomponents to it. But how are those subcomponents layed out? That is up to the layout manager currently in use. If the layout manager respects the preferred dimension of the listForSuggestios I think you should be ok. Not sure though.

From what I can see, you get the "null-layout" by just instantiating a JTextPane, which means that unless you set another layout manager explicitly, you would need to take care of placement / resizing of the subcomponents yourself.

You could try to do something like

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

Here is a complete example

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

    }
}

I think the most elegant way of doing this is to roll your own layout-manager. (It's actually quite simple.) And then, instead of doing textPane.add(list), you do textPane.add(list, YourLayoutManager.POPUP_LIST). The layout-manager then remembers the fact that list was supposed to be layed out according to it's preferred size, and layes it out accordingly in its layoutContainer-method. (If you give the YourLayoutManager a reference to the JTextPane that it is attached to, you could probably even make it layout the list right beside the current caret location.)

like image 117
aioobe Avatar answered Oct 09 '22 20:10

aioobe


If you are dynamically (via code) filling your list, it is bad idea not to use scrollbar. It might work as you want f.e. for 20 list items, but imagine what happens once you need use more data - like 2000. Your GUI will be ruined.

like image 1
Xorty Avatar answered Oct 09 '22 20:10

Xorty