Adding scrolling items dynamically to specific places on a JscrollPane - java

The short version of the question: I have a JScrollPane with a large number of items being scrolled. At certain times I'd like to add some items to the JScrollPane and have them appear NOT at the end of the list, but after (for example) the 17th item.
Normally if the code in question is within the JScrollPane derived class, I just say this.add(); But I believe this goes to the end of the list.
Rationales: Case 1: The underlying data I'm scrolling is an ordered list of items but additions are allowed at any point of the list. When I add things to the middle of the list, I want to avoid loading the whole list again into the JScrollPane.
Case 2: I'm simulating a scrolling list with expanding subcategories. So if the user picks an item that has expanding subcategories, my Action code recognizes this case, looks into program data to find the subcategories, and then adds them to the JScrollPane beneath the chosen category. Don't worry about it, but there will also be some visual indication that it is a subcategory, supplied by my action code.
I can code all of this. All I am hoping to learn is how to add something to a JScrollPane without it being added to the end of the list.

The answer depends on what this component is that you are adding your items to. If you are using a JList, you could use something like DefaultListModel#add(int, Object) to add an item to a specific location.
If you're using something based on a JComponent (like a JPanel), you can use JComponent#add(Component, int) to specify the location that the component should be added, this assumes that the location exists (ie you can't add a component to position 100 if the container only contains a single component).
The following example generates a random number, determines the location that the number should be inserted in order to maintain a ordered list and inserts a component at that point. It will also attempt to scroll the JScrollPane to make the item visible
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test10 {
public static void main(String[] args) {
new Test10();
}
public Test10() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JPanel numbers;
private List<Integer> values;
public TestPane() {
values = new ArrayList<>(25);
setLayout(new BorderLayout());
numbers = new JPanel(new GridLayout(0, 1));
add(new JScrollPane(numbers));
Timer timer = new Timer(500, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int next = (int) (Math.random() * Integer.MAX_VALUE);
int insertion = Collections.binarySearch(values, next);
if (insertion < 0) {
insertion = (Math.abs(insertion)) - 1;
}
values.add(insertion, next);
JLabel label = new JLabel(Integer.toString(next));
numbers.add(label, insertion);
numbers.revalidate();
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Point p = label.getLocation();
JViewport vp = (JViewport) numbers.getParent();
JScrollPane sp = (JScrollPane) vp.getParent();
vp.setViewPosition(p);
}
});
}
});
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}

Related

JScrollPane Viewport bigger than Frame

