Set tooltip for cells in jTable without overriding getToolTipText() - java

I am making gui with the NetBeans GUI Builder(Swing) and need to set different tooltips for each cells in the header. The problem is that jTable is generated automatically, so I can't override its methods.
Is there any possibility to do it without the overriding getToolTipText()?

One way to do this sort of thing is to add a subclass which extends the MouseMotionAdapter and a method to your code to carry out the task for you. Simply place the following SubClass code below the end of your main Class.
class JTableColumnHeaderToolTips extends MouseMotionAdapter {
TableColumn curCol;
// Create a Map to hold the Header Column
// index value and the tooltip related to
// it.
Map headerColumnTips = new HashMap();
// Method to Set tips into Map.
public void setHeaderColumnToolTip(TableColumn column, String tooltip) {
if (tooltip == null) {
headerColumnTips.remove(column);
}
else {
headerColumnTips.put(column, tooltip);
}
}
// Override the Header's mouseMoved event so as
// to display the appropriate tooltip for whatever
// column the mouse pointer is currently on.
#Override
public void mouseMoved(MouseEvent event) {
JTableHeader header = (JTableHeader) event.getSource();
JTable table = header.getTable();
TableColumnModel colModel = table.getColumnModel();
int colIndex = colModel.getColumnIndexAtX(event.getX());
TableColumn column = null;
if (colIndex >= 0) {
column = colModel.getColumn(colIndex);
}
if (column != curCol) {
header.setToolTipText((String) headerColumnTips.get(column));
curCol = column;
}
}
}
Then add this method setJTableColumnToolTips() somewhere within your main Class:
private void SetJTableHeaderColumnToolTips(JTable table, String[] columnToolTips) {
JTableHeader tableHeader = table.getTableHeader();
// See the JTableColumnHeaderToolTips SubClass.
JTableColumnHeaderToolTips toolTips = new JTableColumnHeaderToolTips();
for (int col = 0; col < table.getColumnCount(); col++) {
TableColumn columnIndex = table.getColumnModel().getColumn(col);
toolTips.setHeaderColumnToolTip(columnIndex, columnToolTips[col]);
}
tableHeader.addMouseMotionListener(toolTips);
}
To use this method you might do it this way:
// Provide the Tooltips you want for
// each column within a String Array.
String[] columnToolTips = {"First Name",
"Last Name",
"The person's address",
"The person's phone number",
"The person's age",
"The person's salary"};
// Set your desired ToolTips to the Header Column cells
setJTableHeaderColumnToolTips(recordsTable, columnToolTips);

Related

How to add MouseListener to a table model

I have a JTable. When a user clicks on a cell another JTable is created that shows the data for the whole row of that cell, in a column format (ie the row is converted to a column).
This happens when the user clicks but its a bit irritating to happen every time so I want to make it only on a double click.
The problem is that the getSelection method of the table only takes a addListSelectionListener method and not a MouseListener. How can I do what I want?
Here is the code:
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
int selectedRow = table.getSelectedRow();
DefaultTableModel newModel = new DefaultTableModel();
String rowName = "Row: " + selectedRow;
newModel.setColumnIdentifiers(new Object[]{rowName});
for (int i = 0; i < table.getModel().getColumnCount(); i++) {
newModel.addRow(new Object[]{table.getModel().getValueAt(selectedRow, i)});
}
JTable newTable = new JTable(newModel) {
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(140, 240);
}
};
// Apply any custom renderers and editors
JOptionPane.showMessageDialog(frame, new JScrollPane(newTable),
rowName, JOptionPane.PLAIN_MESSAGE);
}
}
});
This happens when the user clicks but its a bit irritating to happen every time so I want to make it only on a double click
You use a MouseListener, not a ListSelectionListener. You would check the Mouse event for a click count of 2.
Read the section from the Swing tutorial on How to Write a MouseLister for more information and working examples.
Also, a double click will start the editor by default so you want to make sure the cell is not editable. So you may need to override the isCellEditable(...) method of the table.

How to select a column of a JTable in JDialog by selecting a header

