Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

For a JTable using a model class that extends DefaultTableModel how do I allow resizing of JTable columns and get Horizontal Scroll bar?

Posted on 2006-11-09
9
917 Views
Last Modified: 2013-11-23
I am using a class that extends DefaultTableModel for a JTable in a Java Swing GUI.  My code that uses the class is as follows:

       JTable table = new JTable(); //NEW
       sorter = new SortableTableModel(table, columnNames, 0);
       table.setModel(sorter );
       table.setRowSelectionAllowed(false);
       scrollPane = new JScrollPane(table);
       add(scrollPane, BorderLayout.CENTER);

The model class that extends DefaultTableModel is as follows:

import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class SortableTableModel extends DefaultTableModel {
  JTable table;
  JTableHeader header;
  Vector columnNames;
  int selectedHeaderColumn;
  int columnCount;
  int[] minWidth;
  TableCellRenderer[] cellRenderer;
  int clickCount = 0;

  public SortableTableModel( JTable table, String[] columnNames, int rowCount ){
    super( columnNames, rowCount );
    this.table = table;
    header = table.getTableHeader();
    header.setReorderingAllowed(false);
    header.addMouseListener( new HeaderMouseAdapter() );
    this.columnNames = DefaultTableModel.convertToVector( columnNames );
    columnCount = columnNames.length;
    minWidth = new int[ columnCount ];
    cellRenderer = new TableCellRenderer[ columnCount ];
  }

  class HeaderMouseAdapter extends MouseAdapter {
    public void mousePressed( MouseEvent e ){
      Point mousePoint = new Point( e.getX(), e.getY() );
      selectedHeaderColumn = header.columnAtPoint( mousePoint );
      DefaultTableColumnModel cmodel = (DefaultTableColumnModel)table.getColumnModel();
      backupTableColumnAttr( cmodel );

      clickCount++;
      boolean reverseOrder = false;
      if( ( clickCount %2 )==0 ) reverseOrder = true;
      sort( reverseOrder );

      restoreTableColumnAttr( cmodel );
    }
    void backupTableColumnAttr( DefaultTableColumnModel cmodel ){
      for( int i=0 ; i< columnCount ; i++ ){
        TableColumn column = cmodel.getColumn(i);
        minWidth[i] = column.getMinWidth();
        cellRenderer[i] = column.getCellRenderer();
      }
    }
    void restoreTableColumnAttr( DefaultTableColumnModel cmodel ){
      for( int i=0 ; i< columnCount ; i++ ){
        TableColumn column = cmodel.getColumn(i);
        column.setMinWidth( minWidth[i] );
        column.setCellRenderer( cellRenderer[i] );
      }
    }
  }

  void sort( boolean reverseOrder ){
    Vector vec = getDataVector();
    Object[] array = vec.toArray();
    Arrays.sort( array, new Compare( selectedHeaderColumn, reverseOrder ) );
    vec = DefaultTableModel.convertToVector( array );
    setDataVector( vec, columnNames );
  }

  class Compare implements Comparator {
    int sortKey;
    boolean reverseOrder;
    Compare( int sortKey, boolean reverseOrder ){
      this.sortKey = sortKey;
      this.reverseOrder = reverseOrder;
    }
    public int compare( Object o1, Object o2 ){
      Vector v1 = (Vector)o1;
      Vector v2 = (Vector)o2;
      Comparable s1 = (Comparable)v1.get( sortKey );
      Comparable s2 = (Comparable)v2.get( sortKey );
      int ans = s1.compareTo( s2 );
      if( reverseOrder ) ans *= -1;
      return( ans );
    }
    public boolean equals( Object obj ){
      return( false );
    }

  }
}

My JTable columns are not resizable, how do I make them so a user can resize them.  Also I am using a ScrollPane but I don't get a Horizontal Scroll bar when I have many columns in my table.  My columns just get narrower.  How do I keep my columns from getting more narrow when I have more columns and just make my table wider and have a horizontal scroll bar.  

