Java 更新JDialog时焦点丢失
我有:Java 更新JDialog时焦点丢失,java,swing,focus,Java,Swing,Focus,我有: 嵌入在JScrollPane中的JTable,包含项目列表 嵌入在JDialog中的JPanel,显示与所选项目相关的信息 代码按预期工作(信息得到更新),除了JTable失去焦点,并且JDialog在每次更改选择时都获得焦点。因此,我添加了一个表.requestFocusInWindow,但是JTable仍然失去焦点,尽管调用返回true 如何确保JDialog得到更新,但JTable不会失去焦点 ps:我的最终目标是能够用箭头(向上/向下)浏览表格,并在JDialog中查看信息更
- 嵌入在
中的JScrollPane
,包含项目列表JTable
- 嵌入在
中的JDialog
,显示与所选项目相关的信息JPanel
JTable
失去焦点,并且JDialog
在每次更改选择时都获得焦点。因此,我添加了一个表.requestFocusInWindow
,但是JTable
仍然失去焦点,尽管调用返回true
如何确保JDialog
得到更新,但JTable
不会失去焦点
ps:我的最终目标是能够用箭头(向上/向下)浏览表格,并在JDialog中查看信息更新——目前,我需要单击行来完成这项工作
编辑下面是一个复制我的问题的SSCCE(当选择更改时,JDialog的内容会更改,但焦点丢失)
在您的对话框中一定有什么东西能够抓住焦点,因为我已经尝试使用JLabel,它不会引起任何问题。如果需要解决此问题,可以始终在JTable父帧上调用
toFront()
。如果对您的情况没有帮助,请尝试编辑此内容以重现您的问题
请参阅以下代码(在标签上注释grabFocus,以使自己确信对话框中有东西可以抓住焦点):
导入java.awt.Component;
导入java.util.Vector;
导入javax.swing.FocusManager;
导入javax.swing.JDialog;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.ListSelectionModel;
导入javax.swing.SwingUtilities;
导入javax.swing.event.ListSelectionEvent;
导入javax.swing.event.ListSelectionListener;
导入javax.swing.table.DefaultTableModel;
公开课考试{
公共静态类MyTableModel扩展了DefaultTableModel{
私人整数计数;
公共MyTableModel(){
添加列(“测试”);
}
public void insertNewRow(){
Vector rowData=createNewRowData();
insertRow(0,rowData);
}
私有向量createNewRowData(){
矢量数据=新矢量(1);
data.add(“Hello-”+count++);
返回数据;
}
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
新测试().initUI();
}
});
}
public void initUI(){
最终JFrame=新JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
最终MyTableModel模型=新的MyTableModel();
最终JTable表格=新JTable(模型);
对于(int i=0;i<100;i++){
model.insertNewRow();
}
最终JLabel标签=新的JLabel();
JDialog dialog=newjdialog(frame,false);
对话框。添加(标签);
对话框。设置大小(300,50);
对话框。设置位置(400,0);
对话框.setVisible(true);
table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.getSelectionModel().addListSelectionListener(新ListSelectionListener()){
@凌驾
public void值已更改(ListSelectionEvent e){
最终聚焦组件=FocusManager.getCurrentManager().getFocusOwner();
int index=table.getSelectionModel().getLeadSelectionIndex();
如果(索引>-1){
Object valueAt=model.getValueAt(索引,0);
label.setText(“当前选定行为:”+valueAt);
}否则{
label.setText(“无选择”);
}
label.grabFocus();
如果(聚焦!=null){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
frame.toFront();
}
});
}
}
});
最终JScrollPane滚动=新JScrollPane(表);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL\u SCROLLBAR\u根据需要);
frame.add(滚动);
frame.pack();
frame.setVisible(true);
}
}
谢谢你的回答-如果你有时间,我已经在上面发布了一个SSCCE,它复制了这个问题。@assylias是的,我看到了。我刚刚复制了它,调用f.toFront()
似乎有点麻烦。实际上,主要区别在于我调用了dialog.setVisible()
。如果删除该行,我将获得预期的行为。是-我已使用If(!dialog.isVisible())dialog.setVisible(true)更改了该行代码>现在它可以正常工作了。谢谢你的代码,它帮助我发现了问题!
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);
}
}
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);
}
}