What I've been trying to do with a JDialog are...
To select a column of JTable by clicking the header
To check which column is selected by the user
To get the value of the cells inside the column
According to this post and this page , it would be possible to select a column by clicking the header, by setting a JTableHeader.
However, neither of them seem to be applicable to what I'm trying to do.
First of all, I'm not sure where to put JTableHeader. The examples above seem to have put it for the initialization, but I don't see any appropriate space to do this in my coding.
At least I know that the second example is JPanel. So, in order to have a JTableHeader in JDialog, JTableHeader will need to be set in a completely different position, since initComponents() of JDialog cannot be modified manually by default.
In addition, I cannot find how to select a header (unlike individual cells). I assume that I need to set a JTableHeader beforehand.
Finally, I don't see any method to detect which column is selected. At least I found jTable.getValueAt(int, int) method, but this method seems to be made to get a single cell.
Now I suspect that it might be impossible to do them with JTable and JDialog. I'd appreciate if you'd give any insight.
I add a part of initComponents() so that you'd easily understand it.
private void initComponents() {
//here are irrelevant codes
jTable1 = new javax.swing.JTable();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
jLabel1.setFont(new java.awt.Font("MS UI Gothic", 3, 18)); // NOI18N
jLabel1.setText("Choose level(s) or unit(s)");
//irrelevant codes
jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{"EN6", "EN3", "EN5", "IN1"},
{"EN2", "EN3", null, "IN4"},
{null, null, null, "IN1"},
{null, null, null, "IN2"},
new String [] {
"EN2", "EN3", "EN5", "IN1"
}
) {
Class[] types = new Class [] {
java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
});
//lots of lines, seem to be irrelevant
pack();
}
"[...]it would be possible to select a column by clicking the header, by setting a JTableHeader."
Based on your requirements I don't think you need to provide your own table header but attach a MouseListener to the default one instead. This way and using both rows and columns selection models you can easily achieve your goal.
Snippet
final JTable table = new JTable(tableModel);
table.setColumnSelectionAllowed(true);
table.getTableHeader().addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
// Get the right column based on MouseEvent#getPoint()
int columnIndex = table.columnAtPoint(e.getPoint());
// Set this column as the selected one in the columns selection model
table.getColumnModel().getSelectionModel().setSelectionInterval(columnIndex, columnIndex);
// Set all the rows as the selected ones in the rows selection model
table.getSelectionModel().setSelectionInterval(0, table.getRowCount() - 1);
// Print the values in selected column
for (int rowIndex = 0; rowIndex < table.getRowCount(); rowIndex++) {
System.out.println(table.getValueAt(rowIndex, columnIndex));
}
}
});
Note: don't forget to allow columns selection.
See:
MouseEvent#getPoint()
JTable#columnAtPoint(Point p)
JTable#rowAtPoint(Point p)
How to Use Tables: User Selections
You can get the select cell's value using this. But is that right you want?
table.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
if (arg0.getClickCount() == 1) { // 1 : one click, 2 : double click, 3 : right click
int column = table.getSelectedColumn();
int row = table.getSelectedRow();
String str = (String) table.getValueAt(row, column);
int[] rows = table.getSelectedRows();
String str2 = (String) table.getValueAt(rows[0], column);
}
}
});

dynamically changing the width of the column in jtable with Netbeans IDE

Developing an application in netbeans and java swing
I want to change the width of my columns in a jtable
to adjust to the length of data in the cell
aftr a google search i stumble upon Binklye's blog
on the following link
http://binkley.blogspot.com/2006/01/getting-jtable-columns-widths-to-fit.html
below are code snippets
{
final TableCellRenderer renderer = getTableHeader()
.getDefaultRenderer();
for (int i = 0; i < getColumnCount(); ++i)
getColumnModel().getColumn(i).setPreferredWidth(
renderer.getTableCellRendererComponent(this,
getModel().getColumnName(i), false, false, 0, i)
.getPreferredSize().width);
}
public Component prepareRenderer(final TableCellRenderer renderer,
final int row, final int column) {
final Component prepareRenderer = super
.prepareRenderer(renderer, row, column);
final TableColumn tableColumn = getColumnModel().getColumn(column);
tableColumn.setPreferredWidth(max(
prepareRenderer.getPreferredSize().width,
tableColumn.getPreferredWidth()));
return prepareRenderer;
}
will love to have someone help with the implementation of the codes.
On the other hand if there is another soution , will be glad to have a look at it.
Check out Table Column Adjuster.
Try this one:
jtable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
You can write your own custom method which will be fired when you add row or delete it.
Sample code:
public static void resizeRow(JTable table) {
TableColumnModel columnModel = table.getColumnModel();
for (int i = 0; i < columnModel.getColumnCount(); i++) {
TableColumn column = columnModel.getColumn(i);
column.setPreferredWidth(/*your logic of setting width*/);
}
}

