[英]JButton in JList cell is not clickable
In my current swing project I have a JList
displaying all active sockets, and each cell has a JButton
to close that socket.在我当前的 Swing 项目中,我有一个
JList
显示所有活动的套接字,每个单元格都有一个JButton
来关闭该套接字。 But the JButton
in the cell is not clickable: listener does not get fired.但是单元格中的
JButton
不可点击:监听器不会被触发。
I have modified the code to minimal as follows.我已将代码修改为最小,如下所示。
private class ConnectionListRenderer extends JButton implements ListCellRenderer {
public Component getListCellRendererComponent(JList jlist, Object o, int i, boolean bln, boolean bln1) {
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//do something (close the socket in my project)
}
});
return this;
}
}
jList.setCellRenderer(new ConnectionListRenderer());
The list looks fine, but the button on in is not clickable.该列表看起来不错,但 in 上的按钮不可点击。 Am I wrong or
JList
just does not support JButton
in the getting fired?我错了还是
JList
在被解雇时不支持JButton
?
Here's an example that seems to work, although you don't get the same visual effect of a normal button click.这是一个似乎有效的示例,尽管您无法获得与普通按钮单击相同的视觉效果。 Perhaps someone with better painting skill than me could improve this to simulate the visual pressed button effect.
也许有比我更好的绘画技巧的人可以改进它来模拟视觉按下按钮效果。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* A JList of JButtons.
*/
public class JButtonListDemo implements Runnable
{
private JList jlist;
public static void main(String args[])
{
SwingUtilities.invokeLater(new JButtonListDemo());
}
public void run()
{
Object[] items = new ButtonItem[] {
new ButtonItem("Apple"),
new ButtonItem("Banana"),
new ButtonItem("Carrot"),
new ButtonItem("Date"),
new ButtonItem("Eggplant"),
new ButtonItem("Fig"),
new ButtonItem("Guava"),
};
jlist = new JList(items);
jlist.setCellRenderer(new ButtonListRenderer());
jlist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jlist.setVisibleRowCount(5);
jlist.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent event)
{
clickButtonAt(event.getPoint());
}
});
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new JScrollPane(jlist));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void clickButtonAt(Point point)
{
int index = jlist.locationToIndex(point);
ButtonItem item = (ButtonItem) jlist.getModel().getElementAt(index);
item.getButton().doClick();
// jlist.repaint(jlist.getCellBounds(index, index));
}
public class ButtonItem
{
private JButton button;
public ButtonItem(String name)
{
this.button = new JButton(name);
button.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
System.out.println(button.getText() + " was clicked.");
}
});
}
public JButton getButton()
{
return button;
}
@Override
public String toString()
{
return button.getText();
}
}
class ButtonListRenderer extends JButton implements ListCellRenderer
{
public Component getListCellRendererComponent(JList comp, Object value, int index,
boolean isSelected, boolean hasFocus)
{
setEnabled(comp.isEnabled());
setFont(comp.getFont());
setText(value.toString());
if (isSelected)
{
setBackground(comp.getSelectionBackground());
setForeground(comp.getSelectionForeground());
}
else
{
setBackground(comp.getBackground());
setForeground(comp.getForeground());
}
return this;
}
}
}
Alternatively, you could always layout your JButtons vertically on a JPanel (using a new GridLayout(0,1) perhaps) and then put your JPanel in a JScrollPane, thus mocking a JList of JButtons.或者,您可以始终在 JPanel 上垂直布局 JButton(可能使用新的 GridLayout(0,1)),然后将 JPanel 放在 JScrollPane 中,从而模拟 JButton 的 JList。
Render's are not "real" components, they are "rubber stamps" painted onto the surface of the parent component.渲染不是“真正的”组件,它们是涂在父组件表面上的“橡皮图章”。 They have no "physical" presence.
他们没有“物理”存在。
A JList
will have only one instance of the render and this is used to "stamp" each of the items from the list model onto the view. JList
将只有一个渲染实例,这用于将列表模型中的每个项目“标记”到视图上。
Out of the box, JList
is not editable.开箱即用,
JList
不可编辑。
Try the example posted here http://tips4java.wordpress.com/2009/07/12/table-button-column/ 试试这里发布的例子http://tips4java.wordpress.com/2009/07/12/table-button-column/
Do the same with your JList 对JList执行相同操作
Another solution would be to use two lists next to each other.另一种解决方案是使用两个相邻的列表。 The first one renders the actual list content, while the second renders buttons, you can add the two lists to a
JPanel
and layout them with BorderLayout
( Borderlayout.CENTER
and BorderLayout.EAST
).第一个呈现实际列表内容,而第二个呈现按钮,您可以将两个列表添加到
JPanel
并使用BorderLayout
( Borderlayout.CENTER
和BorderLayout.EAST
)对其进行布局。 Add this JPanel
to the viewport of a JScrollPane
.将此
JPanel
添加到JScrollPane
的视口。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.