JTable not visible inside JScrollPane - java

I have a JTable inside a JScrollPane. I want to show the table only when a particular button is pressed otherwise it should not be shown.
Inorder to incorporate that I have set the setVisible method of the ScrollPane to false while declaring and I set it to true inside the actionPerformed method of the JButton.
But the JTable is not visible even when I press the JButton.
Here's my code:
public class TableSample{
private JTable table;
....
private void initialize() {
JScrollPane scrollPane = new JScrollPane();
table = new JTable(new DefaultTableModel(new Object[][] {{null, null}, {null, null}, }, new String[] {"column1", "column2"}));
scrollPane.setViewportView(table);
scrollPane.setVisible(false);
JButton button = new JButton("Show Table");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
....
scrollPane.setVisible(true);
....
}
});
....
}
I have used group layout so the ScrollPane is added to frame with group layout.
Also the JTable is visible when I do not change the setVisible at all (by default true)
Any help is appreciated...

When you add components to a visible GUI the basic logic is:
panel.add(...);
panel.revalidate(); // to invoke the layout manager
panel.repaint(); // sometimes needed to make sure panel is repainted

Related

JTable in JDialog

I have problem with JTable using in JDialog. I want to show my table in dialog with this code:
public class ShortcutKeys extends JDialog {
public ShortcutKeys( JFrame parent ) {
super( parent );
this.setTitle( "Shortcut Keys of..." );
this.setLocationRelativeTo( null );
this.setModal( true );
this.setResizable( false );
this.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE );
this.getContentPane().setLayout( new BorderLayout() );
JTable shortcutKeysTable = getShortcutKeysTable();
this.add( shortcutKeysTable, BorderLayout.CENTER );
this.pack();
}
private JTable getShortcutKeysTable() {
JTable shortcutKeysTable;
Object rowData[][] = { { "1", "11" }, { "2", "22"} };
Object columnNames[] = { "Column One", "Column Two" };
shortcutKeysTable = new JTable(rowData, columnNames);
JScrollPane scrollPane = new JScrollPane(shortcutKeysTable);
this.add(scrollPane, BorderLayout.CENTER);
this.setSize(300, 150);
return shortcutKeysTable;
}
}
So, problem is such that with exactly this code, doesn't show column names - only row data without my size, result is in small table not with my preference.
BUT when in method or in constructor I add this line:
this.setVisible( true );
Then this table shows row data and columns with my size 300x150 BUT when I click ok Exit 'X' then of course this dialog disappeared but show new empty dialog:
http://i.imgur.com/SzkF5iK.png
What I did wrong and how can I resolve this problem?
What must be added to the dialog is the scollPane, which itself contains the table. Not the table itself.
You should decide what the getShortcutKeysTable()does:
either it creates a table, a scrollPane, and adds the scollPane to the dialog (and should be refactored to void createAndAddTable())
or it simply creates a table and returns it, and the caller is responsible for wrapping it into a scollpane and adding the scrollpane to the dialog.
Mixing the two responsibilities makes the code confusing, even for you who wrote the code.
In any wase, setting the size of the dialog is not its responsibility, and it's unneeded, since you call pack() after anyway.
You need to call JDialog.setVisible(true); in order to show the dialog.
But you have a bug in your code: You put the table in a scrollpane and add the scrollpane to the dialog (in method getShortcutKeysTable) and then add the table to the dialog again (in the constructor).
Your code runs fine if you do in the constructor
...
getShortcutKeysTable();
this.pack();
this.setVisible(true);
}

Java changing an existing component

