2017-10-03 13 views
1

私の質問を見るために皆さんに感謝します。動的に作成された個々のJTableセルのセルエディターをオーバーライドします

JTableセル内にあるコンボボックスの選択を使用して、隣のセルのコンボボックスを動的に選択しようとしています。これまで読んできたことをたくさん行ってきましたが、その答えはそのセルのDefaultCellEditorをオーバーライドしている可能性が高いとわかりましたが、私の場合はこれの例が見つかりませんでした。また、JTableの処理方法を操作することが可能なように見えるので、構成は主に行ベースです。繰り返しますが、私は、私または私のアプリケーションに合った方法で例を解釈することはできません。

私が構築しているアプリでは、ユーザーが自分が好む多数のデータタグを入力できるようにしてから、3列のJTableにデータタグの入力と同じ行数を入力します。私は事前にXML解析をいくつか行い、最終的な目標に役立ついくつかの値を見つけますが、最終的にはJTableの作成と書式設定には影響しません。

XMLファイル内の特定のデータ型に対応する一連のコンボボックスを構築します。コンボボックスは、アプリケーション内の別のjPanelでテストされていますが、2番目の列の対応するセルで値が選択されると、JTableの3番目の列には挿入されません。また、この機能では、リスナーがマウスの操作をプライマリコンボボックスと解釈する必要があるため、セカンダリ(3列目)のコンボボックスを作成するコードが行単位でのみ実行されるように見えます。これは正しいのですか?もしそうなら、コンボボックスのマウス編集を解釈して処理するためにはどうすればいいですか?

私のコードとフォローするアプリのスクリーンショット:

This is the user-input form for my GUI. "Number of Tags" sets row count

package adduimdevsswing; 
import java.lang.String; 
import java.awt.*; 
import javax.swing.*; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.TableColumn; 
import java.io.StringWriter; 
import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerException; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 
import java.io.File; 
import javax.xml.transform.OutputKeys; 
import org.w3c.dom.Document; 
import org.w3c.dom.Node; 
import org.w3c.dom.Element; 
import org.w3c.dom.NodeList; 

public class NewJFrame extends javax.swing.JFrame { 
    String testString = ""; 
    String txt = ""; 
    String ResultString1 = ""; 
    String ResultString2 = ""; 
    String[] ResultStringArray; 
    String[] DataTypes = {"Counter","Counter32","Counter64","INTEGER","Integer32", 
         "Unsigned32","Gauge","Gauge32","DisplayString","TruthValue","TimeTicks"}; 
    int ElemLength = 0; 
    int NumOfVariables = 0; 
    String[] VariableUnitNames; 
    String[] TextFieldValues; 
    String[] ComboBoxValues; 
    JTextField[] TextFields; 
    int NumberOfTags = 0; 
    JPanel AddTagsPanel = new JPanel(); 
    DefaultTableModel TableModel; 
    TableColumn DataTypeColumn; 
    JComboBox ComboBox = new JComboBox(DataTypes); 
    NodeList varGroup; 
    NodeList varName; 
    NodeList varDataType; 
    Node Node1; 
    Element Element1; 
    JComboBox CounterCombo; 
    JComboBox Counter32Combo; 
    JComboBox Counter64Combo; 
    JComboBox INTEGERCombo; 
    JComboBox Integer32Combo; 
    JComboBox Unsigned32Combo; 
    JComboBox GaugeCombo; 
    JComboBox Gauge32Combo; 
    JComboBox DisplayStringCombo; 
    JComboBox TruthValueCombo; 
    JComboBox TimeTicksCombo; 

