4

I've removed most of my GUI to keep the code short.

I have a buttongroup of 3 JRadioButtons to select the table schema i want to display in my JTable, which is contained in a JScrollPane

I have tried to use fireTableStructureChanged() andfireTableDataChanged() as well as JTable.repaint() to no avail. Can anyone help me?

Here is a simple example that runs a window with my configuration but does not update the table.

public class test1 implements ActionListener {

private boolean payrollActive = false;

private JPanel mainPanel = new JPanel();
private JTable dataTable;

private Vector<String> courseColumns = new Vector<String>();
private Vector<String> courseColumnsPay = new Vector<String>();
private Vector<String> profsColumns = new Vector<String>();
private Vector<String> offSpaceColumns = new Vector<String>();

public test1() {
    //Add columns for tables
    String[] courseColsPay = {"Year", "Program", "Course", "Code", "CCCode", 
            "Weight", "Session", "Section", "Day", "STime", "FTime", 
            "BookedRM", "EnrolCap", "Description", "ProfFName", 
            "ProfLName", "ProfEmail", "Notes", "Syllabus", "Exam", 
            "CrossList", "PreReqs", "EnrolCtrls", "Shared",
            "TrackChanges", "Address", "WageType", "BasePay",
            "BenefitRate", "Budgeted", "PayAmount", 
            "MthAmount", "Term", "AccNumber", "PayAdmin", "PayableTo"};
    for (String col : courseColsPay) {
        courseColumnsPay.add(col);
    }
    for (int i = 0; i < 25; i++) {
        courseColumns.add(courseColsPay[i]);
    }
    String[] profCols = {"FName", "LName", "Email", "UTEmail", "Birthdate", 
            "OfficeBC", "OfficeRM", "Department", "Status", 
            "Fellowship", "OfficeStat", "PhoneNum", "HomeAddr",
            "HomePhoneNum", "Notes"};
    for (String col : profCols) {
        profsColumns.add(col);
    }
    String[] offSpaceCols = {"Building", "DeptID", "DivisionName", "BldgID", "RoomID",
            "Category", "Description", "ShareType", "DeptName",
            "Status", "SharePerc", "ShareOccupancy", "Area",
            "Fellow", "Commments", "Name", "Position",
            "Dept", "FTE", "CrossApp", "CrossPos", "CrossDept",
            "CrossFTE", "OtherOffice"};
    for (String col : offSpaceCols) {
        offSpaceColumns.add(col);
    }
    mainPanel.setSize(1260, 630);
    mainPanel.setLayout(null);

    JRadioButton coursesBtn = new JRadioButton("Courses");
    coursesBtn.setMnemonic(KeyEvent.VK_C);
    coursesBtn.setActionCommand("Course");
    coursesBtn.setSelected(true);
    coursesBtn.addActionListener(this);

    JRadioButton profsBtn = new JRadioButton("Professors");
    profsBtn.setMnemonic(KeyEvent.VK_P);
    profsBtn.setActionCommand("Professors");
    coursesBtn.addActionListener(this);

    JRadioButton officeSpBtn = new JRadioButton("Office Spaces");
    officeSpBtn.setMnemonic(KeyEvent.VK_O);
    officeSpBtn.setActionCommand("Office Spaces");
    coursesBtn.addActionListener(this);

    ButtonGroup tablesBtns = new ButtonGroup();
    tablesBtns.add(coursesBtn);
    tablesBtns.add(profsBtn);
    tablesBtns.add(officeSpBtn);

    JPanel tableRadioPanel = new JPanel(new GridLayout(0, 1));
    tableRadioPanel.setOpaque(true);
    tableRadioPanel.setBounds(0, 0, 150, 70);
    tableRadioPanel.add(coursesBtn);
    tableRadioPanel.add(profsBtn);
    tableRadioPanel.add(officeSpBtn);

    //table start
    DefaultTableModel coursesModel = new DefaultTableModel(courseColumns, 200);
    dataTable = new JTable(coursesModel);
    dataTable.setFillsViewportHeight(true);
    dataTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

    JScrollPane scrollPane = new JScrollPane(dataTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 
            JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    scrollPane.setBounds(160, 0, 1016, 558);
    //table code end

    mainPanel.add(tableRadioPanel);
    mainPanel.add(scrollPane);

}

public JComponent getMainPanel() {
    return mainPanel;
}

public JTable getDataTable() {
    return dataTable;
}


/**
 * Returns the list of columns for the given table
 * @param identifier the name of the table
 * @return a Vector<String> of column names
 */
public Vector<String> getColumns(String identifier) {
    switch (identifier) {
    case "Courses":
        if (payrollActive) {
            return courseColumnsPay;
        } else {
            return courseColumns;
        }
    case "Professors":
        return profsColumns;
    case "Office Spaces":
        return offSpaceColumns;
    default:
        return null;
    }
}

public static void createAndShowGui() {
    test1 vicu = new test1();

    JFrame frame = new JFrame("Victoria University Database Application");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(1260, 630);
    frame.setLocationRelativeTo(null);
    JLabel emptyLabel = new JLabel("");
    emptyLabel.setPreferredSize(new Dimension(175, 100));
    frame.getContentPane().add(emptyLabel, BorderLayout.CENTER);
    frame.getContentPane().add(vicu.getMainPanel());
    frame.getContentPane().setLayout(null);
    frame.setVisible(true);

}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGui();
        }
    });

}

