Использовать FocusListener
прикрепленные к JTable
, это скажет вам, когда фокус перемещается от стола.
См How to Write a Focus Listener для более подробной информации
Например ...
table.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
loseCellFocus();
}
});
Это, конечно, работать только когда фокус клавиатуры передается новый компонент, способный для приема фокус клавиатуры
Это вызывает вызов метода loseCellFocus() сразу, как только я нажимаю на любую ячейку, это называется
Вы можете использовать JTable#setSurrendersFocusOnKeystroke
или проверить, если компонент, который фокус был передан ребенок в JTable
К примеру ...
table.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
if (e.getOppositeComponent().getParent() != table) {
loseCellFocus();
}
}
});
Runnable Пример ...
Хорошо, это стало беспорядочным. Мало того, что я должен добавить FocusListener
к JTable
, но я должен был убедиться, что один был добавлен к TableCellEditor
компонента: P
Это доказательство концепции только, я бы специализированные классы, которые способны либо для пропагандистские мероприятия или запуская необходимый функциональные возможности с помощью какого-то общего интерфейса
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import javax.swing.DefaultCellEditor;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JViewport;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
JTable table = new JTable(new DefaultTableModel(10, 10));
JTextField editorField = new JTextField(10);
editorField.setBorder(new EmptyBorder(1, 1, 1, 1));
editorField.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
TableCellEditor cellEditor = table.getCellEditor();
if (cellEditor != null) {
if (!cellEditor.stopCellEditing()) {
cellEditor.cancelCellEditing();
}
}
Component gotFocus = e.getOppositeComponent();
if (!gotFocus.equals(table)) {
table.clearSelection();
}
}
});
DefaultCellEditor editor = new DefaultCellEditor(editorField);
table.setDefaultEditor(Object.class, editor);
add(new JScrollPane(table));
table.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
Component gotFocus = e.getOppositeComponent();
if (!gotFocus.getParent().equals(table)) {
TableCellEditor cellEditor = table.getCellEditor();
if (cellEditor != null) {
if (!cellEditor.stopCellEditing()) {
cellEditor.cancelCellEditing();
}
}
table.clearSelection();
}
}
});
JTextField field = new JTextField(10);
add(field, BorderLayout.SOUTH);
}
}
}
AWTEventListener Пример ...
Ладно, на самом деле не хочет идти по этому пути, как она заканчивается в беспорядке перекрестных условий, но , В основном это контролирует ВСЕ MouseEvent
и FocusEvent
s, он делает некоторые обратные результаты для проверки действительных условий (так как мы должны убедиться, что не только если JTable
является частью события, но и если редактор является частью события), а на основе по этим результатам останавливает редактирование ячеек и очищает выбор ...
import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.KeyboardFocusManager;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.FocusEvent;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JTable table = new JTable(new DefaultTableModel(5, 5));
setLayout(new GridBagLayout());
setBorder(new EmptyBorder(20, 20, 20, 20));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JScrollPane(table), gbc);
add(new JTextField(10), gbc);
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
@Override
public void eventDispatched(AWTEvent event) {
if (event instanceof FocusEvent) {
FocusEvent focusEvent = (FocusEvent) event;
if (focusEvent.getID() == FocusEvent.FOCUS_LOST) {
Component focusTo = focusEvent.getOppositeComponent();
Component focusFrom = focusEvent.getComponent();
JTable table = getTableFrom(focusFrom);
if (focusTo == null || !focusTo.getParent().equals(table)) {
stopCellEditing(table);
clearSelection(table);
}
}
} else if (event instanceof MouseEvent) {
MouseEvent mouseEvent = (MouseEvent) event;
if (mouseEvent.getID() == MouseEvent.MOUSE_CLICKED) {
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
JTable table = getTableFrom(focusOwner);
System.out.println(" table = " + table);
System.out.println("focusOwner = " + focusOwner);
// if ((table != null && mouseEvent.getComponent() != table) || (focusOwner != null && !focusOwner.getParent().equals(table))) {
if ((table != null && mouseEvent.getComponent() != table) && (focusOwner != null && !focusOwner.getParent().equals(table))) {
stopCellEditing(table);
clearSelection(table);
}
}
}
}
protected JTable getTableFrom(Component component) {
JTable table = null;
if (component instanceof JTable) {
table = (JTable) component;
} else if (component != null && component.getParent() instanceof JTable) {
table = (JTable) component.getParent();
}
return table;
}
protected void clearSelection(JTable table) {
if (table != null) {
table.clearSelection();
}
}
protected void stopCellEditing(JTable table) {
if (table != null) {
TableCellEditor cellEditor = table.getCellEditor();
if (cellEditor != null) {
if (!cellEditor.stopCellEditing()) {
cellEditor.cancelCellEditing();
}
}
}
}
}, AWTEvent.FOCUS_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK);
}
}
}
Этот пример в основном работает для ВСЕХ JTable
с (когда AWTEventListener
зарегистрирован), но вы можете настроить его, чтобы контролировать одну таблицу, изменяя некоторые из источников событий и сравнивая их друг с другом: P
Используйте 'FocusListener', прикрепленный к' JTable' – MadProgrammer