    public NewJFrame() 
    { 
     initComponents(); 
     jTable1.getColumnModel().getColumn(0).setHeaderValue("Tag Name"); //set first column to be "Tag Name" column 
     jTable1.getColumnModel().getColumn(1).setHeaderValue("Data Type"); //set second column to be "Data Type" column 
     jTable1.getColumnModel().getColumn(2).setHeaderValue("Tag Units"); //set third column to be "Tag Units" column 
     jTable1.setVisible(false); //aesthetically set jTable1 to not be visible until configured by user input 

     try 
     {   
      File MIBFILE = new File("/opt/ecoMeterMIB.xml"); //select the text MIB file to work with 

      /*create instance of documentBuilder*/ 
      DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); 
      Document doc = dBuilder.parse(MIBFILE); 

      /*Find the latest instance of nmsElemTag within ecoMeterMIB.xml by checking the "length" (highest count) of nmsElemTag*/ 
      ElemLength = doc.getElementsByTagName("nmsElemTag").getLength(); 
      NumOfVariables = doc.getElementsByTagName("variableGroup").getLength(); 
      varGroup = doc.getElementsByTagName("variableGroup"); 
      jTextField3.setText(Integer.toString(NumOfVariables)); //display number of variables (nmsElemTag length) 
      String[] varNameStr = new String[NumOfVariables]; 

      /*Define lists to be used as constructors for comboBoxes - Done here to be accessible elsewhere*/ 
      String[] varDataTypeStr = new String[NumOfVariables]; 
      List CounterType = new List(); 
      List Counter32Type = new List(); 
      List Counter64Type = new List(); 
      List INTEGERType = new List(); 
      List Integer32Type = new List(); 
      List Unsigned32Type = new List(); 
      List GaugeType = new List(); 
      List Gauge32Type = new List(); 
      List DisplayStringType = new List(); 
      List TruthValueType = new List(); 
      List TimeTicksType = new List(); 

      /*Parse XML to find/sort all elements by name & data type*/ 
      for(int a=0;a<NumOfVariables;a++) 
      { 
       Element1 = (Element) varGroup.item(a); 
       varName = Element1.getElementsByTagName("name"); 
       varDataType = Element1.getElementsByTagName("dataType"); 
       varNameStr[a] = varName.item(0).getTextContent(); 
       varDataTypeStr[a] = varDataType.item(0).getTextContent(); 

       switch (varDataTypeStr[a]) 
       { 
        case "Counter": 
         CounterType.add(varNameStr[a]); //If dataType is "Counter", Add to Counter Type List 
         break; 
        case "Counter32": 
         Counter32Type.add(varNameStr[a]); //If dataType is "Counter32", Add to Counte32r Type List 
         break; 
        case "Counter64": 
         Counter64Type.add(varNameStr[a]); //If dataType is "Counter64", Add to Counter64 Type List 
         break; 
        case "INTEGER": 
         INTEGERType.add(varNameStr[a]); //If dataType is "INTEGER", Add to INTEGER Type List 
         break; 
        case "Integer32": 
         Integer32Type.add(varNameStr[a]); //If dataType is "Integer32", Add to Integer32 Type List 
         break; 
        case "Unsigned32": 
         Unsigned32Type.add(varNameStr[a]); //If dataType is "Unsigned32", Add to Unsigned32 Type List 
         break; 
        case "Gauge": 
         GaugeType.add(varNameStr[a]); //If dataType is "Gauge", Add to Gauge Type List 
         break; 
        case "Gauge32": 
         Gauge32Type.add(varNameStr[a]); //If dataType is "Gauge32", Add to Gauge32 Type List 
         break; 
        case "DisplayString": 
         DisplayStringType.add(varNameStr[a]); //If dataType is "DisplayString", Add to DisplayString Type List 
         break; 
        case "TruthValue": 
         TruthValueType.add(varNameStr[a]); //If dataType is "TruthValue", Add to TruthValue Type List 
         break; 
        case "TimeTicks": 
         TimeTicksType.add(varNameStr[a]); //If dataType is "TimeTicks", Add to TimeTicks Type List 
         break; 
        default: 
         break; 
       } 
      } 

      /*Create comboBoxes and populate them with the items from above corresponding lists*/ 
      CounterCombo = new JComboBox(CounterType.getItems()); 
      Counter32Combo = new JComboBox(Counter32Type.getItems()); 
      Counter64Combo = new JComboBox(Counter64Type.getItems()); 
      INTEGERCombo = new JComboBox(INTEGERType.getItems()); 
      Integer32Combo = new JComboBox(Integer32Type.getItems()); 
      Unsigned32Combo = new JComboBox(Unsigned32Type.getItems()); 
      GaugeCombo = new JComboBox(GaugeType.getItems()); 
      Gauge32Combo = new JComboBox(Gauge32Type.getItems()); 
      DisplayStringCombo = new JComboBox(DisplayStringType.getItems()); 
      TruthValueCombo = new JComboBox(TruthValueType.getItems()); 
      TimeTicksCombo = new JComboBox(TimeTicksType.getItems());            
     }  