I try to make a JFrame with a dynamical layout which should look like this
------------------------------------------|
| | Details |
| | |
| | |
| list | |
| | |
| | |
| | save |
-------------------------------------------
Where list is some tree structure where when I chose some element, the details of the element appear in Details. Now the Details consist of multiple JPanels which I put into a JPanel with BoxLayout. Below this JPanel I have a save button.
Since there are a lot of details I put the JPanel Details into a JScrollPane however, this scrollPane ignores its purpos and the result is that the Details panel is bigger than the window size. This is it goes till the bottom hiding the save button and the rest of it is not visible. The scrollbar never appears.
I don't know if it has todo with the fact that when an element is selected I update the JPanel's inside the JScrollPane or whatever.
Here is how I instantiate everything. First inside the right panel I add all JPanel's in firstPanel and I put a button inside the JPanel bottom. Then
setLayout(new BorderLayout());
add(bottom, BorderLayout.SOUTH);
scrollPane=new JScrollPane(firstPanel);
JPanel conScroll = new JPanel(new GridLayout());
conScroll.add(scrollPane);
add(conScroll, BorderLayout.CENTER);
On the JFrame level I instantiate the left and right side however I only put the left hand side and an empty JPanel for the right side called display.
When I select an element I update all elements inside firstPanel I call revalidate() and repaint() on the right side panel. Then on the Frame level I remove all elements of displayer and then add the right side to displayer.
As suggested I made a minimal working example (updated).
So for this minimal example I removed the left side. What is left is a JFrame EmpireEditor with a display JPanel inside, inside which I then put a unitEditor. Uniteditor contains two JPanel one in the center and one south. The panel in the center is in a JScrollPane.
package main;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
try {
// Set System L&F
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
}
catch (UnsupportedLookAndFeelException e) {
// handle exception
}
catch (ClassNotFoundException e) {
// handle exception
}
catch (InstantiationException e) {
// handle exception
}
catch (IllegalAccessException e) {
// handle exception
}
#SuppressWarnings("unused")
EmpireEditor r = new EmpireEditor();
}
}
The EmpireEditor
package main;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class EmpireEditor extends JFrame {
private JPanel display;
private UnitEditor unitEditor;
public EmpireEditor() {
super("Editor");
display = new JPanel();
unitEditor = new UnitEditor();
add(display);
display.add(unitEditor);
pack();
setVisible(true);
}
}
and here the UnitEditor a center Pannel where I just fill with a PanelNumber but that's just so that there is something inside and that we can see that the scrollbars don't appear. The Idea is that the bottom is always there and the rest should be filled with the JScrollPane.
package main;
import java.awt.BorderLayout;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
#SuppressWarnings("serial")
public class UnitEditor extends JPanel {
private PanelNumbers numbers = new PanelNumbers();
private JScrollPane scrollPane;
public UnitEditor() {
super();
JPanel firstPanel = new JPanel();
firstPanel.setLayout(new BoxLayout(firstPanel, BoxLayout.Y_AXIS));
firstPanel.add(numbers);
JPanel bottom = new JPanel();
JButton save = new JButton("save");
bottom.add(save);
scrollPane=new JScrollPane(firstPanel);
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
add(bottom,BorderLayout.SOUTH);
}
}
finally the PanelNumber but one could exchange this with anything.
package main;
import java.awt.GridLayout;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
#SuppressWarnings("serial")
public class PanelNumbers extends JPanel{
private Map<Value, JFormattedTextField> nums = new HashMap<>();
public PanelNumbers(){
super();
setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
JFormattedTextField tmp;
JPanel numbers;
numbers = new JPanel();
numbers.setBorder(BorderFactory.createTitledBorder("Numbers"));
numbers.setLayout(new GridLayout(0, 6));
for (Value s : Value.values()) {
numbers.add(new JLabel(s.n()));
tmp = new JFormattedTextField(NumberFormat.getInstance());
setFocus(tmp);
numbers.add(tmp);
nums.put(s, tmp);
}
add(numbers);
}
public void setUnit(String name){
for (Value key : nums.keySet())
nums.get(key).setValue(0);
}
public void save(){
}
private int toNumber(String t) {
int res = 0;
try {
res = Integer.parseInt(t);
} catch (Exception e) {
}
return res;
}
private void setFocus(final JFormattedTextField num) {
num.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
num.selectAll();
}
});
}
});
//num.setPreferredSize(new Dimension(20, 10));
num.setMaximumSize(num.getPreferredSize());
}
public enum Value {
// Kampf
GROESSE("Groesse"),
WAFFENFERTIGKEIT("Waffenfertigkeit"),
FERNKAMPFFERTIGKEIT("Fernkampffertigkeit"),
ANGRIFFSBONUS("Angriffs Bonus"),
NAHKAMPFPANZERUNG("Panzerung nah"),
FERNKAMPFPANZERUNG("Panzerung fern"),
INITIATIVE("Initiative"),
TP("Treffer"),
// Mouvement
FELDER("Felder"),
BWS("Bewegungspunkte"),
B("B Befehl"),
A("A Befehl"),
P("P Befehl"),
H("H Befehl"),
M("Manoever"),
UEBERR("Ueberrenen"),
//Moral
FURCHTFAKTOR("Furchtfaktor"),
MORALERST("Erster Moralwert"),
MORALZWEIT("Zweiter Moralwert"),
//Rest
MAGIE("Magie"),
KONTROL("Kontrollbereich"),
STERNE("Sterne"),
ELEMENTE("Elemente"),
ELEMENTEPROFELD("Elemente pro Feld"),
KOSTEN("Kosten");
private String name;
Value(String name){
this.name = name;
}
public String n(){
return name;
}
}
}
setting the layout of display to GridLayout(1,1) solved the problem, somehow the original layout just let the inner panel become as big as it wants and hence the JScrollPane didn't feel the urge to make it self smaller and have scrollbars.

Loop Instead of Button for displaying images in JLabel? [duplicate]