When I use the DefaultTableModel class I don't have either of these problems, but this class provides column sorting which I need.

I looked at a class that provided column sorting that extended the AbstractTableModel class but I need to add and delete individual columns in my code in my JTable and it did not provide that.

Please help!

Dave

0
Comment
Question by:gdkinney_2
  • 6
  • 3
9 Comments
 
LVL 37

Expert Comment

by:zzynx
ID: 17912563
>> My JTable columns are not resizable, how do I make them so a user can resize them

>> How do I keep my columns from getting more narrow when I have more columns and just make my table wider
>> and have a horizontal scroll bar.  
Twice the same answer:

Add this to your code:

  table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
0
 

Author Comment

by:gdkinney_2
ID: 17913787
Hi zzynx
   Thanks I do get the horizontal scroll bar now but users still cannot resize the table columns.  I know when I use the DefaultTableModel directly without extending the class I can resize the columns so my SortableTableModel class which extends DefaultTableModel must be preventing me from doing that.  Any ideas what I need to do to allow users to resize the columns?

Thanks,
Dave
0
 
LVL 37

Expert Comment

by:zzynx
ID: 17913852
Try

table.getTableHeader().setResizingAllowed(true);
0
Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

Author Comment

by:gdkinney_2
ID: 17926195
I changed my code so that I am using a class that extends the AbstractTableModel class now instead of the DefaultTableModel class.  My JTable now allows user resizing of the JTable columns.  

I will have lots of columns of data.  I want my table to get wider and my column widths to NOT get narrow and get a horizontal scroll bar instead.  I am using JScrollPane with my JTable will this happen automatically or do I need to add some code to make it happen?
0
 
LVL 37

Expert Comment

by:zzynx
ID: 17928385
>> I am using JScrollPane with my JTable
>> will this happen automatically
If you put your table into a JScrollPane AND apply
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
then it will be automatically as you want.

>> My JTable now allows user resizing
The fact of using an AbstractTableModel instead of a DefaultTableModel is not the reason of the fact that now you can resize the columns (although that is what you experience at the moment)
Did you try applying

     table.getTableHeader().setResizingAllowed(true);

with the DefaultTableModel?
0
 

Author Comment

by:gdkinney_2
ID: 17935766
zzynx,

I did try table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF).  Right now I don't have a lot of columns in my table like maybe 6 columns.  Soon I will have more columns in my table.  When I have few columns like now and use table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF) my table does not cover the width of the parent container which I want it to do.

 
0
 
LVL 37

Expert Comment

by:zzynx
ID: 17954157
>> When I have few columns like now and use table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF) my table does not >> cover the width of the parent container
That's indeed the result of applying
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF)

>> which I want it to do
Well, then you shouldn't apply
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF)

If you have more columns and don't want them to be squeezed, then do apply
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF)

What more can I say...
0
 
LVL 37

Accepted Solution

by:
zzynx earned 500 total points
ID: 17954163
cf. http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JTable.html

These are your options:
AUTO_RESIZE_ALL_COLUMNS:
          During all resize operations, proportionately resize all columns.
AUTO_RESIZE_LAST_COLUMN:
          During all resize operations, apply adjustments to the last column only.
AUTO_RESIZE_NEXT_COLUMN:
          When a column is adjusted in the UI, adjust the next column the opposite way.
AUTO_RESIZE_OFF:
          Do not adjust column widths automatically; use a scrollbar.
AUTO_RESIZE_SUBSEQUENT_COLUMNS:
          During UI adjustment, change subsequent columns to preserve the total width; this is the default behavior.
0
 
LVL 37

Expert Comment

by:zzynx
ID: 17963303
Thanx 4 axxepting
0

Featured Post

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Viewers learn about the scanner class in this video and are introduced to receiving user input for their programs. Additionally, objects, conditional statements, and loops are used to help reinforce the concepts. Introduce Scanner class: Importing…
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question