Reputation: 3564
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
Upvotes: 2
Views: 3417
Reputation: 109823
Renderer
is only about to dispaying and formatting JComponets
inside JList
, JComboBox
or JTable
, basically everything is described in JList
and JTable
tutorials, then by using JList
you can you can onlyJList
you can't returns JButtons
is clicked or another JButton's events
, only by the selection in the JList
, sure by this event you can generating awaiting event to the GUI, but only from JList
selection, not from JButton
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 in JList
, because there are missed importand methods in compare with JTable
,
replace JList
with JTable
, create JTable
without TableHeader
and with only one Column
.
.
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;
}
}
}
Upvotes: 1
Reputation: 13
@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.
Upvotes: 0
Reputation: 8874
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.
Upvotes: 3
Reputation: 2050
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.
Upvotes: 1