2 Replies Latest reply: Aug 27, 2012 9:17 AM by Jörg RSS

    Realizing a component (JScrollPane) without pack()

    Jörg
      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
          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
            That works great! Thank you very much,Walter.