@Override
public void actionPerformed(ActionEvent e) {
    JRadioButton targetBtn = (JRadioButton) e.getSource();
    ((DefaultTableModel) dataTable.getModel()).
    setColumnIdentifiers(getColumns(targetBtn.getText()));
}
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
Seve B.
  • 55
  • 1
  • 6
  • 1
    What about your data model has actually changed that the table should actually change? If the data hasn't changed then why should the table? – MadProgrammer Jan 29 '14 at 01:52
  • ((DefaultTableModel) target.getDataTable().getModel()). setColumnIdentifiers(target.getColumns(targetBtn.getText())); i am trying to change the column headers using this function in the listener. I return a Vector from target.getColumns(targetBtn.getText()); for use with http://docs.oracle.com/javase/7/docs/api/javax/swing/table/DefaultTableModel.html#setColumnIdentifiers(java.util.Vector) – Seve B. Jan 29 '14 at 02:00
  • I wrote a simple test which (very basically) does what you code is trying to do and it works fine (without needing to use `fireXxx` methods). Consider providing a runnable example that demonstrates your problem – MadProgrammer Jan 29 '14 at 02:07
  • Ok, thankyou, will post an edit shortly. – Seve B. Jan 29 '14 at 02:09
  • Java GUIs might have to work on a number of platforms, on different screen resolutions & using different PLAFs. As such they are not conducive to exact placement of components. To organize the components for a robust GUI, instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556), along with layout padding & borders for [white space](http://stackoverflow.com/q/17874717/418556). – Andrew Thompson Jan 29 '14 at 02:29
  • I understand, and further agree with you, but my application is for a very limited scope and can do without a layout manager for my purposes, unless you think this is affecting the table's behaviour? – Seve B. Jan 29 '14 at 02:34

2 Answers2

5

The problem seems to be that the code adds the listener 3 times to a single button, rather than once each to each of the 3 buttons!

..my application is for a very limited scope and can do without a layout manager for my purposes, unless you think this is affecting the table's behaviour?

No, not the table. It was however causing the emptyLabel to be assigned no space in the layout. Here is a robust, resizable version of the GUI.

enter image description here

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;
import java.util.*;

public class test1 implements ActionListener {

private boolean payrollActive = false;

private JPanel mainPanel = new JPanel(new BorderLayout(5,5));
private JTable dataTable;

private Vector<String> courseColumns = new Vector<String>();
private Vector<String> courseColumnsPay = new Vector<String>();
private Vector<String> profsColumns = new Vector<String>();
private Vector<String> offSpaceColumns = new Vector<String>();

public test1() {
    mainPanel.setBorder(new EmptyBorder(5,5,5,5));
    //Add columns for tables
    String[] courseColsPay = {"Year", "Program", "Course", "Code", "CCCode",
            "Weight", "Session", "Section", "Day", "STime", "FTime",
            "BookedRM", "EnrolCap", "Description", "ProfFName",
            "ProfLName", "ProfEmail", "Notes", "Syllabus", "Exam",
            "CrossList", "PreReqs", "EnrolCtrls", "Shared",
            "TrackChanges", "Address", "WageType", "BasePay",
            "BenefitRate", "Budgeted", "PayAmount",
            "MthAmount", "Term", "AccNumber", "PayAdmin", "PayableTo"};
    for (String col : courseColsPay) {
        courseColumnsPay.add(col);
    }
    for (int i = 0; i < 25; i++) {
        courseColumns.add(courseColsPay[i]);
    }
    String[] profCols = {"FName", "LName", "Email", "UTEmail", "Birthdate",
            "OfficeBC", "OfficeRM", "Department", "Status",
            "Fellowship", "OfficeStat", "PhoneNum", "HomeAddr",
            "HomePhoneNum", "Notes"};
    for (String col : profCols) {
        profsColumns.add(col);
    }
    String[] offSpaceCols = {"Building", "DeptID", "DivisionName", "BldgID", "RoomID",
            "Category", "Description", "ShareType", "DeptName",
            "Status", "SharePerc", "ShareOccupancy", "Area",
            "Fellow", "Commments", "Name", "Position",
            "Dept", "FTE", "CrossApp", "CrossPos", "CrossDept",
            "CrossFTE", "OtherOffice"};
    for (String col : offSpaceCols) {
        offSpaceColumns.add(col);
    }

    //mainPanel.setSize(1260, 630);
    //mainPanel.setLayout(null);

    JRadioButton coursesBtn = new JRadioButton("Courses");
    coursesBtn.setMnemonic(KeyEvent.VK_C);
    coursesBtn.setActionCommand("Course");
    coursesBtn.setSelected(true);
    coursesBtn.addActionListener(this);

    JRadioButton profsBtn = new JRadioButton("Professors");
    profsBtn.setMnemonic(KeyEvent.VK_P);
    profsBtn.setActionCommand("Professors");
    profsBtn.addActionListener(this);

    JRadioButton officeSpBtn = new JRadioButton("Office Spaces");
    officeSpBtn.setMnemonic(KeyEvent.VK_O);
    officeSpBtn.setActionCommand("Office Spaces");
    officeSpBtn.addActionListener(this);

    ButtonGroup tablesBtns = new ButtonGroup();
    tablesBtns.add(coursesBtn);
    tablesBtns.add(profsBtn);
    tablesBtns.add(officeSpBtn);

    JPanel tableRadioPanel = new JPanel(new GridLayout(0, 1));
    tableRadioPanel.add(coursesBtn);
    tableRadioPanel.add(profsBtn);
    tableRadioPanel.add(officeSpBtn);

    //table start
    DefaultTableModel coursesModel = new DefaultTableModel(courseColumns, 200);
    dataTable = new JTable(coursesModel);
    dataTable.setFillsViewportHeight(true);
    dataTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

    JScrollPane scrollPane = new JScrollPane(dataTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
            JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    //scrollPane.setBounds(160, 0, 1016, 558);
    //table code end

    JPanel gridConstrain = new JPanel();
    gridConstrain.add(tableRadioPanel);
    mainPanel.add(gridConstrain, BorderLayout.LINE_START);
    mainPanel.add(scrollPane);

}

public JComponent getMainPanel() {
    return mainPanel;
}

public JTable getDataTable() {
    return dataTable;
}


/**
 * Returns the list of columns for the given table
 * @param identifier the name of the table
 * @return a Vector<String> of column names
 */
public Vector<String> getColumns(String identifier) {
    switch (identifier) {
    case "Courses":
        if (payrollActive) {
            return courseColumnsPay;
        } else {
            return courseColumns;
        }
    case "Professors":
        return profsColumns;
    case "Office Spaces":
        return offSpaceColumns;
    default:
        return null;
    }
}

public static void createAndShowGui() {
    test1 vicu = new test1();

    JFrame frame = new JFrame("Victoria University Database Application");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    JLabel emptyLabel = new JLabel("Empty Label");
    emptyLabel.setFont(emptyLabel.getFont().deriveFont(80f));
    //emptyLabel.setPreferredSize(new Dimension(175, 100));
    frame.getContentPane().add(emptyLabel, BorderLayout.PAGE_START);
    frame.getContentPane().add(vicu.getMainPanel());
    frame.pack();
    frame.setVisible(true);

}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGui();
        }
    });

}

