how can I add tooltips to JTable's rows (Java Swing)?
These tooltips should contain same values of the relative row.
This is the code I used in my class that extends JTable. It overrides the method "prepareRenderer", but I got empty cells, and it adds a tooltip for each single cell within row, not one tooltip for the whole row (that is what I'm looking for):
public Component prepareRenderer(TableCellRenderer renderer,int row, int col) {
Component comp = super.prepareRenderer(renderer, row, col);
JComponent jcomp = (JComponent)comp;
if (comp == jcomp) {
jcomp.setToolTipText((String)getValueAt(row, col));
}
return comp;
}
it adds a tooltip for each single cell within row, not one tooltip for the whole row
You are changing the tooltip depending on the row and column. If you only want the tooltip to change by row, then I would only check the row value and forget about the column value.
Another way to set the tooltip is to override the getToolTipText(MouseEvent) method of JTable. Then you can use the rowAtPoint(...) method of the table to get the row and then return the appropriate tool tip for the row.
Just use below code while creation of JTable object.
JTable auditTable = new JTable(){
//Implement table cell tool tips.
public String getToolTipText(MouseEvent e) {
String tip = null;
java.awt.Point p = e.getPoint();
int rowIndex = rowAtPoint(p);
int colIndex = columnAtPoint(p);
try {
//comment row, exclude heading
if(rowIndex != 0){
tip = getValueAt(rowIndex, colIndex).toString();
}
} catch (RuntimeException e1) {
//catch null pointer exception if mouse is over an empty line
}
return tip;
}
};
see JComponent.setToolTipText() -- the JComponent you want on per-row data is not the table, but rather the cell renderer of the data, which has access to configuring a JComponent for each rendered cell.
rowIndex can be ZERO.
change:
if(rowIndex != 0){
tip = getValueAt(rowIndex, colIndex).toString();
}
by:
if(rowIndex >= 0){
tip = getValueAt(rowIndex, colIndex).toString();
}
Related
This question already has answers here:
How to get cell value of jtable depending on which row is clicked
(2 answers)
Closed 7 years ago.
When I double click the cell of the JTable, I want it to take the value of that cell and write it in the textfield. What should I do? Here is what I have tried so far, but I don't know where to go from here:
table_1.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
JTable table = (JTable) me.getSource();
Point p = me.getPoint();
int row = table.rowAtPoint(p);
if (me.getClickCount() == 2) {
textfield.settext(???????????);
}
}
});
i understand how it works:
int row = table.rowAtPoint(p);
int column = table.columnAtPoint(p);
textfield.settext(table_1.getValueAt(row, column));
Jtable table = (JTable)e.getsource();
int row = table.getSelectedRow();
int column = table.getSelectedColumn();
ObjectType o = (ObjectType)target.getValueAt(row, column) );
Do this. Will get the value in your JTable based on the row and column selected and then casts the returned value to your object type in the table and returns the value at the row, column. This is inside your Listener.
Shown in similar question Possible Dup?
You can get the value of the table by using:
table.getModel().getValueAt(row, col);
where
row - the row whose value is to be queried
col - the column whose value is to be queried
table - your object name (class jTable)
Note: The column is specified in the table view's display order, and not in the TableModel's column order. This is an important
distinction because as the user rearranges the columns in the table,
the column at a given index in the view will change. Meanwhile the
user's actions never affect the model's column ordering.
In addition, I recommend to read this documentation.
Try to write something like this:
table.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(final MouseEvent e) {
if (e.getClickCount() == 1) {
final JTable jTable= (JTable)e.getSource();
final int row = jTable.getSelectedRow();
final int column = jTable.getSelectedColumn();
final String valueInCell = (String)jTable.getValueAt(row, column);
textfield.setText(valueInCell);
}
});
Well, this is my first post here. But I am little frustrated because I have search everywhere but nothing is working. I have JTable and code works as expected below lines right after if (value.equals("CMAU1294522")) .. however only one cell is show square box. I mouse clicked on a particular row, I want the entire row to show light gray (I think that is standard).
table = new JTable(sorter) {
public Component prepareRenderer(TableCellRenderer renderer, int row, int col) {
Component comp = super.prepareRenderer(renderer, row, col);
Object value = getModel().getValueAt(row, col);
UIManager.put("Table.editRow", new javax.swing.plaf.ColorUIResource(Color.YELLOW));
if(editingRow ==1){
table.setSelectionBackground(Color.red);
}
if (getSelectedRow() == row) {
table.setSelectionBackground(Color.red);
}
if (value.equals("CMAU1294522")) {
comp.setBackground(Color.red);
} else if (value.equals("PNCT")) {
comp.setBackground(Color.green);
} else if (NewJApplet.contReady.containsKey(value)) {
comp.setBackground(Color.CYAN);
} else if (NewJApplet.badCont.containsKey(value)) {
comp.setBackground(Color.red);
} else {
comp.setBackground(Color.white);
}
return comp;
}
Is there any way to do it in prepareRenderer function I already have?
I there any way to do it in PreparRenerere function I already have?
You code to get the "value" is wrong. You always get the value of the current cell being rendered. If you want to highlight the entire row based on a specific value then you need to hardcode the column:
Object value = getModel().getValueAt(row, ???);
Also, it looks like you are sorting the data in the table so you should be using getValueAt(...) instead of getModel().getValueAt(), so you check the data in the sort table, not the data in the unsorted model.
Check out the example code in Table Row Rendering for a working example.
OK, I must be completely brainless but I can't seem to implement the code needed to set (permanently) the background color of the selected (clicked) cell in my JTable. I've read through most of the answers on this site but I'm still not getting it.
I'm using the preparedRenderer() method but I don't understand why it isn't working?
table.addMouseListener(
new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent m) {
row = table.getSelectedRow();
column = table.getSelectedColumn();
}
}
);
table = new JTable(data, columnNames) {
public Component prepareRenderer(TableCellRenderer rend, int r, int k) {
Component g = super.prepareRenderer(rend, row, column);
g.setBackground(Color.BLUE);
return g;
}
};
The way I'm understanding it is that prepareRenderer is taking a specific cell from the table as a Component and then allowing me to change the properties of that Component. But even if I write:
Component g = super.prepareRenderer(rend, 1, 1);
g.setBackground(Color.BLUE);
return g;
it just paints the whole table and not the cell at row=1, column=1???
I'm just not getting it...
it just paints the whole table and not the cell at row=1, column=1???
The prepareRenderer() method is called for every cell that gets repainted. This is done dynamically as the user selects a row or tabs to a new cell or clicks on a cell.
set (permanently) the background color of the selected (clicked) cell in my JTable.
Maybe you can create a Set of Point objects to represent the cells that you want to paint a different color. So when you click on the cell you create a Point object for the row/column and then add the Point to the set.
Then in the prepareRenderer(...) method you create a new Point representing the row/column you are about to renderer. If this Point is found in your Set then you change the background color.
i try to change the color of fields in a JTable according to their value. I don't want to change any color of the first column but it changes anyway in a buggy way(some fileds are not correctly filed like University and Possible_Reviewer):
My code is as following:
table.setDefaultRenderer(Object.class, new CustomRenderer());
private class CustomRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,boolean hasFocus, int row, int col){
Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
try {
Double val = Double.parseDouble(value.toString());
if(col == 0){
comp.setBackground(Color.white);
} else {
comp.setBackground(changeColor(val));
}
} catch (NumberFormatException e){}
return( comp );
}
private Color changeColor(Double val) {
//returns a Color between red and green depending on val
}
}
The weird thing is that when i use "col == 2" it turns the second column white but the first remains strangely colored.
Anyone an idea?
You should extend JTable class and override this method:
public TableCellRenderer getCellRenderer(int row, int column){}
Otherwise JTable will use the same renderer for each cell in the same column.
EDIT:
Like #Mark Bramnik pointed out, it's better to not instantiate a new TableCellRenderer object for every getCellRenderer call. You could implement a method like the following:
setCellRenderer(int row, int col, TableCellRenderer render)
and store the renderer in the extended JTable itself.
How to Use Tables: Using Custom Renderers mentions this alternative approach: "To specify that cells in a particular column should use a renderer, you use the TableColumn method setCellRenderer()."
Addendum: A benefit of this approach is that the renderer "sticks" to the column if the user drags it to a different position. In this example, replace setDefaultRenderer() with setCellRenderer().
table.getColumnModel().getColumn(DATE_COL).setCellRenderer(new DateRenderer());
In a JTable, how can I make some rows automatically increase height to show the complete multiline text inside? This is how it is displayed at the moment:
I do not want to set the height for all rows, but only for the ones which have multiline text.
The only way to know the row height for sure is to render each cell to determine the rendered height. After your table is populated with data you can do:
private void updateRowHeights()
{
for (int row = 0; row < table.getRowCount(); row++)
{
int rowHeight = table.getRowHeight();
for (int column = 0; column < table.getColumnCount(); column++)
{
Component comp = table.prepareRenderer(table.getCellRenderer(row, column), row, column);
rowHeight = Math.max(rowHeight, comp.getPreferredSize().height);
}
table.setRowHeight(row, rowHeight);
}
}
If only the first column can contain multiple line you can optimize the above code for that column only.
Camickr's solution did not work for me at all. My data model was dynamic though - it changed all the time. I guess the mentioned solution works for static data, like coming from an array.
I had JPanel for cell renderer component and it's preferred size wasn't set correctly after using prepareRenderer(...). The size was set correctly after the containing window was already visible and did repaint (2 times in fact after some unspecified, though short time). How could I call updateRowHeights() method shown above then and where would I do this? If I called it in (overriden) Table.paint() it obviously caused infinite repaints. It took me 2 days. Literally. The solution that works for me is this one (this is the cell renderer I used for my column):
public class GlasscubesMessagesTableCellRenderer extends MyJPanelComponent implements TableCellRenderer {
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
//this method updates GUI components of my JPanel based on the model data
updateData(value);
//this sets the component's width to the column width (therwise my JPanel would not properly fill the width - I am not sure if you want this)
setSize(table.getColumnModel().getColumn(column).getWidth(), (int) getPreferredSize().getHeight());
//I used to have revalidate() call here, but it has proven redundant
int height = getHeight();
// the only thing that prevents infinite cell repaints is this
// condition
if (table.getRowHeight(row) != height){
table.setRowHeight(row, height);
}
return this;
}
}
You must iterate over each row, get the bounding box for each element and adjust the height accordingly. There is no code support for this in the standard JTable (see this article for a solution for Java ... 1.3.1 =8*O).