     catch(Exception e) 
     { 
      System.out.println(e); 
     } 

    } 

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed 

    /*Update button and tooltip text for reuse of form*/ 
    jButton2.setText("Re-Create Form"); //Set Button Text to "Re-Create Form" 
    jButton2.setToolTipText("Click to Rebuild the Form for a New Number of Tags."); //Set Tooltip Text 
    NumberOfTags = Integer.parseUnsignedInt(jTextField1.getText()); //Set Number Of tags for new device to user's input 
    TableModel = new DefaultTableModel(NumberOfTags,3); //Create a table model with # of tags from input and three columns 

    jTable1.setModel(TableModel); //set jTable1 in GUI Designer to be rebuilt based on TableModel    
    jTable1.getColumnModel().getColumn(0).setHeaderValue("Tag Name"); //set first column to be "Tag Name" column 
    jTable1.getColumnModel().getColumn(1).setHeaderValue("Data Type"); //set second column to be "Data Type" column 
    jTable1.getColumnModel().getColumn(2).setHeaderValue("Tag Units"); //set third column to be "Tag Units" column   
    jTable1.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(ComboBox)); //second column's default editor is dataTypes comboBox 
    jTable1.setVisible(true); //Table is visible 
    jTable1.setFocusable(true); //Table can take focus 

    jComboBox1.setModel(INTEGERCombo.getModel()); //debugging to confirm comboBox objects receive appropriate values (device info tab of UI) 

     switch(jTable1.getCellEditor(jTable1.getSelectedRow(), 1).getCellEditorValue().toString()) 
       { 
        case "Counter": 
           jTable1.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(CounterCombo)); 
           break; //^if dataType is Counter, set cell editor to CounterCombo tag units combo box 
          case "Counter32": 
           jTable1.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(Counter32Combo)); 
           break; //^if dataType is Counter32, set cell editor to Counter32Combo tag units combo box 
          case "Counter64": 
           jTable1.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(Counter64Combo)); 
           break; //^if dataType is Counter64, set cell editor to Counter64Combo tag units combo box 
          case "INTEGER": 
           jTable1.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(INTEGERCombo)); 
           break; //^if dataType is INTEGER, set cell editor to INTEGERCombo tag units combo box 
          case "Integer32": 
           jTable1.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(Integer32Combo)); 
           break; //^if dataType is Integer32, set cell editor to Integer32Combo tag units combo box 
          case "Unsigned32": 
           jTable1.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(Unsigned32Combo)); 
           break; //^if dataType is Unsigned32, set cell editor to Unsigned32Combo tag units combo box 
          case "Gauge": 
           jTable1.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(GaugeCombo)); 
           break; //^if dataType is Gauge, set cell editor to GaugeCombo tag units combo box 
          case "Gauge32": 
           jTable1.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(Gauge32Combo)); 
           break; //^if dataType is Gauge32, set cell editor to Gauge32Combo tag units combo box 
          case "DisplayString": 
           jTable1.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(DisplayStringCombo)); 
           break; //^if dataType is DisplayString, set cell editor to DisplayStringCombo tag units combo box 
          case "TruthValue": 
           jTable1.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(TruthValueCombo)); 
           break; //^if dataType is TruthValue, set cell editor to TruthValueCombo tag units combo box 
          case "TimeTicks": 
           jTable1.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(TimeTicksCombo)); 
           break; //^if dataType is TimeTicks, set cell editor to TimeTicksCombo tag units combo box 
          default: 
           break; 
       } 

