Show a tooltip above a cell in a JTable - java

I need to show a tooltip above (or below :) a cell when the user enter a wrong value in it (see the image below).
I have a tooltip, but I need a Point to display it at the right position, so I want to get a cell position. Do you know how to get this?
BUT, if you have a better solution to realize this behaviour, I'm open to all proposition (especially for the fact that the tooltip is not bind with the cell/Jtable/Panel and if I move/close/minmize my window the tooltip is display at the same position)
Thanks,
Damien

Please refer below code snippet, and you'll get the solution
JTable table = new JTable() {
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
if (c instanceof JComponent) {
JComponent jc = (JComponent) c;
jc.setToolTipText(getValueAt(row, column).toString());
}
return c;
}
};
If you want to only show the specific cell, all you have to do is change the column param in the params of getValueAt(...) method to a specific column which contains that cell

You have an example of such feature in the Swing components visual guide.
Edit: In fact, it is not really a tooltip that you need here, as the tooltip need to have the cursor positionned over the cell. You want to display the tooltip even if the cursor is outside the cell, right?
Anyway, an alternative solution is to change the background of the cell when the value entered by the user is invalid (in orange or red for example), and then add a "real" tooltip (using the link I provided) in order to give the user a complete error message.

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

Try getCellRect

Use the following code to get the value for the correct row if using RowSorter:
jc.setToolTipText(getValueAt(convertRowIndexToModel(row), column).toString());

Related

jTable not coloring row correctly

i have a problem, basically my program looks like this:
the thing is, it works, it is supposed to color the rows that have "N" in green, but the first time it loads the values, as you can see, the first row have bits of white, but for some reason if i click the list it fixes the issue, i need the rows to be colored properly without the user needing to click on the list to fix the issue, this is my Render code:
public class Render extends JTable {
#Override
public Component prepareRenderer(TableCellRenderer renderer, int rowIndex,
int columnIndex){
Component componente = super.prepareRenderer(renderer, rowIndex, columnIndex);
String val = getValueAt(rowIndex, columnIndex).toString();
if(val.equals("N")){
componente.setBackground(Color.GREEN);
}
return componente;
}
}
I figured i could use Repaint(); in the MouseMoved event in the JTable, but i think is not a proper way to fix it... Any help is appreciated, cheers!
Start by changing
String val = getValueAt(rowIndex, columnIndex).toString();
to
String val = getValueAt(rowIndex, 3).toString();
This will ensure that no matter what column the cell represents, you are checking the appropriate columns value - this is why the leading cells are white
You should also consider providing a default color for when the column values doesn't match
if (val.equals("N")) {
componente.setBackground(Color.GREEN);
} else {
componente.setBackground(getBackground());
}

How to get the currently selected cell's indices in JTable immediately after it is highlighted?

I'm building a spread sheet application. But this is not a question like using table.getSelectedColumn() and table.getSelectedRow() to find the selected cell in a JTable.
In Microsoft Excel, when we navigate through cells using arrow keys, the content in the cells are displayed in the Formula Bar immediately after highlighting the cell. Here, the most important thing is, when a cell is highlighted by the selection as above, the value inside the cell is displayed at the sametime. So my question is, how can we do the same in JTable?
I have tried to do something similar using keyEvent listener, but the problem with that is, when a key event is generated, the next cell is being highlighted but the indices of the previous(which was previously highlighted) is being returned in the getSelectedRow() and getSelectedColumn() methods.
Also i tried the ListSelectionListener. but the same fault exists.
If there's any way to get the selected cell's indices immediately after the new cell is highlighted when navigated using arrow keys, that will work. Also an event should be generated since I want to update the formula bar as in Excel. Can someone help me with this?
Thanks in advance!
You can use this simple trick!
Only have to make two excess jTextfields. (can set to be invisible at the run time)
Try to get an idea from below code segment.
private int r;
private int c;
private String buffer;
private void jTextField1KeyTyped(java.awt.event.KeyEvent evt) {
jTextField2.requestFocus();
buffer = jTextField1.getText();
jTable1.getModel().setValueAt(jTextField1.getText(), r, c);
}
private void jTable1KeyTyped(java.awt.event.KeyEvent evt) {
r = jTable1.getSelectedRow();
c = jTable1.getSelectedColumn();
jTable1.putClientProperty("terminateEditOnFocusLost", true);
jTextField1.requestFocus();
}
private void jTextField1FocusGained(java.awt.event.FocusEvent evt) {
buffer = (String)jTable1.getModel().getValueAt(r, c);
jTextField1.setText(buffer);
jLabel1.setText(buffer);
}
private void jTextField2FocusGained(java.awt.event.FocusEvent evt) {
buffer = jTextField1.getText();
jTable1.getModel().setValueAt(buffer, r, c);
jTextField1.requestFocus();
}

Implement a rename function for a cell in jtable in java

