Изменение цвета строки JTable в зависимости от значения столбца — при щелчке всплывающего окна

#swing #jtable #tablemodel #tablecellrenderer

#swing #jtable #табличная модель #tablecellrenderer

Вопрос:

Мой jTable файл загружен данными, и именно здесь я вызываю свою всплывающую функциональность jTable .

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

По сути, если я щелкаю правой кнопкой мыши по строке, появляется всплывающее окно (проверка кредитоспособности), и если я щелкаю, оно присваивает значение последней ячейке в этой строке. Теперь, основываясь на значении ячейки этого столбца, я должен определить цвет строки. Допустим, если значение ячейки не соответствует действительности, тогда покрасьте строку в красный, а остальное — в зеленый. Я попробовал customCellRenderer и определил свое условие, но цвет строки не изменился. Пользовательский рендеринг ячеек отлично работал для функциональности кнопки, которую мне пришлось написать. Приведенный ниже код использует prepare cellRenderer , который, как мне показалось, прост, но я не вижу никаких изменений в цвете строки.

Мне не хватает какого-либо соединения, пожалуйста, помогите мне.

Заранее спасибо.

     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() amp;amp; table.getModel().getRowCount() != 0
               amp;amp; 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. редактирование каким-то образом странное — редактор забывает / сбрасывает материал? Код выглядел совершенно нормально в предварительном просмотре (после полной копии из моей IDE), теперь первая часть снова потеряна…

2. извините, ребята, это был мой первый пост..

Ответ №1:

после некоторого форматирования (поверьте мне, это важно для того, чтобы код был читабельным 😉 создается впечатление, что вы создаете экземпляр новой таблицы внутри вашего PopupMenu, и только у этой таблицы есть пользовательский рендерер. Что вы можете сделать, но не оказывает никакого влияния на вашу реальную таблицу.

Переместите prepareRenderer в вашу реальную таблицу (ту, которую вы передаете во всплывающее окно в качестве параметра), и вы должны увидеть цвет. Осторожно: из-за ошибки в DefaultTableCellRenderer цвет необходимо устанавливать всегда, то есть

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

Редактировать: пытаюсь объяснить изменения в структуре кода, фрагменты псевдокода

Текущее состояние, вот что вы делаете:

 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(... 
    }
  

Измените на, вот что вы должны сделать:

  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
  

правка 2:
— изменен псевдокод для фактической регистрации прослушивателя)
— код с отступом под addMouseListener представляет собой схему кода внутри TablePopupListener

Комментарии:

1. то, что вы сказали мне, имеет смысл. Но, как вызвать готовый рендерер без написания внутреннего класса в Jtable. Не могли бы вы показать мне какой-нибудь пример ссылки или какую-нибудь структуру.

2. ниже показано, как я вызываю свое всплывающее окно…… JTable.addMouseListener(новый TablePopupListener(JTable)); который находится в другом файле Java под названием FileChooser.java……………….. таким образом, вызов переходит к классу TablePopupListener. Код для класса TablePopupListener приведен в первом сообщении.

3. Без вызова table = new JTable (model){//Логика prepareRenderer} Я не мог вызвать prepareRenderer. Я написал эту логику в методе actionPerformed () класса TablePopupListener.