in a java aplication I have a Jlabel which i want to assign a new image to every time i click a button, using a for loop i can get it to just display the last image skipping all in between images, i know there is a error in my logic here maybe i should not be using a for loop?? any advice
private String imageList[];
ImageIcon image;
imageList = new String[] {"src\\Tour_Eiffel_Wikimedia_Commons.jpg","src\\Ben.jpg", "src\\Rio.jpg", "src\\Liberty.jpg", "src\\Pyramid.jpg"};
//constructor setting first image to display on load
public GeographyGameGUI() {
image = new ImageIcon(imageList[0]);
imageLbl.setIcon(image);
}
//button method
private void nextBtnActionPerformed(java.awt.event.ActionEvent evt) {
for (imgCount = 1; imgCount < imageList.length; imgCount++) {
image = new ImageIcon(imageList[imgCount]);
imageLbl.setIcon(image);
}
if i dont use a for loop and simply use a counter (displayed below) which i declare outside of the button method it loops correctly displaying the images but runs into a ArrayIndexOutOfBoundsException. what is the best practice here? thanks
image = new ImageIcon(imageList[imgCount]);
imageLbl.setIcon(image);
imgCount++;
You're, essentially, blocking the Event Dispatching Thread, prevent it from updating the UI. See Concurrency in Swing for more details
Instead, you should use a javax.swing.Timer to loop over the images, allowing the UI to update before changing to the next one...
See How to use Swing Timers for more details.
Java arrays are zero indexed, this means that the first element in the array is a position 0, not 1
Don't reference src directly within your code, the src directory will not exist once the application is built and packaged
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel label;
private String[] imageList = new String[] {"/Tour_Eiffel_Wikimedia_Commons.jpg","/Ben.jpg", "/Rio.jpg", "/Liberty.jpg", "/Pyramid.jpg"};
public TestPane() {
setLayout(new BorderLayout());
label = new JLabel();
add(label);
JButton btn = new JButton("Play");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
btn.setEnabled(false);
Timer timer = new Timer(1000, new ActionListener() {
private int count;
#Override
public void actionPerformed(ActionEvent e) {
if (count < imageList.length) {
try {
label.setIcon(
new ImageIcon(
ImageIO.read(
TestPane.this.getClass().getResource(imageList[count]))));
} catch (IOException exp) {
exp.printStackTrace();
}
count++;
} else {
((Timer)e.getSource()).stop();
}
}
});
timer.stop();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
Your counter reaches the end of the array so you get out of bounds exception. After each increment you should check whether the end of array has been reached, and if so, set the counter to 0.
If you want to iterate over a few images with a delay on single click you need to use SwingWorker. Using delays in your action listener will suspend event dispatch thread, which means that no other updates or interactions with swing components will be available (it is likely that refreshes will not be done correctly too).
If you do a few updates (setIcon) in a very short time, Swing usually refreshes the component after the last of them, which means that only last image will be visible.
Have a look here: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

Using ListCellRenderers on selected entries

I'm using a ListCellRenderer to edit the appearance of entries in a JList. Once they are selected (by clicking them, this code is within a click event) I call the ListCellRenderer to change the color of the text. If they are selected again I want the text to return to the normal color. The problem I am having is that once I select a second entry the first entry goes back to its normal color. How can I keep selected entries the selected color until they are actually deselected? Here is the section where I actually call the function:
for(int i = 0; i < selectedEntries.size() - 1; i++){
System.out.println("Inside the for loop at entry:" + i);
if(selectedEntries.get(i).equals(selectedEntry)){
selectedEntries.remove(i);
removed = true;
renderer.getListCellRendererComponent(logEntries, value, index, false, false);
System.out.println("Duplicate Entry Removed From List");
}
}
if(!removed){
selectedEntries.add(selectedEntry);
renderer.getListCellRendererComponent(logEntries, value, index, true, false);
}
Just for ease of interpretation selectedEntries is an ArrayList containing each selected entry's text.
Once they are selected (by clicking them, this code is within a click event) I call the ListCellRenderer to change the color of the text
No, that's not how it should work, the ListCellRenderer will be called again (by the JList) and the isSelected parameter will be true, to which you would render the values differently
The ListCellRenderer is responsible for rendering the entire state, selected or not selected.
Have a look at Writing a Custom Cell Renderer for more details
For example
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
DefaultListModel<String> model = new DefaultListModel<>();
model.addElement("Apples");
model.addElement("Bananas");
model.addElement("Peachs");
model.addElement("Pears");
JList<String> listOfStrings = new JList<>(model);
listOfStrings.setCellRenderer(new FancyPancyListCellRenderer());
add(new JScrollPane(listOfStrings));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public static class FancyPancyListCellRenderer extends DefaultListCellRenderer {
protected static final Font SELECTED_FONT = new Font("Comic Sans MS", Font.PLAIN, 12);
#Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (isSelected) {
setForeground(Color.YELLOW);
setFont(SELECTED_FONT);
} else {
setFont(UIManager.getFont("Label.font"));
}
return this;
}
}
}
Also, MouseListener really isn't a suitable means by which to detect changes in the selection, what happens if the user selects rows using the keyboard? You should be using a ListSelectionListener instead (but not to correct this issue).
Have a look at How to Write a List Selection Listener and How to Use Lists for more details

How to set the title of a JComboBox when nothing is selected?

