KJaeg KJaeg - 4 months ago 17
Java Question

Can't show table header of tabbed JTable

I have a

JTabbedPane
, which contains three tables in its tabs. The
JTabbedPane
, again, is in a
JScrollPane
. I want to show a fix table header, which is following the schema
{"Client", "Action", "Location", "Value"}
, for each table. While I was trying to set the header in an
ActionListener
(see later), I am free for other approaches (e. g. initially setting the header).

Other SO-posts are adressing the same issue, but I was not able to get the table header to be shown. The only thing which is working is an adding of data to the table in the mentioned
ActionListener
. I don't understand why the header is not shown, since I am passing the data in form of a
String
-matrix together with a
String
-array that represents the header.

At first, here is a snippet of the code regarding my tables, which is executed on the start up of the GUI (my
initialize()
-method).

tabbedPane = new JTabbedPane(JTabbedPane.TOP);
tabbedPane.setBorder(new SoftBevelBorder(BevelBorder.LOWERED, null, null, null, null));
tabbedPane.setFont(new Font("Carlito", Font.PLAIN, 13));
tabbedPane.setBackground(Color.WHITE);
tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);

tableBefore = new JTable();
tabbedPane.addTab(descrTableBefore, null, tableBefore, null);
tableBefore.setFont(new Font("Carlito", Font.PLAIN, 13));
tableBefore.setFocusable(false);

tableMainTest = new JTable();
tabbedPane.addTab(descrTableMain, null, tableMainTest, null);
tabbedPane.setEnabledAt(1, true);
tableMainTest.setFont(new Font("Carlito", Font.PLAIN, 13));
tableMainTest.setFocusable(false);

tableAfter = new JTable();
tabbedPane.addTab(descrTableAfter, null, tableAfter, null);
tableAfter.setFont(new Font("Carlito", Font.PLAIN, 13));
tableAfter.setFocusable(false);

scrollTables = new JScrollPane();
scrollTables.setBounds(442, 11, 397, 490);
scrollTables.setViewportView(tabbedPane);
frmTestframework.getContentPane().add(scrollTables);


Below is again a code snippet, but this time from the mentioned
ActionListener
, which is added to a button that adds the elements to the
JTable
. Currently I am trying to get it to work with just one table:
tableMainTest
. So that's how I tried to define the table header:

dataMatrixMain = new String[itemListMain.size()][];

for(int j = 0; j < itemListMain.size(); j++)
dataMatrixMain[j] = itemListMain.get(j);

modelMain = new DefaultTableModel(dataMatrixMain, header);

mainGUI.tableMainTest.setModel(modelMain);



  • header
    is a
    String
    -array with the form
    {"Client", "Action", "Location", "Value"}

  • itemListMain
    is a List of String-arrays

  • dataMatrixMain
    is the
    String
    -matrix that will be used to fill my table with data



Does anyone know, what has to be changed to make the header visible?

EDIT:

When the program is started the user will see my tables in following state:

Table in the intial state

The user will simply see three tabs, which tables are all empty.

Filling the tables with content is the users job. After picking an element from a
JList
, and submitting it, the table is filled the following way:

Table filled with data

After each submit of the selected element from the
JList
, it will be directly displayed in the
JTable
. I am doing this by setting the
DefaultTableModel
of the
JTable
. So displaying the entered element works like expected. Only the header is not displayed above of the entries.

EDIT 2: SSCCE

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.border.BevelBorder;
import javax.swing.border.SoftBevelBorder;
import javax.swing.table.DefaultTableModel;


