【问题标题】:How to make a cell behave like it's editable but have it read only?如何使单元格表现得像可编辑但只读?
【发布时间】:2013-06-15 02:52:37
【问题描述】:

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

【问题讨论】:

    标签: java swing jtable tablecelleditor abstracttablemodel


    【解决方案1】:

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

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

    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】:

    如果表格上启用了单元格选择,您可以默认从选定的单元格中复制/粘贴。

    这是一个带有单元格选择的只读 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);
      }
    }
    

    【讨论】:

      【解决方案3】:

      您必须在具有空实现的模型上覆盖 setValue()isCellEditable()

      @Override
      public void setValueAt(Object oValue, int row, int nColumn)
      {
      }
      
      @Override
      public boolean isCellEditable(int rowIndex, int columnIndex)
      {
          return true;
      }
      

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

      【讨论】:

      • 感谢工作!虽然没有保留更改,但是否可以阻止用户进行任何更改?
      • 使用此解决方案,可以直观地进行更改,但只是暂时的。他们不会致力于表的模型。
      猜你喜欢
      • 1970-01-01
      • 2011-08-26
      • 2014-10-25
      • 2011-09-11
      • 2016-07-15
      • 2014-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多