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*/);
}
}
Related
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);
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.
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);
}
}
});
I have a JXTable with custom table model. I added 2 ColorHighlighter's with custom HighlightPredicate's.
Problem is when i click on the column header, the table sorts the rows, BUT the highlighter's remain as for the old view.
How can I update the state of the highlight after sorting a table?
As #kleopatra mentioned, i looked at my predicate:
HighlightPredicate spakowany = new HighlightPredicate() {
#Override
public boolean isHighlighted(Component renderer, ComponentAdapter adapter) {
TableModel tableModel = table.getModel();
if (tableModel instanceof StanTableModel) {
StanTableModel stanTableModel = (StanTableModel) tableModel;
// int rowIndex = adapter.row; <- this was the issue
int rowIndex = adapter.convertRowIndexToModel(adapter.row);
StanTableRow myCustomRow = stanTableModel.getRow(rowIndex);
if ((myCustomRow.isSpakowany()) {
return true;
}
}
return false;
}
};
and used #mKorbel idea:
was:
int rowIndex = adapter.row;
is now:
int rowIndex = adapter.convertRowIndexToModel(adapter.row);
And it works now.
StanTableModel is my custom table model. It has getRow() function and returns a StanTableRow object which in turn has isSpakowany() function.
I have a JTable and i want a cell (or its row) painted in red when the value entered is higher than a certain value. I'm checking that into a TableModelListener to detect TableChange, so I see no way of colouring the table at the renderer (yet I'm sure it is possible, only it is unknown for me).
I also saw this question but i don't know how to use it.
that job for prepareRendered as you can see here
Following is for single table cell you can extend it for row:
First take table column you want to pint and then add a TableCellRenderer to it as follows:
TableColumnModel columnModel = myTable.getColumnModel();
TableColumn column = columnModel.getColumn(5); // Give column index here
column.setCellRenderer(new MyTableCellRenderer());
Make MyTableCellRendere class which implements TableCellRenderer and extends JLabel(so that we can give a background color to it). It will look something like following:
public class MyTableCellRenderer extends JLabel implements TableCellRenderer {
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int col) {
JLabel jLabel = (JLabel) value;
setBackground(jLabel.getBackground());
setForeground(UIConstants.black);
setText(jLabel.getText());
return this;
}
}
Now in method where you are listening table cell value change do something like follow:
JLabel label = new JLabel(changedValue);
// check for some condition
label.setBackground(Color.red); // set color based on some condition
myTable.setValueAt(label, 0, 5); // here 0 is rowNumber and 5 is colIndex that should be same used to get tableColumn before.