如何让一个单元格表现得像它的可编辑但只读它?

时间:2013-06-18 18:47:24

标签: java swing jtable tablecelleditor abstracttablemodel

我有一个JTable,其中我希望单元格在单元格可编辑时的行为方式,但单元格无法编辑,换句话说,只读。因此,如果我双击一个单元格,我应该只能在单元格中选择文本并从该单元格中复制文本。

3 个答案:

答案 0 :(得分:5)

  

是否可以阻止用户进行任何更改?

您需要使用自定义编辑器:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.text.*;

public class TableCopyEditor extends JPanel
{
    public TableCopyEditor()
    {
        String[] columnNames = {"Editable", "Non Editable"};
        Object[][] data =
        {
            {"1", "one"},
            {"2", "two"},
            {"3", "three"}
        };

        JTable table = new JTable(data, columnNames);
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = new JScrollPane( table );
        add( scrollPane );

        //  Create a non-editable editor, but still allow text selection

        Caret caret = new DefaultCaret()
        {
            public void focusGained(FocusEvent e)
            {
                setVisible(true);
                setSelectionVisible(true);
            }
        };
        caret.setBlinkRate( UIManager.getInt("TextField.caretBlinkRate") );

        JTextField textField = new JTextField();
        textField.setEditable(false);
        textField.setCaret(caret);
        textField.setBorder(new LineBorder(Color.BLACK));

        DefaultCellEditor dce = new DefaultCellEditor( textField );
        table.getColumnModel().getColumn(1).setCellEditor(dce);
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("Table Copy Editor");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new TableCopyEditor() );
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

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

}

答案 1 :(得分:2)

您必须使用空实现和setValue()覆盖模型上的isCellEditable()

@Override
public void setValueAt(Object oValue, int row, int nColumn)
{
}

@Override
public boolean isCellEditable(int rowIndex, int columnIndex)
{
    return true;
}

isCellEditable告诉表格允许输入哪些单元格,如果用户输入一些数据,则会调用setValue。由于您使用空实现覆盖函数,因此单元格将恢复为现有值。

答案 2 :(得分:1)

如果在表格上启用了单元格选择,则默认情况下可以从所选单元格中复制/粘贴。

这是一个带有只读JTable且带有单元格选择的演示,以及一个要粘贴到的JTextField:

import java.awt.*;

import javax.swing.*;
import javax.swing.table.*;

public class TableCellSelectionDemo implements Runnable
{
  public static void main(String[] args)
  {
    SwingUtilities.invokeLater(new TableCellSelectionDemo());
  }

  public void run()
  {
    String[] columnNames = {"First", "Last"};
    Object[][] data =
    {
      {"Barney", "Rubble"},
      {"Fred", "Flintstone"}
    };

    DefaultTableModel model = new DefaultTableModel(data, columnNames)
    {
      @Override
      public boolean isCellEditable(int row, int column)
      {
        return false;
      }
    };

    JTable table = new JTable(model);
    table.setCellSelectionEnabled(true);
    table.setPreferredScrollableViewportSize(table.getPreferredSize());

    JScrollPane scroll = new JScrollPane(table);
    scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    scroll.setHorizontalScrollBarPolicy(
        JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

    JTextField text = new JTextField(40);

    JFrame frame = new JFrame("Demo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(scroll, BorderLayout.CENTER);
    frame.getContentPane().add(text, BorderLayout.SOUTH);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }
}