覆盖已动态创建的单个JTable单元格的单元格编辑器

时间:2017-10-03 19:28:20

标签: java swing netbeans combobox

我感谢大家停下来看我的问题。

我正在尝试使用选择JTable单元格内的组合框来动态选择下一列中相邻单元格的组合框。到目前为止,我已经做了很多阅读和实验,并且发现答案最有可能在于覆盖所述单元格的DefaultCellEditor,但我没有找到一个在我的情况下有意义的例子。此外,似乎可以操纵JTable的处理方式,因此配置主要是基于行的。同样,我无法以对我或我的应用程序有意义的方式解释示例。

我正在构建的应用程序允许用户输入他或她更喜欢使用的多个数据标签,然后使用与数据标签输入一样多的行填充三列的JTable。我提前做了一些XML解析,找到了一些对我的最终目标有用的值,但最终不会影响JTable的创建和格式化。

我构建了一组与XML文件中的特定数据类型相对应的组合框。组合框已经在我的应用程序中的不同jPanel上进行了测试,但是当在第二列的相应单元格中选择了值时,它们不会填充到JTable的第三列中。看起来这个功能似乎需要一个Listener来解释鼠标与主组合框的交互,因此创建辅助(第三列)组合框的代码只能逐行执行。这是正确的,如果是这样的话:我必须采取什么方法来解释和处理组合框的鼠标编辑?

我的代码和要关注的应用的屏幕截图:

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;
                }

1 个答案:

答案 0 :(得分: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();
            }
        });
    }
}

在您的情况下,编辑器将根据前一列中的数据进行更改,但概念将相同。