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
920 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
Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

 

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

Independent Software Vendors: 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

Suggested Solutions

Title # Comments Views Activity
sql import cannot be resolved jsp 3 113
ejb entity bean example 2 56
import as existing maven project 3 77
JVM error from eclipse 1 25
After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
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:
Suggested Courses

739 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