How can I set column widths in a JTable

Discussion in 'Java' started by Martin Gregorie, Oct 25, 2010.

  1. I have a Jtable that used to display a number of columns, which are

    Col Class Caption Length (chars)
    1 String License 14
    2 String Date 19 (ccyy-mm-dd hh:mm:ss)
    3 String Licenseee up to 80
    4 String E-mail up to 80
    5 String Phone 19
    6 Boolean Issued 6 (length of the heading)

    None of these are editable because a separate pop-up window is used to
    amend and manipulate each license. This is all working well, but all the
    columns are of equal width. I'd like to fix the lengths of columns 1,2,5
    and 6 on order to leave the maximum amount of space for columns 3 and 4
    but can't work out how.

    It looks as though I should use DefaultTableCellRenderer but I can't work
    out how to tell it how wide each column should be. This topic isn't
    covered in the 'How to use Tables' tutorial, so any pointers would be
    much appreciated.
    Martin Gregorie, Oct 25, 2010
    1. Advertisements

  2. Martin Gregorie

    markspace Guest

    markspace, Oct 25, 2010
    1. Advertisements

  3. It did now. It was the method for getting the list of TableColumn objects
    that had eluded me. Many thanks for your help.

    BTW, what's the best method of building a custom cell renderer with just
    a few tweaks, e.g. monospaced font? Would extending DefaultCellRenderer
    be reasonable or is there a better way?
    Martin Gregorie, Oct 26, 2010
  4. Martin Gregorie

    markspace Guest

    Honestly I have no clue. I just read the tutorial after you posted.
    Looking at the tutorial again, it seems that DefaultCellRederer is for
    the whole table, and TableCellRenderer is for individual columns or
    cells if you need finer grained control.

    So unless your entire table is all monospaced text, I think you'll want
    the latter.
    markspace, Oct 26, 2010
  5. Fair enough. Thanks to your help I now know that its easy to build and
    install custom renderers if columns have different Objects in them. I had
    assumed that you had to somehow diddle with the renderer if you wanted to
    set different widths in columns using the same type of Object, e.g.
    different amounts of data in Strings.

    Now I know that's only partly true - if you just want to adjust column
    widths in pixels you don't need to go near the renderer, but if you want
    to set widths in terms of character counts then you need to extract a lot
    of info from the renderer. The first thing you find is that, if the
    default renderer is being used then getCellRenderer() will return null
    rather than a reference to the default renderer. In this case you need to
    instantiate a DefaultTableCellRenderer because there's quite a lot of
    stuff you'll need from it to calculate the cell width: the Font and the
    FontMetrics both come from the cell renderer. You need both to get the
    FontRenderContext and *thats* where you get the character height and
    width figures from.

    It all reminds me of that old song about "the thigh bone's connected to
    the hip bone....", but I digress.

    So, after all that I thought I could at last calculate the column width
    in pixels from maxCharacterWidth * char count, but that gives me a column
    thats 220% of the required figure, i.e. a bloody great wide column, so
    divide by 2.2. This magic number works correctly on screens with
    different resolutions so its probably safe to use though I don't
    understand why it is needed, let alone why it has to be 2.2.
    Yep, my next step will be to build a cell renderer using a fixed width
    font and see what this does to the magic number.

    I'm somewhat perplexed by all the hoops one needs to jump through to get
    a character width in pixels just to set a column width. I say perplexed
    because I'd have thought this was a common requirement for anybody laying
    out a neatly formatted JTable or a dialogue using JTextFields to edit
    fixed length character data. In the latter case simply setting the width
    of a JTextField in characters and defaulting everything else always seems
    to give a field that's considerably wider than you want.
    Martin Gregorie, Oct 26, 2010
  6. I haven't tried it, but this Table Column Adjuster may be worth a look:

    John B. Matthews, Oct 26, 2010
  7. Martin Gregorie, Oct 26, 2010
  8. OK, I built a Monospace renderer by extending DefaultTableCellRenderer
    and adding code in the constructor to:
    - extract the font size from the default font
    - replaced that with "Monospace.bold" and the default font size (12pt)
    using the Font constants for MONOSPACE and BOLD

    This worked as expected, but had the unexpected effect of roughly
    doubling the pixel width of the maximum width character. If I'd persisted
    my magic number divisor (2.2) I needed to get sensible column widths
    would have needed to be adjusted to something like 5 for the monospaced
    fonts. This struck me as odd, since these fonts looked to be very much
    the same width as the default Dialog.bold fonts.

    Since the object of this faffing about with fixed width fonts was to get
    rid of the magic number divisor if at all possible, I've left things as
    they are, i.e. The JTable cells use 12pt Dialog.bold font and I use the
    magic divisor of 2.2 when converting a number of characters into a column

    I'm happy with the appearance of the JTables, so thanks again for your
    help. I've learnt quite a bit from this exercise.
    Martin Gregorie, Oct 27, 2010
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.