如何在JTable中使用JButton?

时间:2015-10-21 16:36:05

标签: java swing jtable

我一直试图在JTable中添加一个可点击的按钮,但我的表现并不好。

我使用ButtonColumn类来执行此操作,但操作被忽略 - 按钮显示但单击时没有任何操作。

/**
 *  The ButtonColumn class provides a renderer and an editor that looks like a
 *  JButton. The renderer and editor will then be used for a specified column
 *  in the table. The TableModel will contain the String to be displayed on
 *  the button.
 *
 *  The button can be invoked by a mouse click or by pressing the space bar
 *  when the cell has focus. Optionally a mnemonic can be set to invoke the
 *  button. When the button is invoked the provided Action is invoked. The
 *  source of the Action will be the table. The action command will contain
 *  the model row number of the button that was clicked.
 *
 */
public class ButtonColumn extends AbstractCellEditor
    implements TableCellRenderer, TableCellEditor, ActionListener, MouseListener{
    /**
     * 
     */
    private static final long serialVersionUID = -6737467999355167233L;
    private JTable table;
    private Action action;
    private int mnemonic;
    private Border originalBorder;
    private Border focusBorder;

    private JButton renderButton;
    private JButton editButton;
    private Object editorValue;
    private boolean isButtonColumnEditor;

    /**
     *  Create the ButtonColumn to be used as a renderer and editor. The
     *  renderer and editor will automatically be installed on the TableColumn
     *  of the specified column.
     *
     *  @param table the table containing the button renderer/editor
     *  @param action the Action to be invoked when the button is invoked
     *  @param column the column to which the button renderer/editor is added
     */
    public ButtonColumn(JTable table, Action action, int column)
    {
        this.table = table;
        this.action = action;

        renderButton = new JButton();
        editButton = new JButton();
        editButton.setFocusPainted( false );
        editButton.addActionListener( this );
        originalBorder = editButton.getBorder();
        setFocusBorder( new LineBorder(Color.BLUE) );

        TableColumnModel columnModel = table.getColumnModel();
        columnModel.getColumn(column).setCellRenderer( this );
        columnModel.getColumn(column).setCellEditor( this );
        table.addMouseListener( this );
    }


    /**
     *  Get foreground color of the button when the cell has focus
     *
     *  @return the foreground color
     */
    public Border getFocusBorder()
    {
        return focusBorder;
    }

    /**
     *  The foreground color of the button when the cell has focus
     *
     *  @param focusBorder the foreground color
     */
    public void setFocusBorder(Border focusBorder)
    {
        this.focusBorder = focusBorder;
        editButton.setBorder( focusBorder );
    }

    public int getMnemonic()
    {
        return mnemonic;
    }

    /**
     *  The mnemonic to activate the button when the cell has focus
     *
     *  @param mnemonic the mnemonic
     */
    public void setMnemonic(int mnemonic)
    {
        this.mnemonic = mnemonic;
        renderButton.setMnemonic(mnemonic);
        editButton.setMnemonic(mnemonic);
    }

    @Override
    public Component getTableCellEditorComponent(
        JTable table, Object value, boolean isSelected, int row, int column)
    {
        if (value == null)
        {
            editButton.setText( "" );
            editButton.setIcon( null );
        }
        else if (value instanceof Icon)
        {
            editButton.setText( "" );
            editButton.setIcon( (Icon)value );
        }
        else
        {
            editButton.setText( value.toString() );
            editButton.setIcon( null );
        }

        this.editorValue = value;
        return editButton;
    }

    @Override
    public Object getCellEditorValue()
    {
        return editorValue;
    }

//
//  Implement TableCellRenderer interface
//
    @Override
    public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    {
        if (isSelected)
        {
            renderButton.setForeground(table.getSelectionForeground());
            renderButton.setBackground(table.getSelectionBackground());
        }
        else
        {
            renderButton.setForeground(table.getForeground());
            renderButton.setBackground(UIManager.getColor("Button.background"));
        }

        if (hasFocus)
        {
            renderButton.setBorder( focusBorder );
        }
        else
        {
            renderButton.setBorder( originalBorder );
        }

//          renderButton.setText( (value == null) ? "" : value.toString() );
            if (value == null)
            {
                renderButton.setText( "" );
                renderButton.setIcon( null );
            }
            else if (value instanceof Icon)
            {
                renderButton.setText( "" );
                renderButton.setIcon( (Icon)value );
            }
            else
            {
                renderButton.setText( value.toString() );
                renderButton.setIcon( null );
            }

            return renderButton;
        }

    //
    //  Implement ActionListener interface
    //
        /*
         *  The button has been pressed. Stop editing and invoke the custom Action
         */
        @Override
        public void actionPerformed(ActionEvent e)
        {
            int row = table.convertRowIndexToModel( table.getEditingRow() );
            fireEditingStopped();

            //  Invoke the Action

            ActionEvent event = new ActionEvent(
                table,
                ActionEvent.ACTION_PERFORMED,
                "" + row);
            action.actionPerformed(event);
        }

    //
    //  Implement MouseListener interface
    //
        /*
         *  When the mouse is pressed the editor is invoked. If you then then drag
         *  the mouse to another cell before releasing it, the editor is still
         *  active. Make sure editing is stopped when the mouse is released.
         */
        @Override
        public void mousePressed(MouseEvent e)
        {
            if (table.isEditing()
            &&  table.getCellEditor() == this)
                isButtonColumnEditor = true;
        }

        @Override
        public void mouseReleased(MouseEvent e)
        {
            if (isButtonColumnEditor
            &&  table.isEditing())
                table.getCellEditor().stopCellEditing();

            isButtonColumnEditor = false;
        }

        @Override
        public void mouseClicked(MouseEvent e) {}
        @Override
        public void mouseEntered(MouseEvent e) {}
        @Override
        public void mouseExited(MouseEvent e) {}
    }

我的实际代码:

ButtonColumn deleteColumn = new ButtonColumn(eventTable, new AbstractAction(){
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("It works!!!!");
        }
 }, 3);

似乎永远不会被打印出来。我真的可以使用一些帮助。提前谢谢!

编辑:我也尝试过此代码,但似乎也无效。

eventTable.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                JTable target = (JTable)e.getSource();
                int row = target.getSelectedRow();
                int column = target.getSelectedColumn();
                System.out.println("Event table was clicked in row "+row+", column "+column);
            }
        });

2 个答案:

答案 0 :(得分:0)

看一下TableCellRenderer解释。

界面TableCellRenderer

答案 1 :(得分:0)

我的猜测是该列不可编辑,这意味着永远不会调用编辑器,因此永远不会调用Action。

如果这没有帮助,请发布一个正确的SSCCE来证明问题。