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:
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.
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.
The selection mode can be changed on the selection model directly, or via JList 's cover method.
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.
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.)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With