public class GUIMain{

private JFrame frmKeyoperateTestframework;

public JTable tableBefore;
public JTable tableMainTest;
public JTable tableAfter;

public JTabbedPane tabbedPane;
public JScrollPane scrollTables;

/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GUIMain window = new GUIMain();
window.frmKeyoperateTestframework.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

/**
* Create the application.
*/
public GUIMain() {
initialize();
}

/**
* Initialize the contents of the frame.
*/
private void initialize() {

frmKeyoperateTestframework = new JFrame();
frmKeyoperateTestframework.setResizable(false);
frmKeyoperateTestframework.getContentPane().setBackground(Color.WHITE);
frmKeyoperateTestframework.setFont(new Font("Carlito", Font.PLAIN, 14));
frmKeyoperateTestframework.setTitle("GUI");
frmKeyoperateTestframework.setBounds(100, 100, 865, 584);
frmKeyoperateTestframework.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmKeyoperateTestframework.getContentPane().setLayout(null);

tabbedPane = new JTabbedPane(JTabbedPane.TOP);
tabbedPane.setBorder(new SoftBevelBorder(BevelBorder.LOWERED, null, null, null, null));
tabbedPane.setFont(new Font("Carlito", Font.PLAIN, 13));
tabbedPane.setBackground(Color.WHITE);
tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);

scrollTables = new JScrollPane();
scrollTables.setBounds(446, 50, 397, 490);
scrollTables.setViewportView(tabbedPane);
frmKeyoperateTestframework.getContentPane().add(scrollTables);

// "5" to show, that only data rows are displayed
DefaultTableModel tableModel = new DefaultTableModel(new String[]{"Client", "Action", "Location", "Value"}, 5);

tableBefore = new JTable();
tableBefore.setName("tableBefore");
tableBefore.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
tableBefore.setModel(tableModel);
tabbedPane.addTab("Before", null, tableBefore, null);
tableBefore.setFont(new Font("Carlito", Font.PLAIN, 13));
tableBefore.setFocusable(false);

tableMainTest = new JTable();
tableMainTest.setName("tableMainTest");
tableMainTest.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
tableMainTest.setFont(new Font("Carlito", Font.PLAIN, 13));
tableMainTest.setFocusable(false);
tableMainTest.setModel(tableModel);
tabbedPane.addTab("Main", null, tableMainTest, null);
tabbedPane.setEnabledAt(1, true);

tableAfter = new JTable();
tableAfter.setName("tableAfter");
tableAfter.setModel(tableModel);
tableAfter.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
tabbedPane.addTab("After", null, tableAfter, null);
tableAfter.setFont(new Font("Carlito", Font.PLAIN, 13));
tableAfter.setFocusable(false);

tabbedPane.setSelectedComponent(tableMainTest);
}
}

Answer

I found the solution by myself. The solution was simply using a JScrollPane for each table, which was included in the JTabbedPane. Before, the whole JTabbedPane was wrapped in a JScrollPane. Now, each tab holds a JScrollPane instead of a JTable. While it sounds simple to remove the old JScrollPane and pack the tables into an own one, it took some effort to change the remaining code, to fix it, and to fit the new code to the layout of the GUI.

I found a good code example how it should look like here.

Below you can find a code example how a combination of a JTabbedPane, a JScrollPane and JTables has to look like to work:

    tabbedPane = new JTabbedPane(JTabbedPane.TOP);
    tabbedPane.setBounds(446, 50, 397, 490);
    tabbedPane.setBorder(new SoftBevelBorder(BevelBorder.LOWERED, null, null, null, null));
    tabbedPane.setFont(new Font("Carlito", Font.PLAIN, 13));
    tabbedPane.setBackground(Color.WHITE);
    frame.getContentPane().add(tabbedPane);  // JFrame

    tableMainTest = new JTable();
    tableMainTest.setName("tableMainTest");
    tableMainTest.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    tableMainTest.setFont(new Font("Carlito", Font.PLAIN, 13));
    tableMainTest.setFocusable(false);
    tableMainTest.setModel(tableModel);

    tableMainTest.setPreferredScrollableViewportSize(tableMainTest.getPreferredSize());
    tableMainTest.changeSelection(0, 0, false, false);
    tableMainTest.setAutoCreateRowSorter(true);

    JScrollPane scrollMain = new JScrollPane(tableMainTest);
    scrollMain.add(tableMainTest.getTableHeader());
    scrollMain.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER );
    scrollMain.setBounds(446, 50, 397, 490);

    tabbedPane.addTab(descrTableMain, scrollMain);