Сравнение двух таблиц и изменение цвета текста строки таблицы

174
16 декабря 2018, 21:20

Есть 2 таблицы. Sql запросом сравниваю таблицы на совпадающие значения первого столбика и при совпадении нужно закрасить строки первой таблицы зеленым цветом. Не получается это сделать. Закрашиваются все строки красным.

public class MyRenderer extends DefaultTableCellRenderer {
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
            boolean hasFocus, int row, int column) {
                try {
                    super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                    st=conn.createStatement();
                    sql = "Select DISTINCT id From product Where id In (Select id_product From invoices)";
                    rs= st.executeQuery(sql);
                    int result = 0;   
                    while (rs.next()){
                        result = rs.getInt("id");
                        for (int i = 0; i<table_allProduct.getRowCount();i++){
                        row = (int) table_allProduct.getValueAt(i, 0);}
                        //System.out.print(result+" ");                               
                        if(row == result) {
                            setForeground(Color.GREEN);
                            return this;
                        } else {
                            setForeground(Color.RED);
                        }
                    }                         
                    return this;                
                } catch (SQLException ex) {
                    Logger.getLogger(Success.class.getName()).log(Level.SEVERE, null, ex);
                }
                return this;
    }
}          
Answer 1

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

Попробуйте этот вариант:

public class MyRenderer extends DefaultTableCellRenderer {
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        // Нас интересует только первый столбец
        if (column != 0) {
            return this;
        }
        // Не знаю какое значение в value, но пусть будет Integer
        Integer valueId = (Integer) value;
        boolean has = false;
        try {
            st = conn.createStatement();
            sql = "Select DISTINCT id From product Where id In (Select id_product From invoices)";
            rs = st.executeQuery(sql);
            // Ищем наше значение среди, все из результата запроса
            while (rs.next()) {
                int result = rs.getInt("id");
                // Если нашли
                if (valueId == result) {
                    has = true;
                    break;
                }
            }               
            // Если has == true, окрашиваешь зеленым, иначе красным
            setForeground(has ? Color.GREEN : Color.RED);
        } catch (SQLException ex) {
            Logger.getLogger(Success.class.getName()).log(Level.SEVERE, null, ex);
        }
        return this;
    }
}

Но и предложенный мной вариант не эффективный, т.к. если у нас первый столбец это id таблицы product, который также совпадает с значением поля id_product таблицы invoices, то зачем нам делать запросы на id?

Ведь нам нужно просто проверить что такой id существует, а значит тот запрос можно упростить до sql = "SELECT 1 FROM invoices WHERE id_product = " + valueId; (чтобы не бояться sql-инъекции, нужно использовать биндинг параметров и PreparedStatement, но для этого примера и не зная чем у вас является conn, не стал это включать).

Тогда код упростится до:

public class MyRenderer extends DefaultTableCellRenderer {
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        // Нас интересует только первый столбец
        if (column != 0) {
            return this;
        }
        // Не знаю какое значение в value, но пусть будет Integer
        Integer valueId = (Integer) value;
        try {
            st = conn.createStatement();
            sql = "SELECT 1 FROM invoices WHERE id_product = " + valueId;
            rs = st.executeQuery(sql);
            // Если нашли id
            boolean has = rs.next();
            // Если has == true, окрашиваешь зеленым, иначе красным
            setForeground(has ? Color.GREEN : Color.RED);
        } catch (SQLException ex) {
            Logger.getLogger(Success.class.getName()).log(Level.SEVERE, null, ex);
        }
        return this;
    }
}

PS. заметил что у вас создается выражение st=conn.createStatement();, но не закрывается st.close(), так лучше не делать. Советую для этого использовать try-with-resource выражение.

Пример:

...
try (Statement st = conn.createStatement()) {
    sql = "Select DISTINCT id From product Where id In (Select id_product From invoices)";
    rs = st.executeQuery(sql);
    ...
} catch (SQLException ex) {
    Logger.getLogger(Success.class.getName()).log(Level.SEVERE, null, ex);
}
...
Answer 2
 for (int i = 0; i<table_allProduct.getRowCount();i++){
       row = (int) table_allProduct.getValueAt(i, 0);
       //System.out.print(result+" ");                               
       if(row == result) {
           setForeground(Color.GREEN);
           return this;
       } else {
           setForeground(Color.RED);
       }
  }
READ ALSO
IO Java. Проблемы с удалением и поиском

IO Java. Проблемы с удалением и поиском

Новичок в Java, учусьВозникла проблема с удалением и поиском во время решения

151
Пространство до строки в JavaScript

Пространство до строки в JavaScript

У меня программа, которая должна делать все слова с большой буквыЯ написал версию, которая делает слова с заглавной после первого слова

159
LEFT JOIN в sequelize

LEFT JOIN в sequelize

Использую mysql и sequelize в Nodejs проекте

185
Не работает маска ввода MaskedInput

Не работает маска ввода MaskedInput

Маска подключена два разаПервый раз работает второй - нет

180