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

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

我被建议写我的渲染,但是使用它,我的整个表格变成红色并且值不出现,即表格是空的

通过 objects[6] = "Нет"和 objects[9] = "Нет"检查到达和离开

最佳答案

为什么你的整个表格变成红色的问题是因为它重复使用渲染器来绘制每个单元格并且在你的代码中你只设置一次背景(在第一次遇到“Нет”时)并且永远不会将它恢复为默认颜色(或没有颜色)。

只需将渲染器想象成一个邮票,如果您将邮票涂成红色一次并且不再将其重新着色为其他颜色 - 您的所有下一个邮票都将是红色。

而且你不能真的这样做:

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 列中有“Нет”。

这只是对 future 的一个小说明 - 强烈建议在 Stack Overflow 上发布一个 SSCCE(完整的短代码示例),以减少其他人需要花在检查你的代码和分析究竟是什么错误上的时间.您可以阅读 SSCCE here .这将大大增加从 SO 社区获得良好响应/解决方案的机会:)

关于java - 如何动态改变线条的颜色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56831494/

相关文章:

java - JTextArea 的行号和调整 JTextArea 文本大小的问题

java - 将 JSlider 添加到具有 GridLayout 的 JFrame (Java)

java - Eclipse/Hibernate 工具错误 : Archive classpath entry doesn't exist

java - 如何配置 Spring 以使用 aspectj 进行事务处理?

java - 我如何在一个类中拥有 JTextArea,并打印到另一个类中的 JTextArea?

java - JOptionPane 不接受长类型

java - 如何知道应用程序使用的是软键盘还是硬件键盘?

Java:.contains 和 .equals

java - 枚举感知的 ServiceLoader 实现?

java - 如何禁用 JTree 上的默认键行为?