JButton in JList cell is not clickable

痴心易碎 提交于 2020-01-03 08:43:09

问题


In my current swing project I have a JList displaying all active sockets, and each cell has a JButton to close that socket. But the JButton in the cell is not clickable: listener does not get fired.

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. Am I wrong or JList just does not support JButton in the getting fired?


回答1:


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.




回答2:


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.

Out of the box, JList is not editable.




回答3:


Try the example posted here http://tips4java.wordpress.com/2009/07/12/table-button-column/

Do the same with your JList



来源:https://stackoverflow.com/questions/13447972/jbutton-in-jlist-cell-is-not-clickable

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!