An application i am working on requires the use of a JList where each ListItem is a Label followed by a Button.
What i did is i created a Class having a String member for the Text field and added the Class Objects to the Jlist.
Now for the Button,i implemented a Custom List Cell Renderer which is as :
public renderer()
{
text=new JLabel();
button=new JButton("Track");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
System.out.println("Hey");
}
});
}
public Component getListCellRendererComponent(JList list, Object value, int index,boolean isSelected, boolean cellHasFocus)
{
it=(item)list.getModel().getElementAt(index);
text.setText(it.tex);
return this;
}
public void paintComponent(Graphics g)
{
this.add(text);
this.add(button);
this.setVisible(true);
}
public Dimension getpreferredSize(){
Font font=UIManager.getDefaults().getFont("JLabel.Font");
Graphics g=getGraphics();
FontMetrics fm=g.getFontMetrics(font);
return new Dimension(fm.stringWidth(it.tex)+button.getWidth(),fm.getHeight()>button.getWidth()?fm.getHeight():button.getWidth());
}
}
But the button is non responsive when i Click it.What did i miss?
Thanks
You should create a custom List Cell Editor too, wich reuses code from ListCellRenderer for looks, but implements action listener on button. The cell renderers are used just to stamp graphic images in list. For using controls in JList you should use cell editors.
Why to go into so much trouble with JList, renderers and editors, when you can simply create a JPanel with box layout, put all the labels and buttons inside and then display this panel in a scroll pane. Code will be short and there wont be any troubles with behaviour.
Generally speaking, putting other components is components such as JTable and JList is almost always more trouble than it is worth.
Renderer
is only about to dispaying and formattingJComponets
insideJList
,JComboBox
orJTable
, basically everything is described inJList
andJTable
tutorials, then by usingJList
you can you can only



- maybe I'm wrong but I think than nothing else, from the
JList
you can't returnsJButtons
is clicked or anotherJButton's events
, only by the selection in theJList
, sure by this event you can generating awaiting event to the GUI, but only fromJList
selection, not fromJButton
code
import java.awt.*;
import javax.swing.*;
public class ListPanel extends JFrame {
private static final long serialVersionUID = 1L;
public ListPanel() {
DefaultListModel model = new DefaultListModel();
model.addElement(createPanel("one"));
model.addElement(createPanel("two"));
model.addElement(createPanel("three"));
model.addElement(createPanel("four"));
JList list = new JList(model);
list.setCellRenderer(new PanelRenderer());
add(list);
}
public static JButton createPanel(String text) {
JButton panel = new JButton(text);
return panel;
}
public static void main(String[] args) {
ListPanel frame = new ListPanel();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
class PanelRenderer implements ListCellRenderer {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JButton renderer = (JButton) value;
renderer.setBackground(isSelected ? Color.red : list.getBackground());
return renderer;
}
}
}
you have got implements own
Editor
, never tried inJList
, because there are missed importand methods in compare withJTable
,replace
JList
withJTable
, createJTable
withoutTableHeader
and with only oneColumn
.
.
EDIT (@Jakub Zaverka)
.
.

import java.awt.*;
import javax.swing.*;
public class ListPanel extends JFrame {
private static final long serialVersionUID = 1L;
public ListPanel() {
setLayout(new GridLayout(0, 2, 10, 10));
DefaultListModel model = new DefaultListModel();
model.addElement(createButtons("one"));
model.addElement(createButtons("two"));
model.addElement(createButtons("three"));
model.addElement(createButtons("four"));
model.addElement(createButtons("five"));
model.addElement(createButtons("six"));
model.addElement(createButtons("seven"));
model.addElement(createButtons("eight"));
model.addElement(createButtons("nine"));
model.addElement(createButtons("ten"));
model.addElement(createButtons("eleven"));
model.addElement(createButtons("twelwe"));
JList list = new JList(model);
list.setCellRenderer(new PanelRenderer());
add(new JScrollPane(list));
add(new JScrollPane(createPanel()));
}
public static JPanel createPanel() {
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(0, 1, 1, 1));
panel.add(createButtons("one"));
panel.add(createButtons("two"));
panel.add(createButtons("three"));
panel.add(createButtons("four"));
panel.add(createButtons("five"));
panel.add(createButtons("six"));
panel.add(createButtons("seven"));
panel.add(createButtons("eight"));
panel.add(createButtons("nine"));
panel.add(createButtons("ten"));
panel.add(createButtons("eleven"));
panel.add(createButtons("twelwe"));
return panel;
}
public static JButton createButtons(String text) {
JButton button = new JButton(text);
return button;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
ListPanel frame = new ListPanel();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
//frame.pack();
frame.setSize(270, 200);
frame.setVisible(true);
}
});
}
class PanelRenderer implements ListCellRenderer {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JButton renderer = (JButton) value;
renderer.setBackground(isSelected ? Color.red : list.getBackground());
return renderer;
}
}
}
@Jakub Zaverka I agree, i already use this, and it work fine. @nikel I recommend you to use a GridBagLayout and a GridBagConstraint to manage your component.
来源:https://stackoverflow.com/questions/9886682/jbutton-not-responding-to-click-events