问题
I have a JTable in which I want the cells to behave the way it behaves when you have the cells editable, but the cells cannot be editable, in other terms, read only. So if I double click on a cell, I should only be able to select text within the cell and copy text from that cell.
回答1:
is it possible to prevent the user to make any changes?
You would need to use a custom editor:
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();
}
});
}
}
回答2:
You have to override setValue()
on the model with an empty implementation and isCellEditable()
.
@Override
public void setValueAt(Object oValue, int row, int nColumn)
{
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex)
{
return true;
}
The isCellEditable
tells the table which cells are allowed to be entered, and the setValue
is called if the user enter some data. Since you overrode the function with an empty implementation, the cellwill revert to the existing value.
回答3:
If cell selection is enabled on the table, you can Copy/Paste from the selected cell by default.
Here's a demo with a read-only JTable with cell selection on, and a JTextField to paste into:
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);
}
}
来源:https://stackoverflow.com/questions/17176539/how-to-make-a-cell-behave-like-its-editable-but-have-it-read-only