Reputation: 328727
I have:
JTable
, embedded in a JScrollPane
, containing a list of itemsJPanel
, embedded in a JDialog
, that displays information related to the selected itemThe code works as expected (information gets updated), except that the JTable
loses focus and the JDialog
gets the focus every time the selection is changed. So I have added a table.requestFocusInWindow
but the JTable
still loses the focus, although the call returns true.
How can I make sure that the JDialog
gets updated but that the JTable
does not lose the focus?
ps: My end goal is to be able to browse the table with the arrows (up / down) and see the information update in the JDialog - at the moment, I need to click on the rows to do that.
EDIT
See below a SSCCE that replicates my issue (the content of the JDialog changes when selection is changed but the focus is lost).
public class TestTable extends JTable {
public static JFrame f = new JFrame();
public static JTextField text = new JTextField();
public static JDialog dialog;
public static void main(String[] args) {
f.setSize(300, 300);
f.setLocation(300, 300);
f.setResizable(false);
showPopup();
final JScrollPane jScrollPane = new JScrollPane();
jScrollPane.getViewport().add(new TestTable());
f.add(jScrollPane);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public TestTable() {
super();
setModel(new TestTableModel());
getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
ListSelectionModel lsm = (ListSelectionModel) e.getSource();
int row = lsm.getAnchorSelectionIndex();
Object item = getModel().getValueAt(row, 0);
text.setText(item.toString());
dialog.setVisible(true);
TestTable.this.requestFocusInWindow(); //DOES NOT DO ANYTHING
}
});
setCellSelectionEnabled(false);
}
public class TestTableModel extends DefaultTableModel {
public TestTableModel() {
super(new String[]{"DATA"}, 3);
setValueAt(Double.valueOf(-0.1), 0, 0);
setValueAt(Double.valueOf(+0.1), 1, 0);
setValueAt(Double.valueOf(0), 2, 0);
}
}
private static void showPopup() {
dialog = new JDialog(f, "Title");
dialog.setContentPane(text);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
}
}
Upvotes: 0
Views: 1385
Reputation: 47608
There must be something in your dialog that grabs the focus on the fly, because I have tried with a JLabel and it does not cause any problem. If you need to work around this, you can always call toFront()
on your JTable parent Frame. If it does not help your case, try to edit this SSCCE to reproduce your issue.
See this code (comment the grabFocus on the label to convince yourself that there is something in your dialog that grabs the focus):
import java.awt.Component;
import java.util.Vector;
import javax.swing.FocusManager;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
public class Test {
public static class MyTableModel extends DefaultTableModel {
private int count;
public MyTableModel() {
addColumn("Test");
}
public void insertNewRow() {
Vector<String> rowData = createNewRowData();
insertRow(0, rowData);
}
private Vector<String> createNewRowData() {
Vector<String> data = new Vector<String>(1);
data.add("Hello-" + count++);
return data;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Test().initUI();
}
});
}
public void initUI() {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final MyTableModel model = new MyTableModel();
final JTable table = new JTable(model);
for (int i = 0; i < 100; i++) {
model.insertNewRow();
}
final JLabel label = new JLabel();
JDialog dialog = new JDialog(frame, false);
dialog.add(label);
dialog.setSize(300, 50);
dialog.setLocation(400, 0);
dialog.setVisible(true);
table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
final Component focused = FocusManager.getCurrentManager().getFocusOwner();
int index = table.getSelectionModel().getLeadSelectionIndex();
if (index > -1) {
Object valueAt = model.getValueAt(index, 0);
label.setText("Current row selected is: " + valueAt);
} else {
label.setText("No selection");
}
label.grabFocus();
if (focused != null) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
frame.toFront();
}
});
}
}
});
final JScrollPane scroll = new JScrollPane(table);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
frame.add(scroll);
frame.pack();
frame.setVisible(true);
}
}
Upvotes: 1