@Override
public void actionPerformed(ActionEvent e) {
    System.out.println("Event: " + e);
    JRadioButton targetBtn = (JRadioButton) e.getSource();
    ((DefaultTableModel) dataTable.getModel()).
    setColumnIdentifiers(getColumns(targetBtn.getText()));
}
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
5

In your example, you are not registering an ActionListener to profsBtn or officeSpBtn, you keep registering to coursesBtn

JRadioButton coursesBtn = new JRadioButton("Courses");
//...
coursesBtn.addActionListener(this);

JRadioButton profsBtn = new JRadioButton("Professors");
//...
coursesBtn.addActionListener(this);

JRadioButton officeSpBtn = new JRadioButton("Office Spaces");
//...
coursesBtn.addActionListener(this);

Once I register the ActionListener to the correct buttons, it works fine

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • 1
    I found this simply by placing a break point in the `ActionListener`, when it didn't trip, I went back to check that the `ActionListener` was being registered. While I won't say that sometimes you can't see the forest for the trees, this should have set of alarm bells ;) – MadProgrammer Jan 29 '14 at 02:45
  • 1
    *"I found this simply by placing a break point in the `ActionListener`,"* Oh, you kids and your high-tech. 'break-points'! I found out the low-tech. way, by adding a `System.out.println("Event: " + e);` statement. This was based on my long held principle *"When in doubt, print out!"*. But in case anybody is confused, ***using a debugger with breakpoints is more optimal.*** – Andrew Thompson Jan 29 '14 at 02:55
  • 1
    @AndrewThompson To much typing ;) - I actually want to see what was returned by the `getColumns` method, but never got that far ;) – MadProgrammer Jan 29 '14 at 02:59