在细胞选择jtable事件之前 [英] before cell select jtable event
问题描述
在即将选择单元格时是否会触发任何事件?有ListSelectionListener,但它只有在选择发生后触发的事件。我需要某种方法来取消选择事件并使用ListSelectionListener它并不容易,因为选择已经发生,我需要一些状态变量来指示选择是正常还是取消之前的选择。
Are there any event that is fired when cell is about to be selected? There is ListSelectionListener, but it has event that is fired only after selection has happened. I need some way to cancel selection event and using ListSelectionListener it is not easy as selection has already happened and I need to have some state variable that indicates if selection is normal or is cancel of a previous selection.
有没有办法关闭选择通知?然而,这不是100%好的解决方案(如果一些监听器在其本地存储中保存选择状态会有问题)这总比没有好。
Are there a way to switch off selection notifications? However this is not 100% good solution (there will be problems if some listeners saves selection state in its local storage) this is better than nothing.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.ListSelectionModel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.JTable;
public class JTableExample extends JFrame {
/**
*
*/
private static final long serialVersionUID = 6040280633406589974L;
private JPanel contentPane;
private JTable table;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
JTableExample frame = new JTableExample();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public JTableExample() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
table = new JTable(new MyTableModel());
ListSelectionModel selectionModel = table.getSelectionModel();
selectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
selectionModel.addListSelectionListener(new MySelectionListener());
contentPane.add(table, BorderLayout.CENTER);
}
class MyTableModel extends AbstractTableModel {
/**
*
*/
private static final long serialVersionUID = -8312320171325776638L;
public int getRowCount() {
return 10;
}
public int getColumnCount() {
return 10;
}
public Object getValueAt(int rowIndex, int columnIndex) {
return rowIndex * columnIndex;
}
}
class MySelectionListener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent e) {
int selectedRow = table.getSelectedRow();
if (selectedRow == 5) {
System.out.println("I would like this selection never happened.");
}
}
}
}
推荐答案
无论你想达到什么目标:认为mouseEvent还不够,选择可能因其他原因而改变(键盘输入,编程触发器......)。恢复监听器中未经改变的更改不是一种选择:正如您已经指出的那样,需要保留选择的副本并且可能会混淆其他监听器。
whatever the goal is that you want to achieve: thinking "mouseEvent" is not enough, selection might change for other reasons (f.i. keyboard input, programmatic trigger, ..). Reverting an unwated change in a listener is not an option: as you already noted that would require to keep a duplicate of the selection and might confuse other listeners.
唯一的方法(我认为,当然可能是其他人;-)首先是不要让它发生:实现List SelectionModel,如果满足某些条件,它不会改变选择。我最喜欢的(有偏见的:-)是 VetoableListSelectionModel 它是DefaultListSelectionModel的子类,在SingleSelectionMode中,在实际更改之前等待来自感兴趣方的否决。
The only way (that I see, could be others, of course ;-) is not to let it happen in the first place: implement a List SelectionModel which doesn't change the selection if certain conditions are met. My favourite (biased me :-) is a VetoableListSelectionModel It's a subclass of DefaultListSelectionModel which in SingleSelectionMode waits for vetoes from interested parties before actually changing.
这是一个使用它的(原始)代码片段:
Here's a (raw) code snippet using it:
VetoableListSelectionModel vetoableSelection = new VetoableListSelectionModel();
VetoableChangeListener navigationController = new VetoableChangeListener() {
public void vetoableChange(PropertyChangeEvent evt)
throws PropertyVetoException {
// custom method that implements your condition
if (!canSelect((int) evt.getOldValue(), (int) evt.getNewValue()))
throw new PropertyVetoException("uncommitted changes",
evt);
}
};
vetoableSelection.addVetoableChangeListener(navigationController);
myTable.setSelectionModel(vetoableSelection);
这篇关于在细胞选择jtable事件之前的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!