I am trying to change a component from a JLabel to JComboBox when another option is added but for some reason the panel is not updating.
SSCCE:
public class SwitchComponent {
public static void main(String[] args) {
JPanel panel = new JPanel();
JComponent component = new JLabel("This is a test");
panel.add(component);
JComboBox<String> comboBox = new JComboBox<String>();
comboBox.addItem("Testing..");
comboBox.addItem("1.. 2.. 3..");
component = comboBox;
// I have tried with only one of the below lines and without any also...
// Doesn't seem to have an effect.
// I've also tried invoking the below methods on the panel instead.
component.revalidate();
component.repaint();
JOptionPane.showConfirmDialog(null, panel, "Test",
JOptionPane.OK_OPTION,
JOptionPane.PLAIN_MESSAGE);
}
}
Why is this happening? Shouldn't panel be referencing component such that any changes to component are reflected via panel?
Do I really have to completely reassemble the panel when the component changes?
When click YES/NO button on JOptionPane, JOptionPane will close.
We need to add the JComboBox to Panel again and use JOptionPane to show the Panel again in your code.
Have a try with this:
public class SwitchComponent {
public static void main(String[] args) {
JPanel panel = new JPanel();
JComponent component = new JLabel("This is a test");
panel.add(component);
JOptionPane.showConfirmDialog(null, panel, "Test",
JOptionPane.OK_OPTION,
JOptionPane.PLAIN_MESSAGE);
panel.remove(component);
JComboBox<String> comboBox = new JComboBox<String>();
comboBox.addItem("Testing..");
comboBox.addItem("1.. 2.. 3..");
panel.add(comboBox);
// I have tried with only one of the below lines and without any also...
// Doesn't seem to have an effect.
// I've also tried invoking the below methods on the panel instead.
panel.revalidate();
panel.repaint();
JOptionPane.showConfirmDialog(null, panel, "Test",
JOptionPane.OK_OPTION,
JOptionPane.PLAIN_MESSAGE);
}
}
I.e. the label could be second in a series of three, I would want the combo box to remain second when the component is changed to the combo box. Hence why I was trying to change the reference
Use a Card Layout. It will replace a component at the same location.

How to get the Jtable or get jTable model of the current tab?

Is there anyway i can get Jtable from the tabbed panel selected.
I creat tables dynamically for every tab selected using this code:
JScrollPane panel2 = new JScrollPane();
panel2.setName(tabidis);
chattable = new JTable();
chattable.setModel(new javax.swing.table.DefaultTableModel(new Object [][] {},new String [] {"Messages"}));
panel2.setViewportView(chattable);
chattable.setShowGrid(false);
jTabbedPane1.add(username4, panel2);
//I am using GUI environment in netbeans.
I think the hierarchy as follows:
JTabbedPanel1 >> JscrollPAnel1 >> Jtable1
By using the following code:
((JTable)jTabbedPane1.getSelectedComponent().getComponentAt(1,1).getComponentAt(0,0)).getName();
I get the error that "javax.swing.table.JTableHeader cannot be cast to javax.swing.JTable"
That means that i am getting jTable Header as the component. But what i need is to get JTable as the component outcome so to get the model from it.
Or more simply "Is there anyway to get the model of a JTable present in the selected tab"
This seems to work:
#Test
public void test() {
// original components
JTable jTable = new JTable();
JScrollPane scrollPane = new JScrollPane(jTable);
// add them to tab
JTabbedPane jTabbedPane = new JTabbedPane();
jTabbedPane.addTab("tab1", scrollPane);
jTabbedPane.setSelectedComponent(scrollPane);
// get them out of selected tab
JScrollPane scrollRef = (JScrollPane) jTabbedPane.getSelectedComponent();
JTable tableRef = (JTable) scrollRef.getViewport().getComponents()[0];
assertTrue(tableRef == jTable);
}

Updating Data in a JTable

