I have coded up a simple swing gui
. However, my problem is that my table is on the bottom of my page. I would like to have with some space below my buttons and also more space down to the bottom. Here is a short program, what I am doing:
public class minimumExample extends JFrame {
private JTabbedPane tabbedPane;
private FilteredTabPanel filteredTabPanel;
public void createTabBar() {
tabbedPane = new JTabbedPane(JTabbedPane.TOP);
filteredTabPanel = new FilteredTabPanel();
tabbedPane.addTab("Test", filteredTabPanel.createLayout());
add(tabbedPane);
tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
}
private void makeLayout() {
setTitle("Test App");
setLayout(new BorderLayout());
setPreferredSize(new Dimension(1000, 500));
createTabBar();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public void start() {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
makeLayout();
}
});
}
public static void main(String[] args) throws IOException {
minimumExample ex = new minimumExample();
ex.start();
}
public class FilteredTabPanel extends JPanel {
private JPanel selectionArea;
private JLabel lCity;
private JComboBox cityBox;
private JTable filterTable;
String[] columnNames = {"Cities"};
String[][] data = {
{"NY"}, {"NY"}, {"NY"}, {"NY"}, {"LA"}, {"LA"},{"Columbia"},{"DC"},{"DC"},{"DC"},{"DC"},{"DC"},{"DC"}
};
private JScrollPane scrollPane;
public JPanel createLayout() {
JPanel panel = new JPanel(new GridLayout(0, 1));
//add panels to the layout
panel.add(addButtons());
panel.add(showTable());
repaint();
revalidate();
return panel;
}
public JPanel addButtons(){
selectionArea = new JPanel(new FlowLayout(FlowLayout.LEFT));
lCity = new JLabel("City");
String[] fillings = {"NY", "LA", "Columbia", "DC"};
cityBox = new JComboBox(fillings);
cityBox.addActionListener(new ActionListener() {
private String cityFilter;
@Override
public void actionPerformed(ActionEvent arg0) {
//2. get data
cityFilter = cityBox.getSelectedItem().toString();
}
});
selectionArea.add(lCity);
selectionArea.add(cityBox);
selectionArea.repaint();
return selectionArea;
}
private JScrollPane showTable() {
filterTable =new JTable(data, columnNames);
filterTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
scrollPane = new JScrollPane(filterTable);
scrollPane.repaint();
scrollPane.validate();
return scrollPane;
}
}
}
This is how the page looks like:
Any recommendations how to fix that?
What you are trying to do is nesting simple layout managers
to create your layout. I think that the official Swing tutorial
is doing a disservice to the programmers by introducing these
simple layout managers first. I recommend to avoid them and
invest some time into more powerful managers.
FlowLayout
, BorderLayout
and Gridlayout
are really very
simple managers but they cannot do much.
I recommend to use these two managers:
MigLayout
GroupLayout
(JGoodies's FormLayout
is also a good option.)
Not only are these managers more powerful, they also cope with more advanced requirements where others fail. (Resolution independence, adherence to OS design principles etc.)
Before I present my two code examples, I want to say a few
points to your code. You are unnecessarily calling repaint()
and revalidate()
methods.
setPreferredSize(new Dimension(1000, 500));
Specifying sizes in pixels is not portable. You better rely on
the pack()
method.
setLayout(new BorderLayout());
The JFrame's
default layout manager (more precisely its content pane's)
is BorderLayout
. Therefore, this line is not needed.
The following two examples are solutions with MigLayout
and GroupLayout
.
MigLayout solution
MigLayout
is a third-party layout manager, so you need to download and
add additional jar to your project.
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import net.miginfocom.swing.MigLayout;
public class MigLayoutEx extends JFrame {
private JComboBox cityBox;
private JTable filterTable;
public MigLayoutEx() {
initUI();
}
private void initUI() {
JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
add(tabbedPane);
filterTable = createTable();
cityBox = createCityBox();
JPanel pnl = new JPanel(new MigLayout(""));
pnl.add(new JLabel("City"), "split 2");
pnl.add(cityBox, "wrap");
pnl.add(new JScrollPane(filterTable));
tabbedPane.addTab("Test", pnl);
pack();
setTitle("MigLayout example");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private JTable createTable() {
String[] columnNames = {"Cities"};
String[][] data = {
{"NY"}, {"NY"}, {"NY"}, {"NY"}, {"LA"}, {"LA"}, {"Columbia"},
{"DC"}, {"DC"}, {"DC"}, {"DC"}, {"DC"}, {"DC"}
};
JTable table = new JTable(data, columnNames);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
return table;
}
private JComboBox createCityBox() {
String[] fillings = {"NY", "LA", "Columbia", "DC"};
JComboBox box = new JComboBox(fillings);
return box;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MigLayoutEx ex = new MigLayoutEx();
ex.setVisible(true);
}
});
}
}
GroupLayout solution
GroupLayout
is a built-in layout manager, no need to add additional jars.
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.GroupLayout;
import static javax.swing.GroupLayout.Alignment.BASELINE;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
public class GroupLayoutEx extends JFrame {
private JComboBox cityBox;
private JTable filterTable;
public GroupLayoutEx() {
initUI();
}
private void initUI() {
JPanel pnl = new JPanel();
GroupLayout gl = new GroupLayout(pnl);
pnl.setLayout(gl);
JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
add(tabbedPane);
JLabel cityLbl = new JLabel("City");
filterTable = createTable();
JScrollPane spane = new JScrollPane(filterTable);
cityBox = createCityBox();
gl.setAutoCreateGaps(true);
gl.setAutoCreateContainerGaps(true);
gl.setHorizontalGroup(gl.createParallelGroup()
.addGroup(gl.createSequentialGroup()
.addComponent(cityLbl)
.addComponent(cityBox))
.addComponent(spane)
);
gl.setVerticalGroup(gl.createSequentialGroup()
.addGroup(gl.createParallelGroup(BASELINE)
.addComponent(cityLbl)
.addComponent(cityBox))
.addComponent(spane)
);
tabbedPane.addTab("Test", pnl);
pack();
setTitle("GroupLayout example");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private JTable createTable() {
String[] columnNames = {"Cities"};
String[][] data = {
{"NY"}, {"NY"}, {"NY"}, {"NY"}, {"LA"}, {"LA"}, {"Columbia"},
{"DC"}, {"DC"}, {"DC"}, {"DC"}, {"DC"}, {"DC"}
};
JTable table = new JTable(data, columnNames);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
return table;
}
private JComboBox createCityBox() {
String[] fillings = {"NY", "LA", "Columbia", "DC"};
JComboBox box = new JComboBox(fillings);
return box;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
GroupLayoutEx ex = new GroupLayoutEx();
ex.setVisible(true);
}
});
}
}
I recommend to study both managers and to choose your favourite.