How to set and get the cell value of JavaFX Table like swing JTable

I am new to JavaFX and would like to know how to set and get the cell value of JavaFX Table like Swing JTable. i.e. an alternative of setValueAt() & getValueAt of Swing JTable in JavaFX Table.
//would like to get the index of column by Name
int index_RunnableQueueItem = tableQueue.getColumns().indexOf("RunnableQueueItem");
//would like to get the selected row
int row = tableQueue.getSelectionModel().getSelectedIndex();
if (index_RunnableQueueItem != -1 && row != -1) {
// would like to get the value at index of row and column.
//Update that value and set back to cell.
}
TableView really doesn't support this methodology.
Here's a somewhat brittle means of doing what you want, using reflection. It's entirely dependent upon you using PropertyValueFactory in your cell value factory so it can lookup the property name, though.
class MyItem
{
SimpleStringProperty nameProperty = new SimpleStringProperty("name");
public MyItem(String name) {
nameProperty.set(name);
}
public String getName() { return nameProperty.get(); }
public void setName(String name) { nameProperty.set(name); }
public SimpleStringProperty getNameProperty() { return nameProperty; }
}
...
TableView<MyItem> t = new TableView<MyItem>();
TableColumn col = new TableColumn("Name Header");
col.setCellValueFactory(new PropertyValueFactory<MyItem, String>("name"));
t.getColumns().addAll(t);
...
public void setValue(int row, int col, Object val)
{
final MyItem selectedRow = t.getItems().get(row);
final TableColumn<MyItem,?> selectedColumn = t.getColumns().get(col);
// Lookup the propery name for this column
final String propertyName = ((PropertyValueFactory)selectedColumn.getCellValueFactory()).getProperty();
try
{
// Use reflection to get the property
final Field f = MyItem.class.getField(propertyName);
final Object o = f.get(selectedRow);
// Modify the value based on the type of property
if (o instanceof SimpleStringProperty)
{
((SimpleStringProperty)o).setValue(val.toString());
}
else if (o instanceof SimpleIntegerProperty)
{
...
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
Retrieving a simple value from a JavaFx TableView Cell
You can use listeners as listed in other posts, but if you wish to get just a simple value from a cell you can use a simpler method
Example:
// Get the row index where your value is stored
int rowIndex = tableView.getSelectionModel().getSelectedIndex();
// Since you can't get the value directly from the table like the
// getValueAt method in JTable, you need to retrieve the entire row in
// FXCollections ObservableList object
ObservableList rowList =
(ObservableList) tableViewModelos.getItems().get(rowIndex);
// Now you have an ObservableList object where you can retrieve any value
// you have stored using the columnIndex you now your value is, starting
// indexes at 0;
// In my case, I want to retrieve the first value corresponding to the first column //index, and I know it is an Integer Value so I'll cast the object.
int columnIndex = 0;
int value = Integer.parseInt(rowList.get(columnIndex).toString());
Hope this expample helps you.

JTable row totals color coded label

I have 5 JTables on different forms with arbitrary numbers of rows and I would like to have a label for each one that will show me the total number of rows in that table and also change color for 3 seconds when the row count changes. The color should go green if incrementing and red if decrementing. What would be the best way to implement this such that I do not need to duplicate too much code in each of my forms?
basically, you add a TableModelListener to the JTable's model and on receiving change events, update the corresponding labels as appropriate
some code:
public class TableModelRowStorage
// extends AbstractBean // this is a bean convenience lass of several binding frameworks
// but simple to implement directly
implements TableModelListener {
private int rowCount;
public TableModelRowStorage(TableModel model) {
model.addTableModelListener(this);
this.rowCount = model.getRowCount();
}
#Override
public void tableChanged(TableModelEvent e) {
if (((TableModel) e.getSource()).getRowCount() != rowCount) {
int old = rowCount;
rowCount = ((TableModel) e.getSource()).getRowCount();
doStuff(old, rowCount);
}
}
protected void doStuff(int oldRowCount, int newRowCount) {
// here goes what you want to do - all in pseudo-code
// either directly configuring a label/start timer
label.setText("RowCount: " + newRowCount);
label.setForeground(newRowCount - oldRowCount > 0 ? Color.GREEN : Color.RED);
timer.start();
// or indirectly by firing a propertyChange
firePropertyChange("rowCount", oldRowCount, newRowCount);
}
}

Categories