I want to have a JCombobox in my Swing application, which shows the title when nothing is selected. Something like this:
COUNTRY ▼
Spain
Germany
Ireland
I want "COUNTRY" to show when the selected index is -1 and thus, the user wouldn't be able to select it. I tried to put it on the first slot and then overriding the ListCellRenderer so the first element appears greyed out, and handling the events so when trying to select the "title", it selects the first actual element, but I think this is a dirty approach.
Could you lend me a hand?
Overriding the ListCellRenderer is a good approach, but you tried something overly complicated. Just display a certain string if you are rendering the cell -1 and there is no selection (value is null). You are not limited to display elements on the list.
The following is an example program that demonstrates it:
Full Code:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.SwingUtilities;
public class ComboBoxTitleTest
{
public static final void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run()
{
new ComboBoxTitleTest().createAndShowGUI();
}
});
}
public void createAndShowGUI()
{
JFrame frame = new JFrame();
JPanel mainPanel = new JPanel();
JPanel buttonsPanel = new JPanel();
frame.add(mainPanel);
frame.add(buttonsPanel, BorderLayout.SOUTH);
String[] options = { "Spain", "Germany", "Ireland", "The kingdom of far far away" };
final JComboBox comboBox = new JComboBox(options);
comboBox.setRenderer(new MyComboBoxRenderer("COUNTRY"));
comboBox.setSelectedIndex(-1); //By default it selects first item, we don't want any selection
mainPanel.add(comboBox);
JButton clearSelectionButton = new JButton("Clear selection");
clearSelectionButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
comboBox.setSelectedIndex(-1);
}
});
buttonsPanel.add(clearSelectionButton);
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
class MyComboBoxRenderer extends JLabel implements ListCellRenderer
{
private String _title;
public MyComboBoxRenderer(String title)
{
_title = title;
}
#Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean hasFocus)
{
if (index == -1 && value == null) setText(_title);
else setText(value.toString());
return this;
}
}
}
index == -1 in the renderer is the head component that, by default, displays the selected item and where we want to put our title when there's no selection.
The renderer knows that there's nothing selected because the value passed to it is null, which is usually the case. However if for some weird reasons you had selectable null values in your list, you can just let the renderer consult which is the explicit current selected index by passing it a reference to the comboBox, but that is totally unrealistic.

Java - How do you correctly add a ListSelectionListener to a controller?

I've recently been struggling with a Java problem that has been driving me mad. I've been attempting to add a ListSelectionListener in my Controller to a JList in my View but when I have successfully managed to attach the listener to something, it has not been the JList that has been drawing on the screen.
The code below gives a basic idea of what I am attempting to do.
This is my class with my main method:
package Application;
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
View v = new View();
Controller c = new Controller(v);
}
}
This is my View:
package Application;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
public class View extends JFrame {
/* Components for the JList */
public DefaultListModel<String> listModel = new DefaultListModel<String>();
public JList<String> selectedItems = new JList<String>(listModel);
JScrollPane scroll = new JScrollPane(selectedItems);
public View()
{
// set the window title
this.setTitle("JList Test");
// set the window size
this.setSize(new Dimension(400, 400));
// set the window start position
this.setLocation(25, 25);
// set the window layout
FlowLayout layout = new FlowLayout();
layout.setHgap(0);
layout.setVgap(0);
this.setLayout(layout);
// set the window background
this.getContentPane().setBackground(Color.BLACK);
// make the window non-resizable
this.setResizable(false);
// set the default close operation
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// setup and add the JList
initJList();
this.add(scroll);
// add elements to the list model
listModel.addElement(" Item 1 ");
listModel.addElement(" Item 2 ");
listModel.addElement(" Item 3 ");
// make the gui visible
this.setVisible(true);
}
private void initJList() {
selectedItems.setVisibleRowCount(8);
selectedItems.setFixedCellWidth(300);
selectedItems.setFixedCellHeight(40);
selectedItems.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
selectedItems.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
selectedItems = new JList<String>(listModel);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
}
}
This is my controller:
package Application;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class Controller implements ListSelectionListener {
View gui;
public Controller(View v)
{
gui = v;
gui.selectedItems.addListSelectionListener(this);
}
#Override
public void valueChanged(ListSelectionEvent e) {
System.out.println("Selection changed!");
}
}
It compiles OK and the list draws fine but the ListSelectionListener never fires when I select anything in the JList. Can somebody tell me where exactly I am going wrong? Because I have tried loads of things now and I am completely stumped! The thing I find strange is when I attempt to do what I am doing here with JButtons and an ActionListener it works absolutely fine.
Any help is appreciated.
you did a mistake there in initJList() function, you already have passed value of listModel before itself, and again you have passed this value here in this function , so commenting this line will solve the problem. the modified function will look like this here:
private void initJList() {
selectedItems.setVisibleRowCount(8);
selectedItems.setFixedCellWidth(300);
selectedItems.setFixedCellHeight(40);
selectedItems.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
selectedItems.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
//selectedItems = new JList<String>(listModel);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
}
Otherwise :
Declaring the JList like this
public JList<String> selectedItems;
and keeping the function as it is will run fine.

Categories