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.