I read a lot of articles and finally got my JTable rendering as per my requirements but the problem is when the table is scrolled by user, some of the other hidden parts of jtable are also colored as shown in image below
And when the user scrolls the table, other parts are also got colored like this
Why this happens? I read many articles and and all of them show exactly the same thing but this...
Here is my code
JTable table = new JTable()
{
public boolean isCellEditable(int rowIndex, int colIndex)
{
return false;
}
};
(DefaultTableCellRenderer)table.getTableHeader().getDefaultRenderer())
.setHorizontalAlignment(JLabel.CENTER);
table.setModel(new DefaultTableModel(new Object [][] {}, Columns));
table.setRowHeight(25);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.getColumnModel().removeColumn(table.getColumnModel().getColumn(0));
table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer()
{
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if(!table.getModel().getValueAt(row, 10).toString().equals("true"))
{
setBackground(new Color(246,137,137));
}
return this;
}
});
JScrollPane areaScrollPane = new JScrollPane(table);
areaScrollPane.setPreferredSize(new Dimension(width, height));
MyPanel.add(areaScrollPane);
All the articles show this way to render custom row on condition base. What's wrong in my code? Thanks for any support.
if(!table.getModel().getValueAt(row, 10).toString().equals("true"))
{
setBackground(new Color(246,137,137));
}
The same renderer is used for all cells so once you set the background it will apply for all cells. So, I think you need something like:
if(!table.getModel().getValueAt(row, 10).toString().equals("true"))
{
setBackground(new Color(246,137,137));
}
else
setBackground( table.getBackground() );
You should also add code to make sure the cell is not selected so that the default selection color can be painted.
Instead of using a custom renderer you can also override the prepareRenderer(...) method of JTable. Table Row Rendering show how you can render a row based on a value in that row.
Related
I tried to change JTable title cells colour in NetBeans but it doesn't change. But trying to do same things in text editor and it is running perfectly .
This is the Java code related to my problem:
jTable1.getTableHeader().setBackground(Color.GREEN);
Please help me.
The problem is Netbeans gives a set up look and feel. You can create custom renderer though like this
public NewJFrame() {
initComponents();
jTable1.getTableHeader().setDefaultRenderer(new DefaultTableCellRenderer() {
#Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
l.setBorder(new LineBorder(Color.black, 1));
l.setBackground(Color.GREEN);
return l;
}
});
}
Also made with GUI Builder
If you are using netbeans then there will be a line in your main() method.
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
Comment this line and then see the result.
I am using this JTable method to create a Cell with a JComboBox as their rendered appearance.
public void addComboBoxToColumn(String[] options, int column_index){
ComboTableCellRenderer renderer = new ComboTableCellRenderer();
JComboBox<String> combo = new JComboBox<String>(options);
TableCellEditor combo_editor = new DefaultCellEditor(combo);
TableColumn column = getColumnModel().getColumn(column_index);
column.setCellRenderer(renderer);
column.setCellEditor(combo_editor);
}
...
public class ComboTableCellRenderer implements ListCellRenderer, TableCellRenderer
{
DefaultListCellRenderer listRenderer = new DefaultListCellRenderer();
DefaultTableCellRenderer tableRenderer = new DefaultTableCellRenderer();
private void configureRenderer(JLabel renderer, Object value)
{
if (value != null)
renderer.setText((String)value);
}
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
{
listRenderer = (DefaultListCellRenderer)listRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
configureRenderer(listRenderer, value);
return listRenderer;
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
tableRenderer = (DefaultTableCellRenderer)tableRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
configureRenderer(tableRenderer, value);
return tableRenderer;
}
}
My problem is that the combobox is always the size of the cell. I do not want that. Is it possible to make the combo box bigger? Some options in the combobox are too big and are half-hidden.
My problem is that the combobox is always the size of the cell. I do
not want that. Is it possible to make the combo box bigger? Some
options in the combobox are too big and are half-hidden.
not possible without jumping of cell Dimmension on the Screen, don't to confuse the user
to avoiding possible side effects, I'd be
create popup undecorated JDialog (for editable JComboBox), JWindow, put there JComboBox
add ListSelectionListener (have to change ListSelectionMode to SINGLE)
change built in KeyBinding in JTable for TableCellEditor (double_click or F2) to showing JDialog/JWindow have to center to the desired Point on the scren, setVisible must be wrapped in invokeLater
add ItemListener, test for SELECTED, on selected to store value to (setValueAt()) XxxTableModel, then to hide JDialog/JWindow
use only one JDialog (reuse by removeAll from content pane for another action from GUI) for whole JVM instance, only one for JTable
Override the JTable.editCellAt. This is the method that positions the table cell editor by calling setBounds on it. Just set the bounds differently in your preferred way, maybe should span over several columns.
In java Swing table, how to split a cell into two, one is TextField, another one is a checkbox. I have done some codes, but doesn't work. thanks
public class CustomTableCellRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int column) {
Component cell = super.getTableCellRendererComponent(table, obj, isSelected, hasFocus, row, column);
JTextField fld = new JTextField();
JCheckBox chx = new JCheckBox();
cell.add(fld); // Doesn't work
cell.add(chx); // Doesn't work
return cell;
}
}
1) in this case you have to define for LayoutManager, because JLabel/JComponent (by default return TableCellRenderer) doesn't implemented any LayoutManager
2) put JPanel nested another JComponents (JPanel has by default FlowLayout) into Cell
3) most confortable will be put JTextField to one Column and Boolean value (returns JCheckBox) to another Column
JComboBox in TableCellEditor remember last selected value among different rows and even different TableModels. For example select a value on one row, then go to another row, start cell editing and JComboBox will have as its current value last select value on the previos row.
How can it fixed?
Set the value in the getTableCellEditorComponent(..) method.
Example:
public static void main(String... args) {
JFrame frame = new JFrame("Test");
JTable table = new JTable(10, 2);
JComboBox box = new JComboBox(new String[] {"A", "B", "C"});
table.setDefaultEditor(Object.class, new DefaultCellEditor(box) {
#Override
public Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected, int row, int column) {
return super.getTableCellEditorComponent(
table,
table.getValueAt(Math.max(row-1, 0), column),
isSelected,
row,
column);
}
});
frame.add(table);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setVisible(true);
}
I'm trying to render an specific row of my jtable (it should have a different background color and it should have bold characters).
I found several questions regarding how to implement a custom TableCellRenderer (here and here) and the tutorial How to Use Tables and this one (Table Row Rendering).
I'm using a JInternalFrame to display the JTable. I tried to implement both solutions but neither getCellRenderer nor prepareRenderer are being called. When debugging, I can see my new jtable being created, but, my breakpoint inside the methods aren't called.
My code looks like:
this.add(createData(model));
private JComponent createData(ProfitLossTableModel model) {
JTable table = new JTable(model) {
public TableCellRenderer getCellRenderer(int row, int column) {
if ((row == 0) && (column == 0)) {
DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
renderer.setHorizontalAlignment(JLabel.RIGHT);
renderer.setBackground(Color.red);
return renderer;
} else {
return super.getCellRenderer(row, column);
}
}
};
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.changeSelection(0, 0, false, false);
table.setAutoCreateRowSorter(true);
return new JScrollPane(table);
}
As you can see, model is my implementation of a AbstractTableModel.
Of course that I'm missing something. I tried to call repaint() to see if something happened, but nothing occurred.
I also tried to put a JPane inside my JInternalFrame and them add the JScrollPane into it, but nothing occurred also.
Any help?
TIA,
Bob
As discussed in Concepts: Editors and Renderers, "the table invokes the table model's getColumnClass method, which gets the data type of the column's cells." You should verify that your implementation of AbstractTableModel returns a suitable value, as suggested in this example.
Addendum:
I'm trying to render a row, not a column.
Rob Camick's Table Row Rendering approach that overrides prepareRenderer() seems apropos.
tabbedPane.addTab("FirstRow", createFirstRow(model));
...
private JComponent createFirstRow(DefaultTableModel model) {
final Font font = new Font("Serif", Font.BOLD, 14);
JTable table = new JTable(model) {
public Component prepareRenderer(
TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
if (!isRowSelected(row)) {
c.setBackground(row == 0 ? Color.yellow: getBackground());
c.setFont(row == 0 ? font : getFont());
}
return c;
}
};
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.changeSelection(1, 1, false, false);
return new JScrollPane(table);
}