This discussion is archived
2 Replies Latest reply: Aug 27, 2012 7:17 AM by Jörg RSS

Realizing a component (JScrollPane) without pack()

Jörg Explorer
Currently Being Moderated
Hello,

I am trying to implement Re: JTable column header to span multiple columns for a spanning table header. In this example the scrollPane's header is set AFTER the frame has been realized with pack().
In my application, however, I have several different tables which I would like to be shown by a common dialog, to which I pass the corresponding table containing scrollPane only. Is there a way to get the scrollPane realized before it is displayed? Currently I run into a NullPointerException (at the arrow "-->"). I tried doLayout() and validate() to no avail.
import java.awt.*;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.table.*;
 
public class MultiSpanHeader1 {

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {

         @Override
         public void run() {
            new MultiSpanHeader1().makeUI();
         }
      });
   }
 
   public void makeUI() {
      final JFrame frame = new JFrame("MultiSpanHeader test");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setSize(200, 200);
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
      MyTable myTable= new MyTable();
      JScrollPane scroll= new JScrollPane(myTable);
      JPanel panel = new JPanel(new GridLayout(2, 1));
      panel.add(myTable.dummyHeader);
      panel.add(myTable.getTableHeader());
// -->
      System.out.println(scroll.getColumnHeader()); // null
      scroll.getColumnHeader().setView(panel); // NPE
      new TableDialog(frame, scroll);
   }


   class TableDialog extends JDialog {
     public TableDialog(Frame parent, JScrollPane scroll) {
       super(parent, true);
       setLocationRelativeTo(parent);
       add(scroll);
       setVisible(true);
     }
   }


  class MyTable extends JTable {
    final JTableHeader dummyHeader;

    public MyTable() {
      super(5, 6);
      getTableHeader().setReorderingAllowed(false);
      final TableColumnModel model = getColumnModel();
      Enumeration<TableColumn> enumColumns = model.getColumns();
      final List<TableColumn> columns = Collections.list(enumColumns);
      
      final JTable dummy = new JTable(0, 3);
      dummyHeader= dummy.getTableHeader();
      dummyHeader.setReorderingAllowed(false);
      dummyHeader.setResizingAllowed(false);
      final TableColumnModel dummyModel = dummy.getColumnModel();
      Enumeration<TableColumn> enumDummyColumns = dummyModel.getColumns();
      final List<TableColumn> dummyColumns = Collections.list(enumDummyColumns);
      
      model.addColumnModelListener(new TableColumnModelListener() {
         @Override
         public void columnAdded(TableColumnModelEvent e) {
         }
 
         @Override
         public void columnRemoved(TableColumnModelEvent e) {
         }
 
         @Override
         public void columnMoved(TableColumnModelEvent e) {
         }
 
         @Override
         public void columnMarginChanged(ChangeEvent e) {
            dummyColumns.get(0).setWidth(columns.get(0).getWidth());
            dummyColumns.get(1).setWidth(columns.get(1).getWidth() +
                  columns.get(2).getWidth());
            dummyColumns.get(2).setWidth(columns.get(3).getWidth() +
                  columns.get(4).getWidth() + columns.get(5).getWidth());
         }
 
         @Override
         public void columnSelectionChanged(ListSelectionEvent e) {
         }
      });
    }
  }

}
  • 1. Re: Realizing a component (JScrollPane) without pack()
    800268 Expert
    Currently Being Moderated
    You'll have to override JTable#configureEnclosingScrollPane() to do nothing and use JScrollPane#setColumnHeaderView which auto creates the view port:
    import java.awt.EventQueue;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    
    public class TestTable5 {
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JTable table = new JTable(5, 5) {
                        @Override
                        protected void configureEnclosingScrollPane() {
                            // do nothing, custom table header
                        }
                    };
                    JScrollPane pane = new JScrollPane(table);
                    pane.setColumnHeaderView(new JLabel("Hi!"));
                    JFrame frame = new JFrame("Test");
                    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                    frame.getContentPane().add(pane);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    }
  • 2. Re: Realizing a component (JScrollPane) without pack()
    Jörg Explorer
    Currently Being Moderated
    That works great! Thank you very much,Walter.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points