2017-08-19 60 views
0

我試圖根據用戶的輸入製作一列包含JLabel和兩個JRadioButtons的標籤文本。這將是這個樣子:如何根據用戶輸入創建JLabel和JRadioButton?

component with JLabel and JRadioButtons

for(int i=0;i<col;i++){ 
    secondInterfaceLayout.setHorizontalGroup(
    secondInterfaceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
    .addGroup(secondInterfaceLayout.createSequentialGroup() 
     .addContainerGap() 
     .addComponent(labels[i]) 
     .addGap(180, 180, 180) 
     .addGroup(secondInterfaceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addComponent(benefitLabel, PREFERRED_SIZE, 42, PREFERRED_SIZE) 
      .addGroup(secondInterfaceLayout.createSequentialGroup() 
       .addGap(10, 10, 10) 
       .addComponent(benefitButton[i]))) 
     .addGap(68, 68, 68) 
     .addGroup(secondInterfaceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addComponent(lossButton[i]) 
      .addComponent(lossLabel)) 
     .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 
); 

    secondInterfaceLayout.setVerticalGroup(
    secondInterfaceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
    .addGroup(secondInterfaceLayout.createSequentialGroup() 
     .addGap(14, 14, 14) 
     .addGroup(secondInterfaceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addComponent(benefitLabel) 
      .addComponent(lossLabel)) 
     .addPreferredGap(UNRELATED) 
     .addGroup(secondInterfaceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) 
      .addComponent(lossButton[i], TRAILING, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 
      .addComponent(labels[i]) 
      .addComponent(benefitButton[i], TRAILING, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 
     .addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE)) 
); 
+1

似乎這將是最適合使用'JTable'到顯示標準..爲更好地提供幫助,請張貼[MCVE]或[簡短,獨立,正確的示例](http://www.sscce.org/)。 –

+0

請詳細說明問題,以便我們可以更全面地瞭解它。 –

+0

好的,所以我決定玩@ AndrewThompson的建議,看看我是否可以讓JTable顯示你之後的數據。請看下面的代碼。 –

回答

1

所以riffing什麼安德魯·湯普森說,你可以顯示和一個JTable中改變你的標準,因爲你似乎是想要創建和顯示錶格數據,數據可以隨程序運行並受用戶控制而改變。雖然這樣做會帶來一些挑戰,因爲好處與損失似乎是互補的屬性,這意味着如果一個是真的,另一個必須是假的,並且這最容易用單個布爾表示,但是接下來如何連接JTable及其模型如果一行數據包含單個布爾值,以及如何允許用戶更改這些屬性,然後在兩列中顯示更改,那麼它將顯示兩個屬性?

因此,在創建表模型之前,我首先創建了一個類MyCriterion來表示一行數據。它有兩個字段,一個名稱字符串和一個有益的布爾值。再次,如果有利的話,則JTable的「效益」欄應顯示一個複選標記,「損失」欄應該爲空,反之亦然。類:

public class MyCriterion { 
    private String name; 
    private boolean beneficial; 

    public MyCriterion(String name) { 
     this(name, false); 
    } 

    public MyCriterion(String name, boolean beneficial) { 
     this.name = name; 
     this.beneficial = beneficial; 
    } 

    public String getName() { 
     return name; 
    } 

    public boolean isBeneficial() { 
     return beneficial; 
    } 

    public void setBeneficial(boolean beneficial) { 
     this.beneficial = beneficial; 
    } 

    @Override 
    public String toString() { 
     return "MyCriterion [name=" + name + ", beneficial=" + beneficial + "]"; 
    } 

} 

接下來,表格模型,因爲它是非常容易擴展的DefaultTableModel,比它擴展AbstractTableModel的,這是我決定的事,但同樣,給它3列,最後兩個依賴單個boolan的狀態,MyCriterion的beneficial字段。我「硬編碼」列標題:

public static final String[] COLUMN_NAMES = { "Type of Criteria", "Benefit", "Loss" }; 

,並通過他們進入超類的構造函數的頭一個數組和行數的int,並且初始行數當然是0的:

public CriteriaTableModel() { 
    super(COLUMN_NAMES, 0); 
} 

getColumnClass(int columnIndex)應該返回String.class如果器的columnIndex爲0,否則將返回一個Boolean.class,而這樣做會讓JTable中作爲JCheckBoxes顯示最後兩個值。這並不像將它們顯示爲JRadioButton那樣乾淨,但它很簡單並且很有效。

我給模型一個public void addCriterion(MyCriterion myCriterion)方法,使添加一行變得很簡單。它增加了一個MyCriterion值進入超級模型到第0列:

public void addCriterion(MyCriterion myCriterion) { 
    super.addRow(new MyCriterion[] {myCriterion}); 
} 

這意味着,該表的模型,這是由超級舉行的真正的「核」,其實是有一列模型,一個持有MyCriterion對象,所以我不得不重寫setValue(...)getValueAt(...)方法,這個單一數據列轉換爲顯示器的3列:

@Override 
public void setValueAt(Object aValue, int row, int column) { 
    MyCriterion myCriterion = (MyCriterion) super.getValueAt(row, 0); 
    boolean boolValue = (boolean) aValue; 
    switch (column) { 
    case 1: 
     myCriterion.setBeneficial(boolValue); 
     break; 
    case 2: 
     myCriterion.setBeneficial(!boolValue); 

    default: 
     break; 
    } 
    super.setValueAt(myCriterion, row, 0); 
    fireTableRowsUpdated(row, row); 
} 

@Override 
public Object getValueAt(int row, int column) { 
    MyCriterion myCriterion = (MyCriterion) super.getValueAt(row, 0); 
    switch (column) { 
    case 0: 
     return myCriterion.getName(); 
    case 1: 
     return myCriterion.isBeneficial(); 
    case 2: 
     return !myCriterion.isBeneficial(); 

    default: 
     String text = "Invalid column: " + column; 
     throw new IllegalArgumentException(text); 
    } 
} 

public MyCriterion getValueAt(int row) { 
    return (MyCriterion) super.getValueAt(row, 0); 
} 

我的整個表模型類:

Example image of GUI

import java.util.ArrayList; 
import java.util.List; 
import javax.swing.table.DefaultTableModel; 

public @SuppressWarnings("serial") 
class CriteriaTableModel extends DefaultTableModel { 
    public static final String[] COLUMN_NAMES = { "Type of Criteria", "Benefit", "Loss" }; 

    public CriteriaTableModel() { 
     super(COLUMN_NAMES, 0); 
    } 

    @Override 
    public Class<?> getColumnClass(int columnIndex) { 
     switch (columnIndex) { 
     case 0: 
      return String.class; 
     default: 
      return Boolean.class; 
     } 
    } 

    public void addCriterion(MyCriterion myCriterion) { 
     super.addRow(new MyCriterion[] {myCriterion}); 
    } 

    @Override 
    public void setValueAt(Object aValue, int row, int column) { 
     MyCriterion myCriterion = (MyCriterion) super.getValueAt(row, 0); 
     boolean boolValue = (boolean) aValue; 
     switch (column) { 
     case 1: 
      myCriterion.setBeneficial(boolValue); 
      break; 
     case 2: 
      myCriterion.setBeneficial(!boolValue); 

     default: 
      break; 
     } 
     super.setValueAt(myCriterion, row, 0); 
     fireTableRowsUpdated(row, row); 
    } 

    @Override 
    public boolean isCellEditable(int row, int column) { 
     return column > 0; 
    } 

    @Override 
    public Object getValueAt(int row, int column) { 
     MyCriterion myCriterion = (MyCriterion) super.getValueAt(row, 0); 
     switch (column) { 
     case 0: 
      return myCriterion.getName(); 
     case 1: 
      return myCriterion.isBeneficial(); 
     case 2: 
      return !myCriterion.isBeneficial(); 

     default: 
      String text = "Invalid column: " + column; 
      throw new IllegalArgumentException(text); 
     } 
    } 

    public MyCriterion getValueAt(int row) { 
     return (MyCriterion) super.getValueAt(row, 0); 
    } 

    public List<MyCriterion> getCriteria() { 
     List<MyCriterion> criteriaList = new ArrayList<>(); 
     for (int i = 0; i < getRowCount(); i++) { 
      criteriaList.add(getValueAt(i)); 
     } 
     return criteriaList; 
    } 

} 

最後GUI來顯示所有這一點,並有按鈕,允許從JTable的添加和移除列:

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class CriteriaList extends JPanel { 
    private CriteriaTableModel myModel = new CriteriaTableModel(); 
    private JTable criteriaTable = new JTable(myModel); 
    private JTextField criterionNameField = new JTextField(10); 
    private JCheckBox beneficialCB = new JCheckBox("Beneficial"); 

    public CriteriaList() { 
     criteriaTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
     myModel.addCriterion(new MyCriterion("Foo", true)); 
     myModel.addCriterion(new MyCriterion("Bar", false)); 

     JPanel bottomPanel = new JPanel(); 
     bottomPanel.add(new JLabel("Criterion:")); 
     bottomPanel.add(criterionNameField); 
     bottomPanel.add(beneficialCB); 
     bottomPanel.add(new JButton(new AddCriterion("Add"))); 
     bottomPanel.add(new JButton(new RemoveCriterion("Remove"))); 
     bottomPanel.add(new JButton(new DisplayCriterion("Display"))); 

     setLayout(new BorderLayout()); 
     add(new JScrollPane(criteriaTable)); 
     add(bottomPanel, BorderLayout.PAGE_END); 
    } 

    private class RemoveCriterion extends AbstractAction { 
     public RemoveCriterion(String name) { 
      super(name); 
      int mnemonic = (int) name.charAt(0); 
      putValue(MNEMONIC_KEY, mnemonic); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      int row = criteriaTable.getSelectedRow(); 
      if (row >= 0) { 
       myModel.removeRow(row); 
      } 
     } 
    } 

    private class DisplayCriterion extends AbstractAction { 
     public DisplayCriterion(String name) { 
      super(name); 
      int mnemonic = (int) name.charAt(0); 
      putValue(MNEMONIC_KEY, mnemonic); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      for (MyCriterion criterion : myModel.getCriteria()) { 
       System.out.println(criterion); 
      } 
     } 
    } 

    private class AddCriterion extends AbstractAction { 
     public AddCriterion(String name) { 
      super(name); 
      int mnemonic = (int) name.charAt(0); 
      putValue(MNEMONIC_KEY, mnemonic); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      String name = criterionNameField.getText(); 

      boolean beneficial = beneficialCB.isSelected(); 
      MyCriterion myCriterion = new MyCriterion(name, beneficial); 
      myModel.addCriterion(myCriterion); 

      criterionNameField.selectAll(); 
      criterionNameField.requestFocusInWindow(); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 

    private static void createAndShowGui() { 
     CriteriaList mainPanel = new CriteriaList(); 
     JFrame frame = new JFrame("Criteria List"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 
}