2012-05-10 36 views
0

时,我有:聚焦丢失更新的JDialog

  • 一个JTable,嵌入JScrollPane,包含项目的列表
  • 一个JPanel,嵌入JDialog,即显示与选择的项目信息

的代码按预期工作(信息得到更新),除了JTable失去焦点和JDialog每次选择改变时获得焦点。所以我添加了一个table.requestFocusInWindow,但JTable仍然失去焦点,尽管该调用返回true。

我怎样才能确保JDialog得到更新,但JTable没有失去焦点?

ps:我的最终目标是能够使用箭头(上/下)浏览表格并查看JDialog中的信息更新 - 此刻,我需要点击行才能做到这一点。

编辑
请参阅复制我的问题(当选择改变的JDialog的内容发生改变,但焦点丢失)一SSCCE以下。

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); 
    } 
} 

回答

1

您的对话框中必须有一些东西抓住飞行中的焦点,因为我尝试过使用JLabel并且不会导致任何问题。如果您需要解决此问题,则始终可以在您的JTable父框架上调用toFront()。如果它不能帮助您的情况,请尝试编辑此SSCCE以重现您的问题。

看到这个代码(注释标签上的grabFocus说服自己,也有一些是在对话框中,抓住重点):

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); 

    } 
} 
+0

感谢您的答案 - 如果你有一秒钟,我已经发布上面的SSCCE复制了这个问题。 – assylias

+0

@assylias是的,我看到了。我只是复制它,似乎调用'f.toFront()'伎俩 –

+0

其实主要的区别是,我调用'dialog.setVisible()'。如果我删除那条线,我会得到预期的行为。 – assylias