如何动态改变线条的颜色?

时间:2019-07-01 07:23:21

标签: java swing

我的表看起来像这样,一切正常,一切都很好)我需要如果满足条件ARRIVAL = 0或DEPART = 0,则整行中的文本颜色是不同的颜色,例如红色或黑色,没关系,我不知道如何更改它,也许很简单,我是新来的)我没有在其他问题中找到该问题的答案

private void btnLogIdentifications2ActionPerformed(java.awt.event.ActionEvent evt) {                                                       
    setTableSettingsReport();
    searchIdentificationsReport(true);
    open = true;
}
public void searchIdentificationsReport(boolean all) {
    int z = 0;
    while (z < tm.getRowCount()) {
        tm.removeRow(z);
    }
    Statement statement = null;
    try {
        statement = getDbConnection().createStatement();
        String sql = "select a.id, pr.p_name,pr.p_surname,pr.p_patronic, a.date_arrival_from,a.date_arrival_to, a.arrival,a.date_departure_from,a.date_departure_to, a.depart, a.arrival_comment, a.depart_comment,a.prsn_id "
                + "  FROM bio.persons pr, attendance a where pr.p_id=a.prsn_id and a.date<=CURDATE() ";
        if (cbPersons.getSelectedItem() != null && model.getSelectedItem() != null) {
            CodeValueDTO dto = (CodeValueDTO) model.getSelectedItem();
            sql += " and  pr.p_id='" + dto.getId() + "'";
        }
        if (!all) {
            sql += " and (ARRIVAL =0 or DEPART=0)";

        }

        statement.execute(sql);
        ResultSet rs = statement.getResultSet();
        int value = 1;
        while (rs.next()) {
            Object[] objects = new Object[13];
            for (int i = 0; i < 13; i++) {
                objects[i] = rs.getObject(i + 1);
            }
            if (rs.getInt(7) == 0) {
                objects[6] = "Нет";

            } else {
                objects[6] = "Да";
            }

            if (rs.getInt(10) == 0) {
                objects[9] = "Нет";
            } else {
                objects[9] = "Да";
            }
            System.out.println(value);
            jTblReport.setDefaultRenderer(String.class, new MyCellRenderer(6));
            jTblReport.setDefaultRenderer(String.class, new MyCellRenderer(9));

            tm.addRow(objects);
        }

    } catch (SQLException ex) {
        ex.printStackTrace();
    } finally {
        try {
            statement.close();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }

}
private void setTableSettingsReport() {

    jTblReport.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    jTblReport.setRowSelectionAllowed(true);
    jTblReport.setAutoCreateRowSorter(true);
    jTblReport.getTableHeader().setReorderingAllowed(false);

    String[] dbColNames = new String[13];
    dbColNames[0] = "ID";
    dbColNames[1] = "Имя";
    dbColNames[2] = "Фамилия";
    dbColNames[3] = "Отчество";
    dbColNames[4] = "Дата прихода с ";
    dbColNames[5] = "Дата прихода до";
    dbColNames[6] = "Прибытие";
    dbColNames[7] = "Дата ухода с ";
    dbColNames[8] = "Дата ухода до";
    dbColNames[9] = "Убытие";
    dbColNames[10] = "Причина опоздания";
    dbColNames[11] = "Причина раннего ухода";
    dbColNames[12] = "ID лица";

    // dbColNames[8] = "Дата начала";
    //  dbColNames[9] = "Дата окончания";    
    tm.setColumnIdentifiers(dbColNames);
    jTblReport.setModel(tm);
    jTblReport.setSelectionForeground(Color.white);

    jTblReport.setSelectionBackground(Color.red);
    jTblReport.getColumnModel().getColumn(0).setPreferredWidth(10);
    jTblReport.getColumnModel().getColumn(1).setPreferredWidth(60);
    jTblReport.getColumnModel().getColumn(2).setPreferredWidth(60);
    jTblReport.getColumnModel().getColumn(3).setPreferredWidth(60);
    jTblReport.getColumnModel().getColumn(4).setPreferredWidth(60);
    jTblReport.getColumnModel().getColumn(5).setPreferredWidth(60);
    jTblReport.getColumnModel().getColumn(6).setPreferredWidth(60);
    jTblReport.getColumnModel().getColumn(7).setPreferredWidth(60);
    jTblReport.getColumnModel().getColumn(8).setPreferredWidth(60);
    jTblReport.getColumnModel().getColumn(9).setPreferredWidth(60);
    jTblReport.getColumnModel().getColumn(10).setPreferredWidth(60);
    jTblReport.getColumnModel().getColumn(10).setPreferredWidth(60);
    jTblReport.getColumnModel().getColumn(10).setPreferredWidth(60);

}

public class MyCellRenderer extends DefaultTableCellRenderer {

private int columNum = 0;

public MyCellRenderer(Integer columNum) {
    this.columNum = columNum;
}

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
        int row, int column) {
    Object object = table.getValueAt(row, this.columNum);

    if (object.equals("Нет")) {
        setBackground(Color.RED);
    }
    return this;
}

}