As a beginner,i am creating a jtable with some functionalities like adding and removing contents. I would like to know how to make a rename functionality to my application that on selecting this menu should highlight all the contents of the cell as in an editing mode. Thanks in advance
Continuing from your previous post.... Did you want something like below, when when you hit edit in the context menu, you can edit in some popup window?
→
You pretty much already have to tools for this functionality (in your code). For the new Action, you simply need to show a JOptionPane input dialog with the value of the selected cell. The return input of the JOptionPane will be the value you set back to the table. Something like. Keep in mind though, depending on the type of data, you may want to do some logical parsing or conversion. Below I just take the value as a String.
class EditCellAction extends AbstractAction {
private JTable table;
public EditCellAction(JTable table) {
putValue(NAME, "Edit");
this.table = table;
}
#Override
public void actionPerformed(ActionEvent e) {
int row = table.getSelectedRow();
int col = table.getSelectedColumn();
String newValue = JOptionPane.showInputDialog(table,
"Enter a new value:", table.getValueAt(row, col));
((DefaultTableModel) table.getModel()).setValueAt(
newValue, row, col);
}
}
If you don't want the popup, and just want to programmatically start the cell editing, you can simple use table.editCellAt(row, col) to start the editing, and use the underlying text field of the cell editor to select the field contents. Something like below (tested and works)
#Override
public void actionPerformed(ActionEvent e) {
int row = table.getSelectedRow();
int col = table.getSelectedColumn();
table.editCellAt(row, col);
JTextField field = (JTextField) ((DefaultCellEditor) table
.getCellEditor()).getComponent();
field.requestFocus();
field.setSelectionStart(0);
int endSelection =
(!field.getText().isEmpty()) ? field.getText().length() -1 : 0;
field.setSelectionEnd(endSelection);
}
Keep in mind though, if the cell is editable, the user can just double click the cell to edit it. I guess this adds some more functionality

JTable Cells - Handling Long Text

I have a JTable where one column occasionally has a fair amount of text in it. There are algorithms that we're using to expand the height of each row to the tallest cell. The problem is for long text cells we get "fat" rows.
It looks something like this:
=============================
| Col1 | Col2 | This is some|
| | | very long |
| | | text! |
=============================
I've considered a couple solutions:
Clipping the text and adding a mouse listener to "expand" the clipped text
Clipping the text and adding a tooltip or dialog to show the extra contents
Does anyone know of any libraries that fix this? I'm open to using some other technique...I'm not convinced my solution is the best.
Thanks in advance!
I would just use a tooltip.
You can override the getToolTipText(() method of JTable to do this.
JTable table = new JTable(...)
{
public String getToolTipText( MouseEvent e )
{
int row = rowAtPoint( e.getPoint() );
int column = columnAtPoint( e.getPoint() );
Object value = getValueAt(row, column);
return value == null ? null : value.toString();
}
};
Or if its only for certain columns you can use the renderer to set the tooltip text. See Specifying Tool Tips for Cells.
It took me a while to find out how to display the tooltip on Netbeans but your answer helped so much.
here it is implemented on netbeans GUI Builder...
right click on your Jtable->customize code.
choose "custom creation" where the new "javax.swing.JTable();" code is and before the semi colon ; add the code of the answer below... looks like this:
YourTable = new javax.swing.JTable(){
//add tooltip to display the full cell text when not displayed
public String getToolTipText( MouseEvent e )
{
int row = rowAtPoint( e.getPoint() );
int column = columnAtPoint( e.getPoint() );
Object value = getValueAt(row, column);
return value == null ? null : value.toString();
}
}
;
Adding a mouse motion listener to your JTable, getting the value of where the mouse is at, then adding the long value to a tooltip is an efficient way to easily see the longer table cell value when the mouse is hovered over that row:
JTable yourTable = new JTable(<the data>, <the fields>);
// Add a mouse motion listener to your JTable
yourTable.addMouseMotionListener(new MouseMotionListener() {
#Override
public void mouseDragged(MouseEvent e) {
// do nothing
}
#Override
public void mouseMoved(MouseEvent e) {
// Set the tooltip to an empty string
yourTable.setToolTipText("");
// Get the table cell value where the mouse is located
String value = (String) yourTable.getValueAt(yourTable.rowAtPoint(e.getPoint()),
yourTable.columnAtPoint(e.getPoint()));
// If the length of the value is greater than some number...
if (value.length() > 50) {
// add a tooltip to the JTable that shows the value
yourTable.setToolTipText(value);
}
}
});
See result here: https://i.stack.imgur.com/3LHyc.png

Setting the mouse cursor for a particular JTable cell

I have a JTable with a set of uneditable cells and I want all the cells in a particular column to have a different mouse cursor displayed whilst the mouse is hovering over them.
I am already using a custom renderer and setting the cursor on the renderer component doesn't seem to work (as it does for tooltips).
It does seem to work for editors.
Is this not possible in JTable when your cell is not being edited or am I missing something?
Add a MouseMotionListener to the JTable and then on mouseMoved() determine which column it is using JTable's columnAtPoint() and if it's the particular column you are after, setCursor() on the JTable.
Here is one way of changing the cursor at a particular column in JTable:
if(tblExamHistoryAll.columnAtPoint(evt.getPoint())==5)
{
setCursor(Cursor.HAND_CURSOR);
}
else
{
setCursor(0);
}
I wanted to only change the cursor when the mouse was over the text in the cell. This was my solution:
private JTable table = ...;
#Override
public void mouseMoved(MouseEvent e) {
Point point = e.getPoint();
int column = table.columnAtPoint(point);
int row = table.rowAtPoint(point);
Component component = table.getCellRenderer(row, column).getTableCellRendererComponent(table,
getValueAt(row, column), false, false, row, column);
Dimension size = component.getPreferredSize();
Rectangle rectangle = table.getCellRect(row, column, false);
rectangle.setSize(size);
if (rectangle.contains(point)) {
table.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
return;
}
table.setCursor(Cursor.getDefaultCursor());
}

Categories