Изменение цвета ячеек Java JTable
Я хотел бы сделать редактируемую таблицу, а затем проверить данные, чтобы убедиться, что она действительна. Я не уверен, как изменить цвет только одной ячейки. Я хотел бы получить ячейку, например (0,0), и окрасить передний план в красный. Я прочитал другие сообщения о SO, а также Oracle о пользовательском ColorRenderer, но я просто не понимаю, как я буду использовать это.
Спасибо.
Ответы
Ответ 1
Скажите, что ячейка, которую вы хотите отобразить с другим цветом, представляет собой статус (в качестве примеров я возьму отвергнутый и одобренный). Затем я бы выполнил метод в моей модели таблицы с именем getStatus (int row), который возвращает статус для любой заданной строки.
Затем, когда это будет на месте, я собираюсь создать обработчик ячеек, ответственный за рендеринг столбца, к которому принадлежит ячейка. Средство визуализации ячеек должно быть чем-то в строках приведенного ниже кода.
public class StatusColumnCellRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
//Cells are by default rendered as a JLabel.
JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
//Get the status for the current row.
CustomTableModel tableModel = (CustomTableModel) table.getModel();
if (tableModel.getStatus(row) == CustomTableModel.APPROVED) {
l.setBackground(Color.GREEN);
} else {
l.setBackground(Color.RED);
}
//Return the JLabel which renders the cell.
return l;
}
Затем, когда средство визуализации находится на месте, просто "примените" средство визуализации к таблице со следующим фрагментом кода:
Table.getColumnModel().getColumn(columnIndex).setCellRenderer(new StatusColumnCellRenderer());
Что касается создания редактируемой ячейки, просто примените метод isCellEditable (int rowIndex, int columnIndex) в вашей модели таблицы. Вам также необходимо реализовать метод
setValueAt (значение Object, int rowIndex, int columnIndex), если вы хотите сохранить значение, которое предоставляет пользователь (что я предполагаю, что вы это делаете!).
Ответ 2
Я хотел бы сделать редактируемую таблицу, а затем проверить данные, чтобы убедиться, что она действительна.
Другим подходом было бы отредактировать данные до их сохранения в модели таблицы, чтобы предотвратить ввод недействительных данных.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.swing.table.*;
public class TableEdit extends JFrame
{
TableEdit()
{
JTable table = new JTable(5,5);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollpane = new JScrollPane(table);
getContentPane().add(scrollpane);
// Use a custom editor
TableCellEditor fce = new FiveCharacterEditor();
table.setDefaultEditor(Object.class, fce);
}
class FiveCharacterEditor extends DefaultCellEditor
{
FiveCharacterEditor()
{
super( new JTextField() );
}
public boolean stopCellEditing()
{
try
{
String editingValue = (String)getCellEditorValue();
if(editingValue.length() != 5)
{
JTextField textField = (JTextField)getComponent();
textField.setBorder(new LineBorder(Color.red));
textField.selectAll();
textField.requestFocusInWindow();
JOptionPane.showMessageDialog(
null,
"Please enter string with 5 letters.",
"Alert!",JOptionPane.ERROR_MESSAGE);
return false;
}
}
catch(ClassCastException exception)
{
return false;
}
return super.stopCellEditing();
}
public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, int row, int column)
{
Component c = super.getTableCellEditorComponent(
table, value, isSelected, row, column);
((JComponent)c).setBorder(new LineBorder(Color.black));
return c;
}
}
public static void main(String [] args)
{
JFrame frame = new TableEdit();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
Ответ 3
Самый простой способ - написать простой TableCellRenderer
, расширив DefaultTableCellRenderer
и перезаписав метод getTableCellRendererComponent
до setBackground( Color.RED )
. Например:
final JTable table = new JTable(...);
table.setCellRenderer( new DefaultTableCellRenderer() {
public Component getTableCellRenderer(JTable table, Object value, ...) {
super.getTableCellRenderer(...);
if ( value should be highlighted ) {
setBackground( Color.RED );
}
return this;
}
});
Ответ 4
Это самый простой способ покрасить конкретный столбец или ячейку в jTable.
Сначала просто создайте простой класс CustomRenderer
class CustomRenderer extends DefaultTableCellRenderer <br />
{
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
setForeground(Color.blue); >
return c;
}
}
Этот код получает столбец ячейки для рендеринга
TableColumn col = tblExamHistoryAll.getColumnModel().getColumn(5);
DefaultTableModel model3 = (DefaultTableModel)tblExamHistoryAll.getModel();
col.setCellRenderer(new CustomRenderer());
Это очистить все предыдущие строки из вашей таблицы. Если вы не хотите, чтобы они просто удаляли эти строки
model3.getDataVector().removeAllElements();
model3.fireTableDataChanged();
Ответ 5
Я считаю, что правильный способ сделать раскраску в таблице с помощью ColorHighlighter
. У средств визуализации таблиц есть проблемы с отображением разных цветов в одном столбце.
Вот пример того, как использовать маркеры. В этом случае это для выделения ячейки, которая не редактируется.
public class IsCellEditablePredicate implements HighlightPredicate {
private JXTable table;
public IsCellEditablePredicate (final JXTable table) {
this.table = table;
}
@Override
public boolean isHighlighted(Component component, ComponentAdapter componentAdapter) {
return !table.isCellEditable(componentAdapter.row,
componentAdapter.column);
}
}
а затем в своем коде для настройки таблицы вы добавляете маркер и его параметры цвета:
ColorHighlighter grayHighlighter = new ColorHighlighter(new IsCellEditablePredicate(table));
grayHighlighter.setBackground(Color.LIGHT_GRAY);
grayHighlighter.setForeground(table.getForeground());
grayHighlighter.setSelectedBackground(table.getSelectionBackground().darker());
grayHighlighter.setSelectedForeground(table.getSelectionForeground().darker());
table.setHighlighters(grayHighlighter);
Ответ 6
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int col) {
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
int control = row;
control = control % 2;
control = (control == 0) ? 1 : 0;
if (control == 1) {
c.setBackground(Color.green);
} else {
c.setBackground(Color.cyan);
}
return c;
}
Ответ 7
Вы можете расширить DefaultTableCellRenderer, переопределить getTableCellRendererComponent и вызвать что-то вроде
if (myConditions) setBackground(myColor);
перед возвратом "this", когда применяются условия, но у него есть очень раздражающий побочный эффект изменения заднего цвета по умолчанию из-за способа кодирования DefaultTableCellRenderer.setBackGround.
Уловка, которую я нашел, состояла в том, чтобы продублировать DefaultTableCellRenderer в классе с именем HackedDefaultTableCellRenderer, добавить метод, который напрямую вызывает реализацию компонента setBackground:
public void setComponentBackground(Color c) {
super.setBackground(c);
}
затем расширьте этот взломанный класс вместо DefaultTableCellRenderer и вызовите setComponentBackground вместо setBackground в getTableCellRendererComponent.
Недостатком является то, что этот HackedDefaultTableCellRenderer опирается на снимок DefaultTableCellRenderer.