Results 1 to 4 of 4
  1. #1
    bronai is offline Member
    Join Date
    Jan 2009
    Posts
    3
    Rep Power
    0

    Default [SOLVED] JTable in JScrollPane renders partly invisible

    I have a JTable added to a JScrollPane with the auto resize mode of the table set to AUTO_RESIZE_OFF. This allows me to specify the widths of the columns to always be larger than the widest rendered component in a column. i.e. I want all data in a cell always visible. It also enables the table to be larger than the JScrollPane viewport size and the JScrollPane will display scroll bars as necessary.

    PrintJobTable table = new PrintJobTable(model); //class extends JTable
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    JscrollPane scrollPane = new JScrollPane(table);
    table.initColumnSizes(); //sets column widths appropriately so all data is seen

    This all works fine when application is launched. However, after a user
    enters data into a cell, I resize the column width appropriatly so all data can be seen using the following setColumnWidth(int col) method.

    The method sets the column width of the specified column to be larger than (with a margin either side) the widest object in the column including all cells and header.

    This method is called after data is changed in the column. The width of the column is updated fine. However if the the width of the column has increased from what it was originally, the overall table size has also increased and the region of the table at the right hand most side which exceeds the original table size appears invisible. I am not sure if this is a problem with the JTable or JScrollPane rendering and what methods I can call to fix the problem. After setting the column I have tried things like....
    table.doLayout();
    table.revalidate();
    table.repaint();
    scrollPane.revalidate();
    scrollPane.doLayout();
    etc.
    but none of them do anything, and I am blundering in the dark.

    public void setColumnWidth(int col)
    {

    //The margin to place either side of the component in a cell
    int margin = 20;

    //Get the column and make it non resiable by the user
    TableColumn column = getColumnModel().getColumn(col);
    column.setResizable(false);

    //Set the width to be the header width of this column
    TableCellRenderer headerRenderer = getTableHeader().getDefaultRenderer();
    Component comp = headerRenderer.getTableCellRendererComponent(
    this, column.getHeaderValue(),
    false, false, 0, 0);
    int width = comp.getPreferredSize().width;

    //Set the width to be the larger of the header or a cell width in this column
    for (int i=0; i<this.getRowCount(); i++)
    {
    TableCellRenderer renderer = this.getCellRenderer(i, col);
    Component c = renderer.getTableCellRendererComponent(this, getValueAt(i, col), false, false, i, col);
    width = Math.max(width, c.getPreferredSize().width);
    }

    //Usethe width of the largest component (header or cell) plus a margin on other side.
    column.setPreferredWidth(width + 2 * margin);
    column.setMinWidth(width + 2 * margin);
    column.setMaxWidth(width + 2 * margin);

    }

  2. #2
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    8

    Default

    Good one. I'm adding a post just to see what someone who knows something says...

  3. #3
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,458
    Rep Power
    20

    Default

    I think you're making this more complicated than it needs to be. Try this for size.

    Note that if your design otherwise requires a custom renderer, you can code similarly within your implementation of getTableCellRendererComponent. If using multiple renderers for different classes, keeping it within a prepareRenderer override is better, as it will affect all renderers.

    Java Code:
    import java.awt.Component;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.SwingUtilities;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.table.TableColumn;
    
    public class SpringTable {
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             
             @Override
             public void run() {
                new SpringTable().makeUI();
             }
          });
       }
    
       public void makeUI() {
          Object[][] data = new Object[3][3];
          Object[] columnHeaders = new Object[3];
          String str = "data ";
          StringBuffer part = new StringBuffer(str);
    
          for (int i = 0; i < data.length; i++) {
             columnHeaders[i] = "Column " + i;
             for (int j = 0; j < data[i].length; j++) {
                part.append(str);
                data[i][j] = part.toString();
             }
          }
          JTable table = new JTable(data, columnHeaders) {
    
             @Override
             public Component prepareRenderer(TableCellRenderer renderer, int row,
                     int column) {
                Component component = super.prepareRenderer(renderer, row, column);
                int rendererWidth = component.getPreferredSize().width;
                TableColumn tableColumn = getColumnModel().getColumn(column);
                tableColumn.setPreferredWidth(Math.max(rendererWidth +
                        getIntercellSpacing().width,
                        tableColumn.getPreferredWidth()));
                return  component;
             }
             
          };
          table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
          
          
          JFrame frame = new JFrame("");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.setSize(600, 200);
          frame.setLocationRelativeTo(null);
          frame.add(new JScrollPane(table));
          frame.setVisible(true);
       }
    }
    Also note that this approach will not allow you to resize the column smaller than its widest content.

    db

  4. #4
    bronai is offline Member
    Join Date
    Jan 2009
    Posts
    3
    Rep Power
    0

    Default Thanks

    Thank you for your solution. It works really well. I do have a bad habit of making things more complicated than necessary.

Similar Threads

  1. Replies: 2
    Last Post: 04-14-2009, 11:01 PM
  2. Replies: 2
    Last Post: 05-15-2008, 11:15 AM
  3. Returning a string (Partly Bold)
    By TampaTechGuy in forum New To Java
    Replies: 3
    Last Post: 02-03-2008, 10:54 AM
  4. How to make the JTextArea background invisible
    By bradder in forum AWT / Swing
    Replies: 1
    Last Post: 12-05-2007, 07:30 PM
  5. help with JScrollPane
    By tommy in forum AWT / Swing
    Replies: 1
    Last Post: 08-06-2007, 08:58 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •