Announcement Announcement Module
Collapse
No announcement yet.
Customizable, persisted column order and selection. Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Customizable, persisted column order and selection.

    I am looking to give the user the ability to select which columns and the order of for any given table in my application, like MS Money. Has anyone seen this implemented?

  • #2
    My solution...

    Since I hear nothing... I had to implement this myself

    I built it on top of glazedlists with very little effort. If anyone is interested in the details I will take the time to post the information.
    Last edited by mlavwilson2; Mar 7th, 2006, 08:48 AM.

    Comment


    • #3
      SwingX's Table did this like Thunderbird has it. I hope glazedlists supports it soon (if it doesn't already in the latest version).

      Comment


      • #4
        In the meantime, if mlavwilson2's implementation is generic enough, I'd delighted to give it a go and report.

        Thanks!

        Benoit

        Comment


        • #5
          Source for Customizable, persisted colom order and selection...

          I have attached the source for review. It does lack 18n, and the wizard for selecting columns is not elegant, neither of which are high on my list

          Please post any comments/changes...

          Create an instance of TableFormatManager by extending AbstractTableFormatManager.
          Code:
          public class TableFormatManagerImpl extends AbstractTableFormatManager
          {
             public void registerTables()
             {
                //register all the columns available for the News.class
                addTableInfo(new TableInfo(News.class));
                addTableInfoColumn(new ColumnInfo("news.", getMessageSource(), "news", News.class, null, false, 0, 0, 0));
                addTableInfoColumn(new ColumnInfo("news.", getMessageSource(), "syndEntry.link", String.class, null, false, 0, 0, 0));
                addTableInfoColumn(new ColumnInfo("news.", getMessageSource(), "syndEntry.author", String.class, null, false, 0, 0, 0));
                addTableInfoColumn(new ColumnInfo("news.", getMessageSource(), "syndEntry.publishedDate", Date.class, null, false, 0, 75, 75));
             }
          
             public void registerDefaults(Settings settings)
             {
                //register the default columns for the "news" table.
                settings.setDefaultString(TableFormatKeys.COLUMNS("news"), "news,syndEntry.publishedDate");
             }
          }
          Wire up a "tableFormatManager" in spring, also add entries in your resource bundle (don't forget the init-method):
          Code:
          <bean id="tableFormatManager" class="net.mlw.lm.rc.TableFormatManagerImpl" singleton="true" init-method="init">
              <property name="messageSource"><ref bean="messageSource"/></property>
              <property name="settingsManager"><ref bean="settingsManager"/></property>
            </bean>
          Now create the view:
          Code:
          //Create the utility to manage the columns.
          TableCustomizer tableCustomizer = new TableCustomizer(News.class, "news");
          //Get the TableFormat with the last saved config, or the default.
          TableFormat tf = tableCustomizer.getTableFormat();
          ...
          //Do you glazed list magic!
          BasicEventList eventList = new BasicEventList();
          ...  sort, filter ...
          EventTableModel eventTableModel = new EventTableModel(eventList, tf);
          JTable table = new JTable(eventTableModel);
          
          //Register the table back to the utility so that the table will be updated.
          tableCustomizer.addTable(table);
          
          JScrollPane scroller = new JScrollPane(table);
          //Add a customize table button to the scroll pane.  This could go anywhere.
          scroller.setCorner(JScrollPane.UPPER_RIGHT_CORNER, tableCustomizer.getButton());
          scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
          ...
          That should do it
          Last edited by mlavwilson2; Mar 12th, 2006, 09:44 PM.

          Comment


          • #6
            Thanks for this.
            I shall have a go tomorrow and report.

            In the meantime, could you provide a bit more info for the relationship between your News Class and the string used:
            Code:
               ColumnInfo("news.", getMessageSource(), "news", News.class, null, false, 0, 0, 0));
            
            ...
               settings.setDefaultString(TableFormatKeys.COLUMNS("news"), "news,syndEntry.publishedDate");
            are syndEntry.xxxx attributes of "News"?

            Why do you have a "news", News.class ColumnInfo? and then what looks like a list of ColumnInfo for the attributes of News.

            Any reason why you could not use the Spring BeanWrapper class rather than beanutils from Apache Common? (it is a new dependency for me).

            Thanks

            Benoit
            Last edited by benoitx; Mar 12th, 2006, 02:12 PM.

            Comment


            • #7
              A little doc to make up for NO javadoc...

              Originally posted by benoitx
              Thanks for this.
              I shall have a go tomorrow and report.

              In the meantime, could you provide a bit more info for the relationship between your News Class and the string used:
              Code:
                 ColumnInfo("news.", getMessageSource(), "news", News.class, null, false, 0, 0, 0));
              
              ...
                 settings.setDefaultString(TableFormatKeys.COLUMNS("news"), "news,syndEntry.publishedDate");
              The "news" is the key used to C.R.U.D. the selected columns. There could be many of these refering to a single News.class in the confiuration.
              The "news. is a prefix used as the key to a resource bundle.
              The News.class defines the columns/properties for the given type. There can be only one of these.

              Originally posted by benoitx
              are syndEntry.xxxx attributes of "News"?
              Yes.
              Originally posted by benoitx
              Why do you have a "news", News.class ColumnInfo? and then what looks like a list of ColumnInfo for the attributes of News.

              Any reason why you could not use the Spring BeanWrapper class rather than beanutils from Apache Common? (it is a new dependency for me).

              Thanks

              Benoit
              the
              ColumnInfo("news.", getMessageSource(), "news", News.class, null, fal...
              example above is confusing because the News.class actually has a getNews method that returns itself for rendering. I should have removed this, its confusing.

              I am not aware of BeanWrapper. I used beanUtils because I needed access to mapped and indexed properties like: projection[24].value and position(QB).worth, does BeanWrapper support this, if so I would love to ditch that depend!

              I should have taken the time to javadoc this, sorry.
              Last edited by mlavwilson2; Mar 12th, 2006, 03:16 PM.

              Comment


              • #8
                Hi

                Making some progress, looks very cool... could you post any required messages (like columnInfo.name and columnInfo.description, etc).

                I also would need the icons left.icon, right.icon? and may be others?

                Thanks a lot

                Benoit
                Last edited by benoitx; Mar 12th, 2006, 05:30 PM.

                Comment


                • #9
                  Hi Matthew

                  A further 3 questions:
                  1- any particular reason why the selection form is implemented as a Wizard? This seems to be OTT but I could have misunderstood something...

                  2- Is there a way to simplify the setup? at the moment, it requires both a class and a key name. The risk is that they could be going out of sync, one is used to get the tableFormat and the other the initial config (in settings) and labels (in messages.properties). That may be ok, but the ColumnInfo seems to have a lot of info and does not seem to take advantage of the discovery of attribute type (see GlazedTableModel). I will investigate further if it is ok with you.

                  3- usage, it may be possible to have this behaviour by default if the TableFactory (may be) was able to handle all the glue work... For instance, I use GlazedTableModel everywhere with a modelId, that in turn could be used as the Key. More thinking to do of course... and it is getting late!

                  I've removed the beanutils dependencies and so far it seems working fine. I have also removed the DefaultTableFormat and used directly the GlazedTableModel. Again, it seems to work fine.

                  Thanks for this, it is cool stuff.

                  Benoit

                  Comment


                  • #10
                    images

                    Originally posted by benoitx
                    Hi

                    Making some progress, looks very cool... could you post any required messages (like columnInfo.name and columnInfo.description, etc).

                    I also would need the icons left.icon, right.icon? and may be others?

                    Thanks a lot

                    Benoit
                    I will get back to you on the 1/2 done i18 keys
                    Last edited by mlavwilson2; Mar 13th, 2006, 06:03 AM.

                    Comment


                    • #11
                      cool...

                      Originally posted by benoitx
                      Hi Matthew

                      A further 3 questions:
                      1- any particular reason why the selection form is implemented as a Wizard? This seems to be OTT but I could have misunderstood something...
                      I planned on making a next page to set up the sorting on the selected columns, i want to get to this soon. But it could be converted to a dialog.

                      Originally posted by benoitx
                      2- Is there a way to simplify the setup? at the moment, it requires both a class and a key name. The risk is that they could be going out of sync, one is used to get the tableFormat and the other the initial config (in settings) and labels (in messages.properties). That may be ok, but the ColumnInfo seems to have a lot of info and does not seem to take advantage of the discovery of attribute type (see GlazedTableModel). I will investigate further if it is ok with you.
                      In my application I have a Player.class. This player is displayed in many different tables, I want each to have its own selection persisted. However, I see the point the *.class could go away...

                      As for the GlazedTable model I discarded that when I discovered it did not support indexed and mapped properties. I have an attribute that returns an array of Float(s), I could not get the GlazedTableModel and BeanWrapper to display "player.projection[12]".

                      Originally posted by benoitx
                      3- usage, it may be possible to have this behaviour by default if the TableFactory (may be) was able to handle all the glue work... For instance, I use GlazedTableModel everywhere with a modelId, that in turn could be used as the Key. More thinking to do of course... and it is getting late!
                      I like where this is going...

                      Originally posted by benoitx
                      I've removed the beanutils dependencies and so far it seems working fine. I have also removed the DefaultTableFormat and used directly the GlazedTableModel. Again, it seems to work fine.

                      Thanks for this, it is cool stuff.

                      Benoit
                      Have you tested mapped and indexed properties?

                      Comment


                      • #12
                        Thanks for the icons. I'd like to suggest a few changes, could you get in touch directly?

                        I must admit that I have *not* tested mapped or indexed properties. I do not know whether BeanWrapper support them or not...

                        Thanks & regards,

                        Benoit
                        Last edited by benoitx; Mar 13th, 2006, 03:41 AM.

                        Comment


                        • #13
                          new feature?

                          Hi

                          I'd also like to have possibility to entirely do away with the addTableInfo/addColumnInfo.

                          My thoughts (just that at the moment) is that the combination of modelId and list of columnNames given to a GlazedTableModel should be enough to build the Table/ColumnInfo on the fly if no special comparison/renderer etc are required.

                          I'd like to try this and send you the code (probably add a ColumnInfo constructor with less parameters and have an extended GlazedTableModel to handle the case where there is nothing known about the model/columns).

                          What do you think?

                          Best regards

                          Benoit

                          PS: I did move the Wizard to a dialog but as you mention the sorting... that'd be cool to have so I have reverted to a Wizard. In order to display the title correctly, you need to explicitly setTitle on the dialog in TableCustomizationWizard.
                          For the "Title Panel Title" and "Title pane description" I've found that one needs to add a id to the TableCustomizationWizard and then have a message:
                          id.pageId.title and id.pageId.caption entries.

                          Comment


                          • #14
                            I like, but...

                            I could not get GlazedTableModel to render indexed or mapped properties. This is a feature I can not afford to give up. So we need to have an extension point so that I can plug in my impl to replace the GlazedTableModel. However, I think you want to delegate some of the work down to the GlazedTableModel. Be careful we do not want to eliminate indexed properties.

                            Originally posted by benoitx
                            Hi

                            I'd also like to have possibility to entirely do away with the addTableInfo/addColumnInfo.

                            My thoughts (just that at the moment) is that the combination of modelId and list of columnNames given to a GlazedTableModel should be enough to build the Table/ColumnInfo on the fly if no special comparison/renderer etc are required.

                            I'd like to try this and send you the code (probably add a ColumnInfo constructor with less parameters and have an extended GlazedTableModel to handle the case where there is nothing known about the model/columns).

                            What do you think?

                            Best regards

                            Benoit
                            I like the auto discovery of table attributes, however I need the ability to limit what the user can configure. There are some public methods that mean nothing to the end user. I also would not want to loose the ability to set the min, recomended and max column widths. So overloading the method with less params would be cool.

                            Originally posted by benoitx
                            PS: I did move the Wizard to a dialog but as you mention the sorting... that'd be cool to have so I have reverted to a Wizard. In order to display the title correctly, you need to explicitly setTitle on the dialog in TableCustomizationWizard.
                            For the "Title Panel Title" and "Title pane description" I've found that one needs to add a id to the TableCustomizationWizard and then have a message:
                            id.pageId.title and id.pageId.caption entries.
                            I was wondering why it was not displaying a title like the rest of my wizards
                            Last edited by mlavwilson2; Mar 13th, 2006, 07:50 AM.

                            Comment


                            • #15
                              I guess we could have an injected implementation for the getValue/setValue onthe CustomizableTableFormat.

                              One using beanUtils and the other beanWrapper.

                              I'm currently modifying things to allow auto-discovery (without removing the ability to fully define it as you have now).

                              Best regards from London,

                              Benoit

                              Comment

                              Working...
                              X