2013-05-22 63 views
1

我的問題是:Swing GUI:JList與行上的jtextFields

我有一個按鈕,單擊它時會向JList添加組件。列表的每一行由兩個jtextField組成。第一個是行的ID。每次按「添加按鈕」時,都會出現一個新行,ID會增加,並且使用該應用程序的人將在第二個jTextField(轉發ID字段)上寫任何他想要的內容。

然後它將有一個滾動窗格,當有超過4行。 我也想要一個刪除按鈕。可以刪除一些行。

你能幫我嗎?我不知道如何創建這樣的列表...

謝謝!

+0

你不能做到這一點。 'JList'不是一個容器,它是一個組件,所以它不能容納組件。爲什麼你(認爲你)需要一個JList?爲什麼不用'JPanel'來做這件事? – drewmoore

+0

我真的不知道如何開始。好的,這是邏輯。但是我必須創建一個列表嗎?每次按下按鈕時添加字段。還有一個刪除按鈕,可以刪除一些行。 – user2144555

+1

更好地使用兩列的JTable,第一個不可編輯 – MadProgrammer

回答

4

只需使用JTable兩列。這將允許您建立兩列,一列用於ID,一列用於價值。這將使您可以編輯第二列。

enter image description here

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.table.AbstractTableModel; 

public class TestTable04 { 

    public static void main(String[] args) { 
     new TestTable04(); 
    } 

    private int id = 0; 

    public TestTable04() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException ex) { 
       } catch (InstantiationException ex) { 
       } catch (IllegalAccessException ex) { 
       } catch (UnsupportedLookAndFeelException ex) { 
       } 

       final RecordTableModel model = new RecordTableModel(); 
       JTable table = new JTable(model); 

       JButton add = new JButton("Add"); 
       add.addActionListener(new ActionListener() { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         model.add(new Record(++id)); 
        } 
       }); 

       JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(add, BorderLayout.SOUTH); 
       frame.add(new JScrollPane(table)); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 

     }); 
    } 

    public class Record { 

     private int id; 
     private String value; 

     public Record(int id) { 
      this.id = id; 
     } 

     public int getID() { 
      return id; 
     } 

     public void setValue(String value) { 
      this.value = value; 
     } 

     public String getValue() { 
      return value; 
     } 

    } 

    public class RecordTableModel extends AbstractTableModel { 

     private List<Record> lstRecords; 

     public RecordTableModel() { 
      lstRecords = new ArrayList<>(24); 
     } 

     public void add(Record record) { 
      lstRecords.add(record); 
      fireTableRowsInserted(lstRecords.size() - 1, lstRecords.size() - 1); 
     } 

     public void remove(Record record) { 
      if (lstRecords.contains(record)) { 
       int index = lstRecords.indexOf(record); 
       remove(index); 
      } 
     } 

     public void remove(int index) { 
      lstRecords.remove(index); 
      fireTableRowsDeleted(index, index); 
     } 

     @Override 
     public int getRowCount() { 
      return lstRecords.size(); 
     } 

     @Override 
     public int getColumnCount() { 
      return 2; 
     } 

     @Override 
     public Class<?> getColumnClass(int columnIndex) { 
      Class clazz = String.class; 
      switch (columnIndex) { 
       case 0: 
        clazz = Integer.class; 
        break; 
      } 
      return clazz; 
     } 

     @Override 
     public String getColumnName(int column) { 
      String name = null; 
      switch (column) { 
       case 0: 
        name = "ID"; 
        break; 
       case 1: 
        name = "Value"; 
        break; 
      } 
      return name; 
     } 

     @Override 
     public Object getValueAt(int rowIndex, int columnIndex) { 
      Record record = lstRecords.get(rowIndex); 
      Object value = null; 
      switch (columnIndex) { 
       case 0: 
        value = record.getID(); 
        break; 
       case 1: 
        value = record.getValue(); 
        break; 
      } 
      return value; 
     } 

     @Override 
     public boolean isCellEditable(int rowIndex, int columnIndex) { 
      return columnIndex == 1; 
     } 

     @Override 
     public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 
      Record record = lstRecords.get(rowIndex); 
      switch (columnIndex) { 
       case 1: 
        record.setValue(aValue == null ? null : aValue.toString()); 
        fireTableCellUpdated(rowIndex, columnIndex); 
        break; 
      } 
     } 
    } 
} 

退房How to use tables更多細節

+0

哇,非常好!謝謝! – user2144555

+0

你能告訴我如何在表格單元格中添加圖標嗎?在第三欄。 – user2144555

+0

當然,首先檢查[如何使用渲染器](http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#renderer) – MadProgrammer

0

您可以嘗試創建自定義ListCellRenderer並使用JList的setRenderer方法來分配它。重寫ListCellRenderer的getListCellRenderer()方法以返回包含兩個組件的JPanel,用於id的JLabel和用於用戶輸入的JTextfield。您可能需要在其他地方保留對JTextField的引用,以便可以檢索用戶輸入。

要實現添加和刪除方法,我建議使用ListModel支持JList。添加並移除到ListModel也將更新JList UI。

+2

用戶如何編輯這些值? – MadProgrammer