JTable row color change based on a column value- on pop up click

半城伤御伤魂 提交于 2019-12-11 18:05:59

问题


My jtable is loaded with data and this is where I call my Pop up functionality on jTable.

jTable.addMouseListener(new TablePopupListener(jTable));
displayTable();

So basically, if I right click a row, a popup(credit check) comes up and if I click it is setting a value to the last cell in that row. Now, based on this column cell value I have to define the color of a row. Let's say, if the cell value is fail then turn the row to red else to green. I have tried customCellRenderer and defined my condition but there is no change in row color. The custom cell renderer worked great for a button functionality that I had to write, though. The below code uses prepare cellRenderer which I felt is easy but I don't see any change in row color.

I am missing some connection, plz provide me help.

Thanks in advance.

    class TablePopupListener extends MouseAdapter implements ActionListener { 
        JPopupMenu popup; 
        JTable table; 
        int[] selRows; 
        TableModel model; 
        ArrayList rowValueList = new ArrayList(); 
        JMenuItem creditCheck = new JMenuItem("Credit Check");

        public TablePopupListener(JTable jTable) {
            this.table = jTable;
            model = table.getModel();
            popup = new JPopupMenu();
            JMenuItem creditCheck = new JMenuItem("Credit Check");
            creditCheck.addActionListener(this);
            popup.add(creditCheck);

        }

        public void mousePressed(MouseEvent me) {
           firePopup(me);
        }

        public void mouseReleased(MouseEvent me) {
           firePopup(me);
        }

        public void firePopup(MouseEvent me) {

            /*
             * The popup menu will be shown only if there is a row selection in the
             * table
             */

            // popup.show(table, me.getX(), me.getY());
            if (me.isPopupTrigger() && table.getModel().getRowCount() != 0
               && table.getSelectedRow() != -1) {
              // popup.show(table,me.getX(),me.getY());
              if (me.isPopupTrigger()) {
                   JTable source = (JTable) me.getSource();
                   int row = source.rowAtPoint(me.getPoint());
                   int column = source.columnAtPoint(me.getPoint());

                   if (!source.isRowSelected(row))
                      source.changeSelection(row, column, false, false);

                   popup.show(table, me.getX(), me.getY());

              }
            }
         }

    public void actionPerformed(ActionEvent ae) {
        if (ae.getActionCommand().equals("Credit Check")) {
            System.out.println("you have clicked creditCheckpopup");
            selRows = table.getSelectedRows();
            if (selRows.length > 0) {
                for (int i = 0; i < selRows.length; i++) {
                  // get Table data
                    for (int j = 1; j < (table.getColumnCount()) - 1; j++) {
                        rowValueList.add(model.getValueAt(selRows[i], j));
                    }
                    System.out.println("Selection : " + rowValueList);
                }
            } else {
                System.out.println("you have clicked something idiot");
            }

            int result = new COpxDeal(rowValueList).CheckCredit();
            if (result == 1)
                rowValueList.add("pass");
            else
                rowValueList.add("fail");
            String aValue = (String) rowValueList.get(14);
            for (int i = 0; i < selRows.length; i++) {
                model.setValueAt(aValue, selRows[i], 15);
            }

     // inserted comment (Kleopatra): where are we? that's outside of the TablePopup?
     // okay, nothing like copying the code into an IDE and let that do the formatting, silly me ;-)
     // this is indeed _inside_ the popup, that is the table is recreated
            table = new JTable(model) {
                public Component prepareRenderer(TableCellRenderer renderer,
                        int row, int column) {
                    Component c = super.prepareRenderer(renderer, row, column);
                    JComponent jc = (JComponent) c;

                    // if (!isRowSelected(row)){
                    // c.setBackground(getBackground());
                    // System.out.println(isRowSelected(row));
                    // }
                    int modelRow = convertRowIndexToModel(row);
                    String strTestValue = "fail";
                    String strTblValue = (String) getModel().getValueAt(
                            modelRow, 15);
                    System.out.println("result :" + strTblValue);
                    if (strTblValue == null || strTblValue.equals(""))
                        System.out.println("there is nothing in strTblValue");
                    else if (strTestValue.equals(strTblValue)) {
                        jc.setBackground(Color.RED);
                    } else {
                        jc.setBackground(Color.green);
                    }

                    return c;
                }
            };

        }

    }
}

回答1:


after some formatting (believe me, it's important for code to be readable ;-) seems like you instantiate a new table inside your popupMenu and only that table has the custom renderer. Which you can do, but doesn't have any effect on the your real table.

Move the prepareRenderer into your real table (the one you pass into the popup as parameter) and you should see the coloring. Beware: due to a bug in DefaultTableCellRenderer, you have to set the color always, that is

 if (nothingToDo) {
     setBackground(normal)
 } else if ... {
     setBackground(one)
 } else {
     setBackground(other)
 }

Edit: trying to explain the changes in code structure, pseudo-code snippets

Current state, that's what you are doing:

JTable table = new JTable();
table.addMouseListener(new TablePopupListener(table));
     // keep listener-local reference to table
    JTable table = table;
    ....
    // in the listener guts, the reference is replaced
    table = new JTable() {
         @Override
         Component prepareRenderer(... 
    }

Change to, that's what you should do:

 JTable table = new JTable() {
      @Override
      Component prepareRenderer(...
 };
 table.addMouseListener(new TablePopupListener(table));
     // keep listener-local reference to table
     JTable table = table;
     // don't replace ever, it's for reading only

edit 2: - changed the pseudo-code to actually register the listener) - the code indented below the addMouseListener is mean as an outline of the code inside the TablePopupListener



来源:https://stackoverflow.com/questions/5878908/jtable-row-color-change-based-on-a-column-value-on-pop-up-click

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!