[英]How to change the color of the line dynamically?
我的表看起来像这样,一切正常,一切正常)我需要如果满足条件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] =“Нет”到达和离开检查
整个表变红的问题是因为它重复使用渲染器绘制每个单元格,并且在代码中只设置背景一次(在第一次遇到“Нет”时)并且永远不会将其返回到默认颜色(或没有颜色)。
只需将渲染器视为印章,如果您将印章涂成红色一次并且不将其重新着色为其他东西 - 您的所有下一个印章都将为红色。
你也不能真的这样做:
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。 这将大大增加从SO社区获得良好响应/解决方案的机会:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.