答えて

2

あなたが動的にJTableののgetCellEditor(...)メソッドをオーバーライドし、コンボボックス内の項目を変更することができます。ただ、行に基づいてアイテムに変更を下回る

例は:

import java.awt.*; 
import java.util.List; 
import java.util.ArrayList; 
import javax.swing.*; 
import javax.swing.event.*; 
import javax.swing.border.*; 
import javax.swing.table.*; 

public class TableComboBoxByRow extends JPanel 
{ 
    List<String[]> editorData = new ArrayList<String[]>(3); 

    public TableComboBoxByRow() 
    { 
     setLayout(new BorderLayout()); 

     // Create the editorData to be used for each row 

     editorData.add(new String[]{ "Red", "Blue", "Green" }); 
     editorData.add(new String[]{ "Circle", "Square", "Triangle" }); 
     editorData.add(new String[]{ "Apple", "Orange", "Banana" }); 

     // Create the table with default data 

     Object[][] data = 
     { 
      {"Color", "Red"}, 
      {"Shape", "Square"}, 
      {"Fruit", "Banana"}, 
      {"Plain", "Text"} 
     }; 
     String[] columnNames = {"Type","Value"}; 

     DefaultTableModel model = new DefaultTableModel(data, columnNames); 
     JTable table = new JTable(model) 
     { 
      // Determine editor to be used by row 
      public TableCellEditor getCellEditor(int row, int column) 
      { 
       int modelColumn = convertColumnIndexToModel(column); 

       if (modelColumn == 1 && row < 3) 
       { 
        JComboBox<String> comboBox1 = new JComboBox<String>(editorData.get(row)); 
        return new DefaultCellEditor(comboBox1); 
       } 
       else 
        return super.getCellEditor(row, column); 
      } 
     }; 

     JScrollPane scrollPane = new JScrollPane(table); 
     add(scrollPane); 
//  table.getColumnModel().getColumn(1).setCellRenderer(new ComboBoxRenderer2()); 
    } 
/* 
    class ComboBoxRenderer2 extends DefaultTableCellRenderer 
    { 
     @Override 
     public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) 
     { 
      JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 
      label.setIcon(UIManager.getIcon("Table.descendingSortIcon")); 
      return label; 
     } 
    } 
*/ 
    private static void createAndShowUI() 
    { 
     JFrame frame = new JFrame("Table Combo Box by Row"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new TableComboBoxByRow()); 
     frame.setSize(200, 200); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

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

をお使いの場合には、エディタは、前の列内のデータに基づいて変更されますが、考え方は同じになります。

+0

私はあなたの答えをありがとう、あなたの同じコードを他の投稿された問題への回答として読んでいます。しかし、私はこれが私が抱えている問題の解決策としてどのように機能するか見ることに苦労しています。 "データ型"列(2列目)の個々のセルを見て、選択した値を使用して、このセルの右側にある単一のセルに直接コンボボックスを生成する必要があります。 Units "列(3列目) - 同じcellEditorを使用する行または列を1つも設定しないでください。さらに、試してみると、getCellEditorを効果的にオーバーライドできません。 – Greg2Duo

+0

おそらく、私は行と列の両方の入力を可能にするためにsetCellEditorをオーバーライドする必要がありますか? – Greg2Duo

+0

''データタイプ 'の列にある個々のセルを正確に見ることができる必要があります。あなたは行/列を知っています。したがって、3列目のエディタを取得したら、まずテーブルのgetValueAt(row、2)メソッドを使用して2列目の値を取得します。次に、返された値に基づいて適切なエディタを返します。前に述べたように、私が提供する簡単な実装は行と列に依存します。前の列の行/列と値を知る必要があります。 – camickr

関連する問題