I created inventory application, when display transaction list from database I use JTabel inside JScrollPane. Set JScrollPane horizontalScrollBar Policy to AS_NEED and JTable setAutoResize to false and Column width set using TableColumnModel as I need. When Width set manually table width going out of viewport and HorizotalScrollBar activate. But I run program and Use scrollbar to see column outside viewport, text and header text get blur during scroll.
Follow given code an screen shoot of project
SetTableModel using DefaultTableModel
DefaultTableModel dm;
dm = new DefaultTableModel(0, 0){
#Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
String titleCol[] = new String[]{"ID","Invoice No","Date","Account Name","Total Amount","Taxeble Amount","Tax %","Tax Amount","Discount Amount","Grand Total"};
dm.setColumnIdentifiers(titleCol);
table1.setModel(dm);
table1.getTableHeader().setFont(new Font("Tahoma", Font.BOLD, 14));
Set Width of Column using TableColumnModel
table1.getTableHeader().setPreferredSize(new Dimension(table1.getTableHeader().getPreferredSize().width, 35));
TableColumnModel columnModel = table1.getColumnModel();
columnModel.getColumn(0).setMinWidth(50);
columnModel.getColumn(0).setMaxWidth(50);
columnModel.getColumn(1).setMinWidth(85);
columnModel.getColumn(1).setMaxWidth(85);
columnModel.getColumn(2).setMinWidth(100);
columnModel.getColumn(2).setMaxWidth(100);
columnModel.getColumn(3).setMinWidth(250);
columnModel.getColumn(4).setMinWidth(100);
columnModel.getColumn(4).setMaxWidth(100);
columnModel.getColumn(5).setMinWidth(130);
columnModel.getColumn(5).setMaxWidth(130);
columnModel.getColumn(6).setMinWidth(75);
columnModel.getColumn(6).setMaxWidth(75);
columnModel.getColumn(7).setMinWidth(130);
columnModel.getColumn(7).setMaxWidth(130);
columnModel.getColumn(8).setMinWidth(130);
columnModel.getColumn(8).setMaxWidth(130);
columnModel.getColumn(9).setMinWidth(130);
columnModel.getColumn(9).setMaxWidth(130);
Screenshot of Before using Horizotal ScrollBar
Screenshot of After using Horizotal ScrollBar
So Is there any solution to avoid blur.
Your problem in next line:
table1.getTableHeader().setPreferredSize(new Dimension(table1.getTableHeader().getPreferredSize().width, 35));
Set height of your header with help of TableCellRenderer, for example:
DefaultTableCellRenderer defaultRenderer = (DefaultTableCellRenderer) table.getTableHeader().getDefaultRenderer();
defaultRenderer.setPreferredSize(new Dimension(0,35));
Related
I have a tablePanel which is a JScrollPane,and initialized with a JTable, the JTable initialized with a defaultTableModel.When I trying to add some rows to the table, but didn't see the scroll bar, appriciated for any reply.
JFrame jFrame = new JFrame();
//rows will be added dynamically.
DefaultTableModel defautTableModel = new DefaultTableModel(null,columnNames){
#Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
JTable jTable = new JTable(defautTableModel);
jTable.setLocation(20,60);
jTable.setSize(950,450);
jTable.setRowHeight(25);
jTable.getColumn("No.").setMaxWidth(45);
jTable.getColumn("position").setMaxWidth(45);
...
JTableHeader jTableHeader = jTable.getTableHeader();
jTableHeader.setLocation(20,30);
jTableHeader.setSize(950,30);
jTableHeader.setFont(new Font(null, Font.BOLD, 16));
jTableHeader.setResizingAllowed(true);
jTableHeader.setReorderingAllowed(true);
JScrollPane tablePanel = new JScrollPane(jTable);
tablePanel.setLayout(null);
tablePanel.add(jTableHeader);
tablePanel.add(jTable);
jFrame.setContentPane(tablePanel);
tablePanel.setLayout(null); is the primary cause of your problem. A JScrollPane has its own layout manager which is used to manage the scrollbars, view port and headers.
tablePanel.add is your next problem, as you shouldn't be adding components to the JScrollPane. Instead, you should be setting the JScrollPane's JViewPort.
But, since you're using JScrollPane tablePanel = new JScrollPane(jTable);, there's actually no need for the three lines which follow it.
I would highly recommend that you take a closer look at:
How to us tables
How to use scroll panes
Laying Out Components Within a Container
Now, before you tell me how nothing I've suggested actually works, go and re-read Laying Out Components Within a Container - this is the corner stone concept you will need to understand and master before Swing really begins to work for you
JScrollPane tablePanel = new JScrollPane(jTable);
// No need for the below code
/*tablePanel.setLayout(null);
tablePanel.add(jTableHeader);
tablePanel.add(jTable);*/
jFrame.setContentPane(tablePanel);
I am working with swing JTable and have a trouble with repainting table. I draw a JTable with thr following code
Object[] column = new Object[]{"Entity", "Attribute"};
Object[][] rowData = new Object[][]{{"E1", "A1"},{"E2", "A2"}};
TableCellRenderer cellRenderer = new TableCellRenderer();
JTable table = new JTable(new DefaultTableModel(rowData, column));
table.setCellSelectionEnabled(true);
table.getColumnModel().getColumn(0).setCellRenderer(cellRenderer);
Below is my table renderer code ..
public class TableCellRenderer implements javax.swing.table.TableCellRenderer {
//private JPanel panel;
JTextField field;
private JTable table;
#Override
public Component getTableCellRendererComponent(final JTable table, final Object value,
boolean isSelected, boolean hasFocus, final int row, final int column) {
this.table = table;
//JTextField field = null;
System.out.println("Rendere : Row : " + row + "Column : " + column);
final JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
JButton button = new JButton("?");
button.setPreferredSize(new Dimension(20, panel.getHeight()));
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
new SelectionDialog(panel, table, value, row, column);
}
});
if(table.getValueAt(row, column) != null){
field = new JTextField(table.getValueAt(row, column).toString());
}else{
field = new JTextField(table.getValueAt(row, column).toString());
}
field.setPreferredSize(new Dimension(30, panel.getHeight()));
panel.add(field, BorderLayout.WEST);
panel.add(button, BorderLayout.EAST);
return panel;
}
this is how i am updating contents of a cell in table..
SelectionDialog.this.table.getModel().setValueAt("E7", 0, 0);
I am updating the table model data via the SelectionDialog for e.g change data at row 0, colum 0 to E7 etc. After changing data in table model i have tried the following options but none of them has refreshed the table data in view however the data in model of JTable was updated correctly. If I add a new row on the fly and then call the below methods then every thing work fine but if I modify data in the model of an existing row then none of the solution mentioned below is working
//((DefaultTableModel)SelectionDialog.this.table.getModel()).addRow(new Object[]{"E3", "A3"});
//((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableCellUpdated(SelectionDialog.this.row, SelectionDialog.this.column);
//((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableChanged(new TableModelEvent(SelectionDialog.this.table.getModel()));
//((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableStructureChanged();
//SelectionDialog.this.table.repaint();
// SelectionDialog.this.table.revalidate();
Please provide any insights about the problem as I am to swing and may have missed some very prominent things.
Edit 1: Just adding one more note which i wanted to place earlier but don't know how i missed. Table is not updated in general but if i focus out from the cell in which change was made or i change the size of table then it immediately change the contents of that particular cell to fresh selected value.
Problem Solved:
I am placing my findings for someone who is facing similar problem.
I rendered a button and a text box inside each cell in my table. When button was clicked (Editor code is not provided as it looks irrelevant to me to place here) a dialog appear which inputs value from user and update the specific column and row.
The lines i mentioned as not working at the end of my post (before edit 1) were working correctly however renderer was not executing unless i manually focus out from the selected cell (whose button was clicked) or manually change the size of jtable which make sense as button was inside editor and button click shows that cell is edited and off-course renderer will not execute unless editing is finished which requires focus out or enter key etc.
I applied the following code as
table.editCellAt(-1, -1);
It focus out from the edited cell (edited with the button) and hence renderer executes and work as expected.
When you are using a DefaultTableModel and you want to update a certain value, you need to use the DefaultTableModel#setValueAt method.
Calling this method (on the Event Dispatch Thread of course) will update your model and fire the necessary events. Those events will cause your JTable to update itself.
A few additional remarks about your renderer:
Creating new components in each call of your renderer is not the way to go. This becomes incredibly slow for large tables. Create all components once in the constructor of your renderer, and just update their state
Adding a JButton to your table in the renderer has no effect, unless you have an editor as well. The button will not be clickable, and the action listener you attach to it will never be called. See the renderers and editors section in the JTable tutorial for more information.
There should be no need to call getValueAt in your renderer. The value is passed in as one of the arguments
Like the title says, is there a simple way to change the width of the gridlines in JTable?
I found out, that there is a simple way to change the color of the showed gridlines in the Jtable but I could not find any methods to change the gridline width.
One of the ways is to override the prepareRenderer(...) method of JTable class, using BorderFactory to create custom border:
JTable table = new JTable( model ) {
public Component prepareRenderer( TableCellRenderer renderer, int row, int column) {
JComponent jc = (JComponent)super.prepareRenderer(renderer, row, column);
jc.setBorder(BorderFactory.createLineBorder(Color.BLACK, 3));
return jc;
}
};
I have a JTable in a JScrollPane. If the screen shows half of a row in the JTable, when clicking on the JTable, the JScrollPane scrolls automatically to show the entire row.
How do I stop that behavior, such that a click will not scroll the JScrollPane.
Thanks!
The behavior is enforced by calling scrollRectToVisible() from the table's UI delegate, typically derived from BasicTableUI. Short of supplying your own delegate, you can use setPreferredScrollableViewportSize() to make the height of enclosing Container an intergral multiple of the rowHeight, as shown below and in this example.
private static final int N_ROWS = 8;
private JTable table = new JTable();
...
Dimension d = new Dimension(
table.getPreferredScrollableViewportSize().width,
N_ROWS * table.getRowHeight());
table.setPreferredScrollableViewportSize(d);
add(new JScrollPane(table));
I am quiet new to Swing. I have a JTable in which images are displayed in each cell. I need to create a RED border only around the cell which is currently selected. To do this I used following renderer class:
public class ImageRenderer extends DefaultTableCellRenderer {
JLabel lbl=new JLabel();
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column )
{
lbl.setIcon((ImageIcon)value);
if(isSelected && hasFocus)
{
lbl.setBorder(BorderFactory.createEtchedBorder(Color.RED, Color.yellow));
}
return lbl;
}
}
The problem I am facing is that when I click on any cell in the JTable then instead of that particular cell the border is displayed for all the cells of the given column. I only need the border around the selected cell and not around all the cells present in that particular column.
Did you try to unset the border if the cell is not selected?
if(isSelected && hasFocus)
{
lbl.setBorder(BorderFactory.createEtchedBorder(Color.RED, Color.yellow));
}else{
lbl.setBorder( BorderFactory.createEmptyBorder() );
}