2012-05-10 35 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