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
921 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
[X]
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
  • 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

724 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