题
有一种简单的方法来处理上一个JTable控件时,有一个键盘按下的按钮(即,CTRL键),并且选择的行,得到不同的功能?我一直要求创建一个表,其中CTRL +点击(鼠标点击)上的行只会取消选定行,从来没有选择一行。如果用户CTRL +点击次数未被选择的行,什么都不会发生。
我已经能够创建一个表,以及类似的CTRL + A禁用的功能(选择所有),并且我已经能够判断是否当产生的MouseEvent按下控制按钮,但是我不能似乎要弄清楚如何CTRL +点击可以调整。下面是一些代码:
package nicky;
import javax.swing.*;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.*;
public class TableTester extends JPanel {
public TableTester() {
super(new GridLayout(1,0));
final String[] columnNames = {"First Name",
"Last Name",
"Sport",
"# of Years",
"Vegetarian"};
final Object[][] data = {
{"Tom", "Roberts","Athletic", new Integer(5), new Boolean(false)},
{"Sarah", "Watt", "Football", new Integer(3), new Boolean(true)},
{"Laura", "Brown", "Swimming", new Integer(2), new Boolean(false)},
{"Simon", "Smith", "Tennis", new Integer(20), new Boolean(true)},
{"Paul", "Jones", "Rugby", new Integer(10), new Boolean(false)}
};
JTable table = new JTable(data, columnNames);
table.setPreferredScrollableViewportSize(new Dimension(500, 100));
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
table.addMouseListener(new MouseListener(){
public void mouseEntered(MouseEvent me){}
public void mouseExited(MouseEvent me){}
public void mouseReleased(MouseEvent me){}
public void mouseClicked(MouseEvent me){}
public void mousePressed(MouseEvent me){
if (me.isControlDown()){
System.out.println("This is working ");
}
}
});
InputMap inputMap = table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK);
inputMap.put(keyStroke, "none");
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
}
private static void createAndShowGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("TableTester");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TableTester newContentPane = new TableTester();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
在方法的mousePressed我打得四处从表中获取所有选定行,然后去检查新单击行是在selectedRows ......不过,我不知道是否有一个方法,看看哪一行与相关的MouseEvent。
(另外,我知道像这样的不应该与周围太多发挥预期的行为,但它是在复制公司的遗留系统)
任何意见/建议,将不胜感激!
解决方案
OK,第二次取(我离开第一个,因为它可能感兴趣的人一些其他用途,谁知道说出来是有教育的目的...: - ?)。)
我有一看的JTable的源代码并且发现了鼠标事件是由它的外表处理和感觉。知道如何处理控制键,我可以放心地覆盖changeSelection方法做你所需要的。结果 我找到的要求有点怪(你仍然可以使用Shift +单击,无?),但我不知道上下文。
class SpecialTable extends JTable
{
SpecialTable(Object[][] data, String[] columnNames)
{
super(data, columnNames);
// That's already the default
// setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
}
/**
* Called by javax.swing.plaf.basic.BasicTableUI.Handler.adjustSelection(MouseEvent)
* like: table.changeSelection(pressedRow, pressedCol, e.isControlDown(), e.isShiftDown());
*/
@Override
public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend)
{
if (toggle && !isRowSelected(rowIndex))
return; // Don't do the selection
super.changeSelection(rowIndex, columnIndex, toggle, extend);
}
}
更简单,你需要的东西!
BTW,感谢提供这种简单好测试用例,我可能没有,如果我不得不写自己... :-D这是一个有趣和学习的挑战尝试。
其他提示
我有以下成功,虽然我不知道这是最好的方法......
class SpecialTable extends JTable
{
boolean bIsControlDown;
int clickedRow;
SpecialTable(Object[][] data, String[] columnNames)
{
super(data, columnNames);
// setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
getSelectionModel().addListSelectionListener(this);
addMouseListener(new MouseInputAdapter()
{
public void mousePressed(MouseEvent me)
{
bIsControlDown = me.isControlDown();
clickedRow = rowAtPoint(me.getPoint());
}
});
}
public void valueChanged(ListSelectionEvent evt)
{
super.valueChanged(evt);
if (bIsControlDown)
{
if (!evt.getValueIsAdjusting())
{
// System.out.println(evt);
// System.out.println("=> " + clickedRow);
getSelectionModel().removeSelectionInterval(clickedRow, clickedRow);
}
}
}
}
替换限定table
在代码仅与行:
JTable table = new SpecialTable(data, columnNames);
table.setPreferredScrollableViewportSize(new Dimension(500, 100));
在控制单击一个未被选择的行,它简要地选择,则取消选择。
不隶属于 StackOverflow