Lets say I have a table. One of the cells holds a JLabel. If I change the text of the JLabel how do I get the JTable to show the change?
Look at the following code, what should I change to make it show the changes to the JLabel?
public class ActivTimerFrame extends JFrame implements ActionListener{
//Data for table and Combo Box
String timePlay = "1 Hour";
String timeDev = "2 Hours";
String[] comboChoices = {"Play Time", "Dev Time"};
String[] columnNames = {"Activity", "Time Allowed", "Time Left"};
Object[][] data = {{"Play Time", "1 Hour", timePlay }, {"Dev Time", "2 Hours", timeDev }};
//This is where the UI stuff is...
JTable table = new JTable(data, columnNames);
JScrollPane scrollPane = new JScrollPane(table);
JPanel mainPanel = new JPanel();
JComboBox comboBox = new JComboBox(comboChoices);
JButton start = new JButton("Start");
JButton stop = new JButton("Stop");
public ActivTimerFrame() {
super("Activity Timer");
setSize(655, 255);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setResizable(false);
GridLayout layout = new GridLayout(2,1);
setLayout(layout);
add(scrollPane);
stop.setEnabled(false);
start.addActionListener(this);
mainPanel.add(comboBox);
mainPanel.add(start);
mainPanel.add(stop);
add(mainPanel);
}
#Override
public void actionPerformed(ActionEvent evt) {
Object source = evt.getSource();
if(source == start) {
timePlay ="It Works";
}
}
}
You can do
table.getModel().setValueAt(cellValueObject, rowIndex, colIndex);
to set a particular cell.
in you case for what you are trying, you can do
timePlay ="It Works";
table.getModel().setValueAt(timePlay, 0, 1);
You need to have your JTable use a TableModel such as an AbstractTableModel or DefaultTableModel and then change the data in the table model when desired. This will then be reflected as changes in the data displayed in the JTable if you also fire the appropriate listener notification method (which is done automatically for you if you use the DefaultTableModel). The Swing tutorial on JTables explains all of this, and if you haven't gone through it, you owe it to yourself to do so.

How can I refresh a JScrollPane after choosing an element from a JComboBox?

I have a JComboBox, and I want to load in a JScrollPane a different content everytime I choose a different element from the JComboBox. The content consists of a various number of JLabels and JTextFields.
What I have done:
JScrollPane scrollPane;
JComboBox combo;
JPanel back = new JPanel(new BorderLayout());
combo = new JComboBox({ "Bird", "Cat", "Dog", "Rabbit", "Pig" });
combo.addActionListener(new AnimalLoader());
scrollPane = showPanel((String) combo.getSelectedItem());
back.add(combo, BorderLayout.NORTH);
back.add(scrollPane, BorderLayout.SOUTH);
back.setVisible(true);
protected JScrollPane showPanel(String name)
{
JPanel contentPanel = new JPanel(new JLabel(name));
scrollPane = new JScrollPane(contentPanel);
return scrollPane;
}
private class AnimalLoader implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
JComboBox cb = (JComboBox) e.getSource();
String selected = (String) cb.getSelectedItem();
scrollPane = showPanel(selected);
}
}
I didn't manage to make this reload a different JScrollPane when I choose another item.
Only the JScrollPane that belongs to the first item (the default one) of the JComboBox is loaded.
Any ideas of what I've done wrong please?
scrollPane = showPanel(selected);
Don't create a new scoll pane when you select an item. Instead you need to change the panel that is contained in the viewport of the scroll pane. That is, your "showPanel" method should return the panel, not a scrollpane. Then you can use:
scrollPane.setViewportView( showPanel(selected) );
Next time a proper SSCCE should be posted.
There is no evidence the newly created JScrollPane is ever added to anything.
I would try either of:
Add a JPanel with a CardLayout to
the JScrollPane, and add other
collections of components to the
JPanel.
Call
setViewportView(Component view) on
the existing JScrollPane.
panel.revalidate();
panel.repaint();
As you are using this example, try this variation at line 73, near the end of the ComboBoxDemo constructor:
//Lay out the demo.
add(petList, BorderLayout.PAGE_START);
JScrollPane jsp = new JScrollPane(picture);
jsp.getViewport().setPreferredSize(new Dimension(100, 100));
add(jsp, BorderLayout.PAGE_END);
setBorder(BorderFactory.createEmptyBorder(20,20,20,20));

Categories