
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.TableColumn;
import org.fest.swing.core.BasicRobot;
import org.fest.swing.core.Robot;
import org.fest.swing.fixture.FrameFixture;
import org.fest.swing.fixture.JTableFixture;
import static org.fest.swing.timing.Pause.*;
import org.testng.annotations.*;
import static org.testng.Assert.*;

/**
 * This test verifies whether clicking on table header succeeds.
 * The table is contained inside JScrollPane. Table has 3 columns.
 * First column is fully visible, second is partially visible
 * and third is not visible.
 */
public class HeaderClickTest {

    private static final int COLUMN_WIDTH = 200;
    private static final int FRAME_WIDTH = (int) (COLUMN_WIDTH * 1.3);
    private static final int FRAME_HEIGHT = 200;
    private FrameFixture frameFixture;
    private JTableFixture tableFixture;
    private JTable table;
    private int headerClickCounter = 0;

    @BeforeMethod
    public void createFrame() {
        createTable();
        final JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(1, 0));
        panel.add(new JScrollPane(this.table));
        final JFrame frame = new JFrame();
        frame.setTitle("Test Frame");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                frame.setContentPane(panel);
                Dimension dim = new Dimension(FRAME_WIDTH, FRAME_HEIGHT);
                frame.setMinimumSize(dim);
                frame.setMaximumSize(dim);
                frame.setPreferredSize(dim);

                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                frame.toFront();
            }
        });

        pause(1000); // wait for frame to show up

        Robot robot = BasicRobot.robotWithNewAwtHierarchy();
        this.frameFixture = new FrameFixture(robot, frame);
        this.tableFixture = new JTableFixture(robot, this.table);
    }

    private void createTable() {
        String[] columnNames = {"Visible", "Semi Visible", "Not Visible"};
        Object[][] data = {
            {"data", "data", "data"},
            {"data", "data", "data"},
            {"data", "data", "data"}
        };

        this.table = new JTable(data, columnNames);
        this.table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

        for (int col = 0; col < this.table.getColumnCount(); col++) {
            TableColumn column = this.table.getColumnModel().getColumn(col);
            column.setPreferredWidth(COLUMN_WIDTH);
            column.setMaxWidth(COLUMN_WIDTH);
            column.setMinWidth(COLUMN_WIDTH);
        }

        this.table.getTableHeader().addMouseListener(new HeaderMouseListener());
    }

    @Test
    public void testTableHeaderClick() {
        for (int column = 0; column < this.table.getColumnCount(); column++) {
            pause(1000);
            this.tableFixture.tableHeader().clickColumn(column);
            assertSame(this.headerClickCounter, column + 1);
        }
        pause(1000);
    }

    @AfterMethod
    public void closeFrame() {
        this.frameFixture.close();
    }

    private class HeaderMouseListener extends MouseAdapter {

        @Override
        public void mouseClicked(MouseEvent arg0) {
            headerClickCounter++;
        }
    }
}