建议我编写渲染器,但是使用它时,我的整个表变为红色并且值不出现,即表为空

通过对象[6] =“Нет”和对象[9] =“Нет”

1 个答案:

答案 0 :(得分:3)

整个表格变成红色的问题是因为它重复使用了渲染器来绘制每个单元格,并且在您的代码中您只设置了一次背景(第一次遇到“Нет”时),并且从不将其恢复为默认颜色(或者不返回)颜色)。

只需将渲染器视为图章,如果您将图章涂成红色一次而又不重新涂成其他颜色,则所有下一个图章将变成红色。

您也不能真正做到这一点:

jTblReport.setDefaultRenderer(String.class, new MyCellRenderer(6));
jTblReport.setDefaultRenderer(String.class, new MyCellRenderer(9));

第二个优先于第一个,因为表每个类类型仅存储一个渲染器。相反,您可以直接在渲染器中处理此逻辑。话虽如此,不建议在渲染器中进行任何“繁重的工作”(例如服务器/数据库请求等),因为这会大大降低UI响应速度。相反,您应该在单独的线程上执行此类操作,并将结果提供给表模型。

无论哪种方式,下面是一个简单案例的完整示例:

import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.util.Objects;

/**
 * @author Mikle Garin
 * @see https://stackoverflow.com/questions/56831494/how-to-change-the-color-of-the-line-dynamically
 */
public class TableRenderer
{
    public static void main ( String[] args )
    {
        SwingUtilities.invokeLater ( () -> {
            final JFrame frame = new JFrame ( "Table renderer" );
            frame.add ( new JScrollPane ( createTableSettingsReport () ) );
            frame.setDefaultCloseOperation ( WindowConstants.EXIT_ON_CLOSE );
            frame.pack ();
            frame.setLocationRelativeTo ( null );
            frame.setVisible ( true );
        } );
    }

