如何解决更改JTable的选择行为以仅选择行或列中可变数量的单元格
我有一个JTable,可以在其中启用行或列选择之间进行更改。此功能效果很好,但我希望能够确定在当前所选单元格旁边突出显示的单元格数量。当前,选择整个行或整个列。我试图添加一个ListSelectionModel来实现此功能,但它只允许选择整个行或整个列。以下是示例图片:
和
ADJACENTSELECTION默认情况下设置为2,因此我想在启用rowSelection时突出显示所选单元格左右两侧的2个单元格,或者当rowSelection为false时突出显示所选单元格上下的2个单元格。任何帮助将不胜感激。这是我的代码:
package selectionTest;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.border.Border;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
public class App {
private void display() {
JFrame f = new JFrame("Demo");
JPanel gui = new JPanel(new BorderLayout());
GridTable gridTable = new GridTable(25,25);
gui.add(gridTable,BorderLayout.CENTER);
f.add(gui);
f.setBackground(Color.BLUE);
gui.setBackground(Color.WHITE);
f.setLocationByPlatform(true);
f.pack();
f.setSize(500,600);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new App().display();
}
});
}
}
class GridTable extends JTable {
static int ADJACENTSELECTION = 2;
boolean rowSelection = false;
int rows,cols;
public GridTable(int rows,int cols) {
this.rows = rows;
this.cols = cols;
this.setModel(new DefaultTableModel(rows,cols));
this.setShowGrid(true);
Border blackline = BorderFactory.createLineBorder(Color.black);
this.setBorder(blackline);
this.setGridColor(Color.black);
ActionMap map = this.getActionMap();
Action action = switchOrientation();
String keyStrokeAndKey = "control O";
KeyStroke keyStroke = KeyStroke.getKeyStroke(keyStrokeAndKey);
this.getInputMap().put(keyStroke,keyStrokeAndKey);
this.getActionMap().put(keyStrokeAndKey,action);
this.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent event) {
int row = getSelectedRow();
int column = getSelectedColumn();
if (rowSelection) {
setRowSelectionInterval(Math.max(0,row - ADJACENTSELECTION),Math.min(row,row + ADJACENTSELECTION));
} else {
setColumnSelectionInterval(Math.max(0,column - ADJACENTSELECTION),Math.min(column,column + ADJACENTSELECTION));
}
}
});
}
private AbstractAction switchOrientation() {
AbstractAction switchOrientation = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
rowSelection = !rowSelection;
setColumnSelectionAllowed(rowSelection);
setRowSelectionAllowed(!rowSelection);
}
};
return switchOrientation;
}
}
解决方法
您快到了,只需执行几个额外的步骤,就可以更新选择侦听器以仅突出显示特定的单元格:
-
通过向
this.setCellSelectionEnabled(true);
方法中添加GridTable
来选择特定的单元格:public GridTable(int rows,int cols) { this.setCellSelectionEnabled(true); //...
-
确保
SelectionInterval
范围/值正确:if (rowSelection == true){ //Correct using `getRowCount()` for selection range setRowSelectionInterval(Math.max(0,row - ADJACENTSELECTION),Math.min(getRowCount()-1,row + ADJACENTSELECTION)); } else{ //Correct using `getColumnCount()` for selection range setColumnSelectionInterval(Math.max(0,column - ADJACENTSELECTION),Math.min(getColumnCount()-1,column + ADJACENTSELECTION)); }
-
确保在更新选择时不会触发选择事件再次发生。您可以通过使用布尔值来跟踪选择事件来做到这一点:
this.getSelectionModel().addListSelectionListener(new ListSelectionListener(){ //Use this to track changes boolean initial = true; //... public void valueChanged(ListSelectionEvent e){ if (initial){ int column = getSelectedColumn(); int row = getSelectedRow(); //...
-
最后,将它们放在一起,这是完整的选择侦听器(并且不要忘记将
this.setCellSelectionEnabled(true);
添加到GridTable中):this.getSelectionModel().addListSelectionListener(new ListSelectionListener(){ //Use this to track changes boolean initial = true; public void valueChanged(ListSelectionEvent e){ //Only change value on first select (This prevents the below from triggering itself) if (initial){ int column = getSelectedColumn(); int row = getSelectedRow(); initial = false; if (rowSelection == true){ setRowSelectionInterval(Math.max(0,row + ADJACENTSELECTION)); } else{ setColumnSelectionInterval(Math.max(0,column + ADJACENTSELECTION)); } } //Set the value back once a selection is complete else{ initial = true; } } });
这将突出显示选定的单元格,并在选择的两侧显示两个单元格
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。