具有JSpinner的JTable启用/禁用 [英] JTable with JSpinner Enable/Disable

查看:63
本文介绍了具有JSpinner的JTable启用/禁用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个3列的JTable.第2列是一个复选框,我想为该行启用/禁用JSpinner.

I've got a 3 column JTable. Column 2 is a checkbox which I want to enable/disable the JSpinner for that row.

除了一件事之外,我已经按照自己的方式工作了-JSpinner实际上看起来并不像它的已禁用(文本和微调按钮为灰色).我不太确定如何实现这一目标.我已经尝试过在JSpinner上强行调用setEnabled(false),但是该表似乎无法正确重绘.

I've got working how I want except for one thing -- The JSpinner doesn't actually look like its disabled (text and spinner buttons greyed out). I'm not quite sure how to attain this. I've tried forcibly calling setEnabled(false) on the JSpinner, but the table doesn't seem to redraw correctly.

以下是我通过其他StackOverflow示例工作的一些代码:

Here is some code I've gotten working through other StackOverflow examples:

import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.EventObject;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTable;
import javax.swing.WindowConstants;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

public class SpinnerTable {
    public JComponent makeUI() {
        String[] columnNames = { "Name", "Spinner Enable", "Spinner" };
        final Object[][] data = { { "aaa", true, 1 }, { "bbb", true, 10 },
                { "ccc", true, 10 } };

        final DefaultTableModel model = new DefaultTableModel(data, columnNames) {
            @Override
            public Class<?> getColumnClass(int column) {
                return getValueAt(0, column).getClass();
            }
        };
        JTable table = new JTable(model) {

            @Override
            public void setValueAt(Object aValue, int row, int column) {
                super.setValueAt(aValue, row, column);

            }

            @Override
            public boolean isCellEditable(int row, int column) {

                if (column == 2)
                    return (Boolean) model.getValueAt(row, 1);

                return super.isCellEditable(row, column);
            }

        };

        table.setRowHeight(36);
        table.setAutoCreateRowSorter(true);
        TableColumn column = table.getColumnModel().getColumn(2);
        column.setCellRenderer(new ComboBoxCellRenderer());
        column.setCellEditor(new ComboBoxCellEditor());

        return new JScrollPane(table);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }

    public static void createAndShowGUI() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.getContentPane().add(new SpinnerTable().makeUI());
        f.setSize(320, 240);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

class SpinnerPanel extends JPanel {
    protected JSpinner spinner = new JSpinner() {
        @Override
        public Dimension getPreferredSize() {
            Dimension d = super.getPreferredSize();
            return new Dimension(40, d.height);
        }
    };

    public SpinnerPanel() {
        super();
        setOpaque(true);
        add(spinner);
    }
}

class ComboBoxCellRenderer extends SpinnerPanel implements TableCellRenderer {
    public ComboBoxCellRenderer() {
        super();
        setName("Table.cellRenderer");
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
        setBackground(isSelected ? table.getSelectionBackground() : table
                .getBackground());
        if (value != null) {
            spinner.setValue(value);
        }
        return this;
    }
}

class ComboBoxCellEditor extends SpinnerPanel implements TableCellEditor {
    public ComboBoxCellEditor() {
        super();
        spinner.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                fireEditingStopped();

            }
        });
        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                fireEditingStopped();
            }
        });
    }

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value,
            boolean isSelected, int row, int column) {
        this.setBackground(table.getSelectionBackground());
        spinner.setValue(value);
        return this;
    }

    // Copid from DefaultCellEditor.EditorDelegate
    @Override
    public Object getCellEditorValue() {
        return spinner.getValue();
    }

    @Override
    public boolean shouldSelectCell(EventObject anEvent) {
        if (anEvent instanceof MouseEvent) {
            MouseEvent e = (MouseEvent) anEvent;
            return e.getID() != MouseEvent.MOUSE_DRAGGED;
        }
        return true;
    }

    @Override
    public boolean stopCellEditing() {
        fireEditingStopped();
        return true;
    };

    transient protected ChangeEvent changeEvent = null;

    @Override
    public boolean isCellEditable(EventObject e) {
        return true;
    }

    @Override
    public void cancelCellEditing() {
        fireEditingCanceled();
    }

    @Override
    public void addCellEditorListener(CellEditorListener l) {
        listenerList.add(CellEditorListener.class, l);
    }

    @Override
    public void removeCellEditorListener(CellEditorListener l) {
        listenerList.remove(CellEditorListener.class, l);
    }

    public CellEditorListener[] getCellEditorListeners() {
        return listenerList.getListeners(CellEditorListener.class);
    }

    protected void fireEditingStopped() {
        // Guaranteed to return a non-null array
        Object[] listeners = listenerList.getListenerList();
        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i] == CellEditorListener.class) {
                // Lazily create the event:
                if (changeEvent == null)
                    changeEvent = new ChangeEvent(this);
                ((CellEditorListener) listeners[i + 1])
                        .editingStopped(changeEvent);
            }
        }
    }

    protected void fireEditingCanceled() {
        // Guaranteed to return a non-null array
        Object[] listeners = listenerList.getListenerList();
        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i] == CellEditorListener.class) {
                // Lazily create the event:
                if (changeEvent == null)
                    changeEvent = new ChangeEvent(this);
                ((CellEditorListener) listeners[i + 1])
                        .editingCanceled(changeEvent);
            }
        }
    }
}

推荐答案

当修改第1列时,该表不知道应重新绘制第2列中的单元格.您可以通过手动触发更新来通知表.例如,扩展模型的setValueAt():

The table does not know it should repaint the cell in column 2 when column 1 was modified. You can notify the table by firing an update manually. For example, extend model's setValueAt():

@Override
public void setValueAt(Object aValue, int row, int column) {
    super.setValueAt(aValue, row, column);
    if (column == 1)
        fireTableRowsUpdated(row, row);
}

这将禁用编辑器,并且微调器将变得不可编辑.如果需要实际从视觉上禁用微调器,则可以在渲染器内部基于isCellEditable启用/禁用微调器,即:

This will disable the editor and spinner will become not editable. If you need to actually disable the spinner visually, then, inside the renderer you can enable/disable the spinner based on isCellEditable, ie:

spinner.setEnabled(table.isCellEditable(row, column));

请注意,在当前的实现中,您扩展了JTable以实现isCellEditablesetValueAt.这些实际上应该是模型的一部分.

Note that in your current implementation you extend JTable to implement isCellEditable and setValueAt. These should really be part of the model.

这篇关于具有JSpinner的JTable启用/禁用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