    private static JTable createTableSettingsReport ()
    {
        final String[] dbColNames = new String[ 13 ];
        dbColNames[ 0 ] = "ID";
        dbColNames[ 1 ] = "Имя";
        dbColNames[ 2 ] = "Фамилия";
        dbColNames[ 3 ] = "Отчество";
        dbColNames[ 4 ] = "Дата прихода с ";
        dbColNames[ 5 ] = "Дата прихода до";
        dbColNames[ 6 ] = "Прибытие";
        dbColNames[ 7 ] = "Дата ухода с ";
        dbColNames[ 8 ] = "Дата ухода до";
        dbColNames[ 9 ] = "Убытие";
        dbColNames[ 10 ] = "Причина опоздания";
        dbColNames[ 11 ] = "Причина раннего ухода";
        dbColNames[ 12 ] = "ID лица";

        final String[][] data = {
                { "1", "Сергей", "Кирчин", "Васильевич",
                        "15.12.2002", "22.12.2002", "Да",
                        "25.08.2005", "26.08.2005", "Да",
                        "Болел", "Стало плохо", "123" },

                { "2", "Сергей", "Кирчин", "Васильевич",
                        "15.12.2002", "22.12.2002", "Нет",
                        "25.08.2005", "26.08.2005", "Да",
                        "Болел", "Стало плохо", "123" },

                { "3", "Сергей", "Кирчин", "Васильевич",
                        "15.12.2002", "22.12.2002", "Да",
                        "25.08.2005", "26.08.2005", "Нет",
                        "Болел", "Стало плохо", "123" }
        };

        final JTable jTblReport = new JTable ( new DefaultTableModel ( data, dbColNames ) );
        jTblReport.setSelectionMode ( ListSelectionModel.SINGLE_SELECTION );
        jTblReport.setRowSelectionAllowed ( true );
        jTblReport.setAutoCreateRowSorter ( true );
        jTblReport.getTableHeader ().setReorderingAllowed ( false );

        jTblReport.setDefaultRenderer ( Object.class, new MyCellRenderer () );

        // Optionally (if you have Boolean values, just easier to distinguish the data by type):
        // jTblReport.setDefaultRenderer ( Boolean.class, new MyBooleanCellRenderer () );

        jTblReport.getColumnModel ().getColumn ( 0 ).setPreferredWidth ( 10 );
        jTblReport.getColumnModel ().getColumn ( 1 ).setPreferredWidth ( 60 );
        jTblReport.getColumnModel ().getColumn ( 2 ).setPreferredWidth ( 60 );
        jTblReport.getColumnModel ().getColumn ( 3 ).setPreferredWidth ( 60 );
        jTblReport.getColumnModel ().getColumn ( 4 ).setPreferredWidth ( 60 );
        jTblReport.getColumnModel ().getColumn ( 5 ).setPreferredWidth ( 60 );
        jTblReport.getColumnModel ().getColumn ( 6 ).setPreferredWidth ( 60 );
        jTblReport.getColumnModel ().getColumn ( 7 ).setPreferredWidth ( 60 );
        jTblReport.getColumnModel ().getColumn ( 8 ).setPreferredWidth ( 60 );
        jTblReport.getColumnModel ().getColumn ( 9 ).setPreferredWidth ( 60 );
        jTblReport.getColumnModel ().getColumn ( 10 ).setPreferredWidth ( 60 );
        jTblReport.getColumnModel ().getColumn ( 10 ).setPreferredWidth ( 60 );
        jTblReport.getColumnModel ().getColumn ( 10 ).setPreferredWidth ( 60 );

        return jTblReport;
    }

    public static class MyCellRenderer extends DefaultTableCellRenderer
    {
        public MyCellRenderer ()
        {
            super ();
            setOpaque ( true );
            setBackground ( Color.WHITE );
        }

        @Override
        public Component getTableCellRendererComponent ( final JTable table, final Object value, final boolean isSelected,
                                                         final boolean hasFocus, final int row, final int column )
        {
            // Still need to call this to setup default stuff below
            super.getTableCellRendererComponent ( table, value, isSelected, hasFocus, row, column );

            // We should let selection color override our highlight
            if ( !isSelected )
            {
                // Checking conditions
                final boolean arrival = Objects.equals ( table.getValueAt ( row, 6 ), "Да" );
                final boolean departure = Objects.equals ( table.getValueAt ( row, 9 ), "Да" );
                setBackground ( !arrival || !departure ? Color.RED : Color.WHITE );
            }

            return this;
        }
    }
}

在此示例中,渲染器适用于表格的所有单元格,并为每行的所有单元格上色为红色,以防问题中提到的第6列或第9列中有“Нет”。

这只是对未来的一小部分提示-强烈建议在Stack Overflow上发布SSCCE(可正常工作的简短代码示例),以减少其他人花费在遍历您的代码和分析到底是什么错误上的时间。您可以阅读有关SSCCE here的信息。这将大大增加从SO社区获得良好响应/解决方案的机会:)