I have a show button to show a JTable
on click but the table is not visible.
Note: when I remove the JScrollPane
the code works properly but the header of the table is not shown, so any help please to make this code work properly without removing the JScrollPane
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
public class Training extends JFrame {
public Training() {
getContentPane().setLayout(new FlowLayout());
JTable table = new JTable();
table.setModel(new DefaultTableModel(new Object[][] { { "joe", "joe" },
{ "mickel", "mickel" }, }, new String[] { "LastName",
"FirstName" }));
final JScrollPane pane = new JScrollPane(table);
pane.setVisible(false);
getContentPane().add(pane);
JButton btn = new JButton("show");
add(btn);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
pane.setVisible(true);
}
});
}
public static void main(String[] args) {
Training app = new Training();
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.setSize(600, 600);
app.setVisible(true);
}
}
Later on in a program, if you call setVisible(false) the frame will become invisible, but the software object will still exist and can be made visible again with setVisible(true) .
You need to use setOpaque(false) to make it transparent. Call that both on the JScrollPane, and on it's ViewPort. sp. setOpaque(false); sp.
setVisible(true) is a blocking operation and blocks until dialog is closed. So one dialog pops up and app blocks on setVisible(true) when you close it, another serVisible(true) is invoked and so on.
After pane.setVisible(true);
add the following:
getContentPane().validate();
getContentPane().repaint();
A few things to note:
Never extends JFrame
class unnecessarily, or else you might need to extend another class which is very necessary but in java a single class may not extend more than one other class (no multiple inheritance).
Always create Swing components on Event Dispatch Thread via SwingUtilities.invokeLater(Runnable r)
block.
Do not use setSize(..)
call JFrame#pack()
before setting JFrame
visible
No need for getContentPane.add(..)
or getContentPane().setLayout(..)
, simply call add(..)
or setLayout(..)
on JFrame
instance as these calls are fowared to the contentPane.
The problem you have is you do not refresh you frame/container after setting pane visible. I disagree with @Dan. Do not use validate()
(getContentPane()
is not necesarry either) rather:
revalidate();
repaint();
as revalidate()
covers validate()
. Also validate is used when new JComponent
s are added to a visible component, whereas revalidate()
is used when JComponent
is removed/added from a visible component.
Here is a fixed version of the code with the above implemented:
After button pressed:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
public class Training {
private JFrame frame;
public Training() {
frame = new JFrame();
frame.setLayout(new FlowLayout());
JTable table = new JTable();
table.setModel(new DefaultTableModel(new Object[][]{{"joe", "joe"},
{"mickel", "mickel"},}, new String[]{"LastName",
"FirstName"}));
final JScrollPane pane = new JScrollPane(table);
pane.setVisible(false);
frame.add(pane);
JButton btn = new JButton("show");
frame.add(btn);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
pane.setVisible(true);
frame.pack();//this is so the frame will resize after adding pane
frame.revalidate();
frame.repaint();
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Training();
}
});
}
}
UPDATE:
Also for a more reusable Layout
, why not add all components to a JPanel
, and add that JPanel
to the JFrame
, thus if you ever need to add more stuff its simple.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With