Swing Puzzler #1

February 15th, 2010

I don’t like programming puzzles. If a small piece of code does not do what it appears to be doing after skimming through it, it is either the problem in the code itself, or the underlying libraries that it is using. Code should be easy to read, and easy to understand. This is why i didn’t enjoy any of the “Java puzzles” sessions during the last few JavaOne conferences. I have the original book and i’ve seen the presentation slides. Personally, i don’t think that i can learn much from them – except seeing that the puzzles originate from the intricacies of the language specification, unfortunate naming of the core APIs, or the artificial restrictions of binary compatibility that resulted in the mess that is core Java generics.

Unfortunately, all of these are still part of the platform – whether we want them or not. Which is why i’d like to present you with this simple Swing program based on the code from QStorm in one of the Substance forums. Note that the following code does not use Substance and runs under the default look-and-feel.

public class Puzzle1 {
   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            JFrame frame = new JFrame("Puzzle 1");
            frame.setSize(new Dimension(300, 200));
            frame.setLocationRelativeTo(null);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            final JTable table = new JTable();
            table.getSelectionModel().addListSelectionListener(
                  new ListSelectionListener() {
                     @Override
                     public void valueChanged(ListSelectionEvent e) {
                        if (e.getValueIsAdjusting())
                           return;

                        System.out.println("Table: "
                              + table.getRowCount() + ", model: "
                              + table.getModel().getRowCount());
                     }
                  });
            table.setAutoCreateRowSorter(true);
            table.setModel(new DefaultTableModel(
                  new Object[][] { new Object[] { "Steven", 10 } },
                  new Object[] { "Name", "Value" }));
            frame.add(table, BorderLayout.CENTER);

            JPanel controls = new JPanel(
                  new FlowLayout(FlowLayout.TRAILING));

            JButton selectAllRowsBtn = new JButton("Select all rows");
            selectAllRowsBtn.addActionListener(new ActionListener() {
               public void actionPerformed(ActionEvent e) {
                  table.selectAll();
               }
            });
            controls.add(selectAllRowsBtn);

            JButton resetModelBtn = new JButton("Reset model");
            resetModelBtn.addActionListener(new ActionListener() {
               public void actionPerformed(ActionEvent e) {
                  table.setModel(new DefaultTableModel());
               }
            });
            controls.add(resetModelBtn);

            frame.add(controls, BorderLayout.SOUTH);

            frame.setVisible(true);
         }
      });
   }
}

This is how the UI looks like – it has a table with one row, and two buttons on the bottom:

When the “Select all rows” button is clicked, the JTable.selectAll() is called:

When the “Reset model” is called, the table model is reset to an empty model (no rows):

After the table is created, a selection listener is added to it. It prints the number of table rows as returned by JTable.getRowCount() and as returned by JTable.getModel().getRowCount().

What is the last line printed to the console after the two buttons have been activated?

  • Table: 0, model: 0
  • Table: 1, model: 0
  • Table: 1, model: 1
  • None of the above