2012-05-21 42 views
0

我創建了下面的示例源代碼,並且想知道我需要做什麼來更新我的JPanel,並使用JLabel來更新我的JPanel,該JLabel具有位於JTable中單擊的行中的信息。如何使用不同類的信息更新JPanel?

我還想指出,這僅僅是一個簡單的例子,因爲我已經通過一些SO成員在這裏改進了示例代碼。所以我張貼這種裸例子,以此來學習

SwingTesting(主)

public class SwingTesting { 

    private final JFrame frame; 
    private final TablePane tablePane; 
    private final JSplitPane splitPane; 
    private final JPanel infoPanel; 
    private final JLabel infoLabel; 

    public SwingTesting() { 
     tablePane = new TablePane(); 
     infoPanel = new JPanel(); 
     frame = new JFrame(); 

     infoLabel = new JLabel(); //this is the panel i want to add the label to 
     infoPanel.add(infoLabel); 

     splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, tablePane, infoPanel); 

     frame.add(splitPane); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       new SwingTesting(); 
      } 
     }); 
    } 
} 

TablePane

public class TablePane extends JPanel { 

    private final JTable table; 
    private final TableModel tableModel; 
    private final ListSelectionModel listSelectionModel; 

    public TablePane() { 
     table = new JTable(); 
     tableModel = createTableModel(); 
     table.setModel(tableModel); 
     table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); 
     table.add(table.getTableHeader(), BorderLayout.PAGE_START); 
     table.setFillsViewportHeight(true); 

     listSelectionModel = table.getSelectionModel(); 
     table.setSelectionModel(listSelectionModel); 
     listSelectionModel.addListSelectionListener(new SharedListSelectionHandler()); 
     table.setSelectionModel(listSelectionModel); 

     this.setLayout(new GridBagLayout()); 

     GridBagConstraints gbc = new GridBagConstraints(); 
     gbc.anchor = GridBagConstraints.NORTHWEST; 
     gbc.fill = GridBagConstraints.BOTH; 
     gbc.gridx = 0; 
     gbc.gridy = 0; 
     gbc.gridheight = 1; 
     gbc.gridwidth = 3; 
     gbc.insets = new Insets(5, 5, 5, 5); 
     gbc.ipadx = 2; 
     gbc.ipady = 2; 
     gbc.weightx = 1; 
     gbc.weighty = 1; 

     this.add(new JScrollPane(table), gbc); 
    } 

    private TableModel createTableModel() { 
     DefaultTableModel model = new DefaultTableModel(
      new Object[] {"Car", "Color", "Year"}, 0 
     ){ 
      @Override public boolean isCellEditable(int row, int column) { 
       return false; 
      } 
     }; 

     addTableData(model); 
     return model; 
    } 

    private void addTableData(DefaultTableModel model) { 
     model.addRow(new Object[] {"Nissan", "Black", "2007"}); 
     model.addRow(new Object[] {"Toyota", "Blue", "2012"}); 
     model.addRow(new Object[] {"Chevrolet", "Red", "2009"}); 
     model.addRow(new Object[] {"Scion", "Silver", "2005"}); 
     model.addRow(new Object[] {"Cadilac", "Grey", "2001"}); 
    } 


    class SharedListSelectionHandler implements ListSelectionListener { 

     //When selection changes i want to add a label to the panel 
     //currently it just prints out the info from the selected row  
     @Override 
     public void valueChanged(ListSelectionEvent e) { 
      ListSelectionModel lsm = (ListSelectionModel) e.getSource(); 
      String contents = ""; 

      if(lsm.isSelectionEmpty()) { 
       System.out.println("<none>"); 
      } else { 
       int minIndex = lsm.getMinSelectionIndex(); 
       int maxIndex = lsm.getMaxSelectionIndex(); 
       for(int i = minIndex; i <= maxIndex; i++) { 
        if(lsm.isSelectedIndex(i)) { 
         for(int j = 0; j < table.getColumnCount(); j++) { 
          contents += table.getValueAt(i, j) + " "; 
         } 
        } 
       } 
       System.out.println(contents); 
      } 
     }   
    } 
} 

所以我不知道如何從ListSelectionListener訪問的JPanel。我應該將面板傳遞給TablePane類嗎?還是有更合適的方法來做到這一點?

另外,由於某種原因,我的ListSelectionListener打印出兩行信息,我搞砸了循環嗎?

編輯

public class TablePane extends JPanel { 

    private final JTable table; 
    private final TableModel tableModel; 
    private final ListSelectionModel listSelectionModel; 

    private final displayPanel; 

    public TablePane() { 
     //removed code for reading purposes 
    } 

    //IDE says issue with thinking displayPanel may have already been initialized 
    public TablePane(JPanel panel) { 
     //this(); 
     //displayPanel = panel; 
    } 


    //ListSelectionListener uses panel.add(jlabel) 

} 

它是那樣簡單採取final了嗎?

+0

這個問題太廣泛了。請細化並提出更具體的問題。 – mre

+1

在您的TablePane類(構造函數將有一個參數)中SwingTesting上創建對此JPanel的引用,並在SwingTesting中爲您的JPanel創建getter。 – Sajmon

+0

@Sajmon謝謝你的回覆,我以爲這是我必須這樣做的方式。希望也有其他的方法。 – WilliamShatner

回答

1

可以傳遞JLabel對象到TablePane對象(在TablePane的構造,或者通過提供一個定製setLabel()方法)。然後,您可以使用StringBuilder創建需要放在標籤上的文本,並在StringBuilder對象的標籤上(通過其toString()方法)在標籤上調用setText()

我相信你打印everytihn兩次,因爲valueChanged方法被調用兩次:一旦關於取消選擇當前行的通知,然後再通知選擇新行。

+0

感謝您確認我必須通過構造函數傳遞組件。出於純粹的好奇心,是否有另一種方式來做到這一點?任何類型的事件或任何事情?另外,感謝你用'valueChanged'解釋這個問題 – WilliamShatner

+0

你不需要通過構造函數來傳遞它(你也可以通過任何其他的普通函數調用來實現),但是你需要先引用標籤更新它。有很多方法可以在對象之間傳遞數據;在這種情況下,將標籤對象傳遞到處理更改事件的位置是最簡單的解決方案。 – Attila

+0

我已經添加了一個修改,你會介意告訴我我需要做些什麼來修復最後一個問題嗎? (我知道我已經給你正確的答案,但沒想到我會對構造函數有問題)。我沒有想到在別處使用過的構造函數。 – WilliamShatner