我正在尝试禁用JTable中除1列之外的所有行的选择。 (示例屏幕截图中的Layer Column)。在其他列中,我有旋转器和复选框,我希望用户能够与之交互,而不会影响图层列中的选择。
我最初的尝试是在发生任何选定行时将其存储起来,然后在选择A列外的单元格时恢复到该组选定行。它有点工作,但问题是它闪现"选择其他单元格时,在将其还原之前。如何防止" flash"?
以下是我设置的示例来说明问题:
public class TableTest {
static int[] selectedRows = new int[0];
final static String[] columns = new String[] { "Layer", "Enabled", "Read Only", "Storage" };
final static DefaultTableModel model = new DefaultTableModel(new Vector(), new Vector(Arrays.asList(columns))) {
@Override
public void setValueAt(Object obj, int row, int col) {
if (obj instanceof Boolean || obj instanceof Integer) {
Object localObject = super.getValueAt(row, col);
if (localObject instanceof Integer) {
Integer val = (Integer) localObject;
((SpinnerCell) obj).getSpinner().setValue(val);
} else if (localObject instanceof Boolean) {
Boolean val = (Boolean) localObject;
((CheckboxCell) obj).getCheckBox().setEnabled(val);
}
} else {
super.setValueAt(obj, row, col);
}
}
@Override
public boolean isCellEditable(int rowIndex, int colIndex) {
return colIndex != 0;
}
};
public static void main(String[] a) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JTable table = new JTable(model) {
@Override
public TableCellRenderer getCellRenderer(final int rowIndex, int colIndex) {
int reaRowlIndex = convertRowIndexToModel(rowIndex);
int realColumnIndex = convertColumnIndexToModel(colIndex);
Object o = model.getValueAt(reaRowlIndex, realColumnIndex);
if (o instanceof TableCellRenderer) {
return (TableCellRenderer) o;
} else {
return super.getCellRenderer(reaRowlIndex, realColumnIndex);
}
}
//
@Override
public TableCellEditor getCellEditor(final int rowIndex, int colIndex) {
int reaRowlIndex = convertRowIndexToModel(rowIndex);
int realColumnIndex = convertColumnIndexToModel(colIndex);
Object o = model.getValueAt(reaRowlIndex, realColumnIndex);
if (o instanceof TableCellEditor) {
return (TableCellEditor) o;
} else {
return super.getCellEditor(reaRowlIndex, realColumnIndex);
}
}
};
table.getTableHeader().setReorderingAllowed(false);
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent arg0) {
if (table.getSelectedColumn() == 0) {
selectedRows = table.getSelectedRows();
System.out.println("Selected Rows before " + Arrays.toString(selectedRows));
}
}
});
final ListSelectionModel columnListSelectionModel = table.getColumnModel().getSelectionModel();
columnListSelectionModel.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if (table.getSelectedColumn() != 0) {
table.clearSelection();
System.out.println("Selected Rows during " + Arrays.toString(table.getSelectedRows()));
for (int i = 0; i < selectedRows.length; i++) {
table.getSelectionModel().addSelectionInterval(selectedRows[i], selectedRows[i]);
}
System.out.println("Selected Rows after " + Arrays.toString(table.getSelectedRows()));
}
}
});
model.addRow(new Object[] { "Bird", new CheckboxCell(new JCheckBox()),
new CheckboxCell(new JCheckBox()), new SpinnerCell(new JSpinner()) });
model.addRow(new Object[] { "Cat", new CheckboxCell(new JCheckBox()), new CheckboxCell(new JCheckBox()),
new SpinnerCell(new JSpinner()) });
model.addRow(new Object[] { "Dog", new CheckboxCell(new JCheckBox()), new CheckboxCell(new JCheckBox()),
new SpinnerCell(new JSpinner()) });
model.addRow(new Object[] { "Fish", new CheckboxCell(new JCheckBox()),
new CheckboxCell(new JCheckBox()), new SpinnerCell(new JSpinner()) });
model.addRow(new Object[] { "Pig", new CheckboxCell(new JCheckBox()), new CheckboxCell(new JCheckBox()),
new SpinnerCell(new JSpinner()) });
frame.add(new JScrollPane(table));
frame.setSize(300, 200);
frame.setVisible(true);
}
});
}
static class CheckboxCell extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
private static final long serialVersionUID = 1L;
private JCheckBox checkBox;
public CheckboxCell(JCheckBox inputCheckBox) {
checkBox = inputCheckBox;
}
@Override
public Object getCellEditorValue() {
return checkBox.isSelected();
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row,
int column) {
return checkBox;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
return checkBox;
}
public JCheckBox getCheckBox() {
return checkBox;
}
@Override
public boolean isCellEditable(EventObject evt) {
return true;
}
public String toString() {
return checkBox.isSelected() + "";
}
}
static class SpinnerCell extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
private static final long serialVersionUID = 1L;
private JSpinner editSpinner, renderSpinner;
public SpinnerCell() {
editSpinner = new JSpinner();
JTextField tf = ((JSpinner.DefaultEditor) editSpinner.getEditor()).getTextField();
tf.setForeground(Color.black);
renderSpinner = new JSpinner();
JTextField tf2 = ((JSpinner.DefaultEditor) renderSpinner.getEditor()).getTextField();
tf2.setForeground(Color.black);
}
public SpinnerCell(JSpinner showSpinner) {
editSpinner = showSpinner;
JTextField tf = ((JSpinner.DefaultEditor) editSpinner.getEditor()).getTextField();
tf.setForeground(Color.black);
renderSpinner = showSpinner;
JTextField tf2 = ((JSpinner.DefaultEditor) renderSpinner.getEditor()).getTextField();
tf2.setForeground(Color.black);
}
@Override
public Object getCellEditorValue() {
return editSpinner.getValue();
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row,
int column) {
return editSpinner;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
return renderSpinner;
}
public String toString() {
return editSpinner.getValue().toString();
}
public JSpinner getSpinner() {
return editSpinner;
}
@Override
public boolean isCellEditable(EventObject evt) {
return true;
}
}
}
答案 0 :(得分:3)
如果你想要阻止闪光灯,你需要在选择之前拦截一个事件,因为table.getSelectedColumn()
仅在选择完成后才有效,你总会看到该选择闪烁。
您可以使用键侦听器检查“右箭头”,“数字键盘右”和“结束”键按下以及鼠标单击的侦听器以检查用户单击的位置,然后将事件更改为选择列A仅
例如,请参阅此答案,了解如何在选择之前检查用户点击鼠标的位置:https://stackoverflow.com/a/7351053/1270000
然后,您只需添加一些代码来选择A列中的正确单元格,并且不要忘记使用事件“e.consume()
”以防止原始事件因错误的用户选择而完成。
答案 1 :(得分:3)
没有尝试过,但您可以使用自定义ListSelectionModel。
以下示例允许您打开/关闭行的选择:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ToggleListSelectionModel extends DefaultListSelectionModel
{
@Override
public void setSelectionInterval(int index0, int index1)
{
// Select multiple lines
if (index0 != index1)
{
super.addSelectionInterval(index0, index1);
return;
}
// Toggle selection of a single line
if (super.isSelectedIndex(index0))
{
super.removeSelectionInterval(index0, index0);
}
else
{
super.addSelectionInterval(index0, index0);
}
}
private static void createAndShowGUI()
{
String[] numbers = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };
final JList<String> list = new JList<String>( numbers );
list.setVisibleRowCount( numbers.length );
list.setSelectionModel(new ToggleListSelectionModel());
// list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
JButton clear = new JButton("Clear");
clear.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
list.clearSelection();
}
});
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(list), BorderLayout.CENTER);
frame.add(clear, BorderLayout.PAGE_END);
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
在您的情况下,我猜您需要访问该表,以便您可以使用getSelectedColumn()
方法。
您将从上面的示例中删除逻辑并将其替换为:
if (table.getSelectedColumn() == 0)
super.setSelectionInterval(index0, index1);
答案 2 :(得分:3)
这是我的简短例子:
<?php
define ("DB_ACCESS", "mysqli");
define ("DB_HOST", "***.**.*.**");
define ("DB_NAME", "test1");
define ("DB_USER", "****");
define ("DB_PASSWORD", "****");
define ("DB_PORT", "3307");
global $dbdtk_dbaccess, $dbdtk_dbhost, $dbdtk_dbuser, $dbdtk_dbpasswd,
$dbdtk_dbname, $dbdtk_dbport;
$dbdtk_dbaccess = DB_ACCESS;
$dbdtk_dbhost = DB_HOST;
$dbdtk_dbuser = DB_USER;
$dbdtk_dbpasswd = DB_PASSWORD;
$dbdtk_dbname = DB_NAME;
$dbdtk_dbport = DB_PORT;
$db = &ADONewConnection($dbdtk_dbaccess);
$db->debug = 0;
$db->Connect($dbdtk_dbhost, $dbdtk_dbuser, $dbdtk_dbpasswd,
$dbdtk_dbname, dbdtk_dbport);
$ADODB_FETCH_MODE = ADODB_FETCH_BOTH;
?>
JTable#changeSelection(...)
table.setCellSelectionEnabled(true);
ListSelectionModel#isSelectedIndex(...)