Reputation: 2316
I'm building an application which will consist of few tabbed panels. On each of them, I'd like to put sets of components separated from each other by borders. It would look like:
|- Titled Border 1 ---
[JTextField] [JComboBox] [JTextField] [JComboBox]
|--------
|- Titled Border 2 ---
[JTextField] [JComboBox] [JTextField] [JComboBox]
|--------
... and so forth.
When I tried to simply add new border, Titled Border 2, to the panel, it was added and covered the first one leaving components on top though. In some examples I saw many JPanels defined within one frame and each panel had its own border. It might work in my case but how to add these panels to be displayed within one tab?
One of Oracle's tutorials shows exactly a tabbed pane with demo of many kinds of borders. When I tried to edit it and put a component there, it appeared between two borders instead of being surrounded. And it was another option that was unsuccessful for me.
Second thing is, I don't use any layout manager, components positions are fixed and honestly I would keep this setting. Or maybe you recommend using any layout manager in this specific case?
Would you have any hints on how to solve this problem?
Edit: it seems I'm not allowed yet to attach a screenshot, but here's the part of code taking care of displaying the borders:
lenMicro = new JPanel();
lenMicro.setLayout(null);
bGreyLine = BorderFactory.createLineBorder(Color.GRAY, 1, true);
bTitled1 = BorderFactory.createTitledBorder(bGreyLine, "Length (1/2)", TitledBorder.LEFT, TitledBorder.TOP);
lenMicro.setBorder(bTitled1);
bTitled2 = BorderFactory.createTitledBorder(bGreyLine, "Length (2/2)", TitledBorder.LEFT, TitledBorder.TOP);
lenMicro.setBorder(bTitled2);
The border titled "Length (2/2)" is displayed when the last two lines are uncommented.
Upvotes: 8
Views: 47101
Reputation: 2316
OK, so this solves a big part of my concerns regarding usage of Layout Manager and adding borders to groups of components:
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import java.awt.*;
public class TestingGround extends JFrame {
private JTextField tLenUnit, tLenResult, tAreUnit, tAreResult;
private JComboBox<String> cLenInUnit, cLenOutUnit, cAreInUnit, cAreOutUnit;
private JPanel lenMicro, lenMicro1, lenMicro2, lenNormal, lenMacro, area, volume;
private Border bGreyLine, bTitled1, bTitled2;
private TestingGround() {
setTitle("Testing Ground for an Application");
setVisible(true);
setResizable(true);
setLocationRelativeTo(null);
try {
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
lenMicro = new JPanel();
lenMicro.setLayout(new GridBagLayout());
lenMicro1 = new JPanel();
lenMicro1.setLayout(new GridBagLayout());
bGreyLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1, true);
bTitled1 = BorderFactory.createTitledBorder(bGreyLine, "Length", TitledBorder.LEFT, TitledBorder.TOP);
lenMicro1.setBorder(bTitled1);
tLenUnit = new JTextField("0.0");
tLenUnit.setColumns(10);
lenMicro1.add(tLenUnit, new GBC(0, 0, 2, 1).setAnchor(GBC.WEST).setInsets(5, 5, 5, 5));
cLenInUnit = new JComboBox<String>();
cLenInUnit.addItem("");
cLenInUnit.addItem("First");
cLenInUnit.addItem("Second");
cLenInUnit.setSelectedIndex(0);
cLenInUnit.setPreferredSize(new Dimension(120, 25));
lenMicro1.add(cLenInUnit, new GBC(2, 0, 3, 1));
tLenResult = new JTextField("");
tLenResult.setColumns(10);
lenMicro1.add(tLenResult, new GBC(5, 0, 2, 1).setInsets(5, 5, 5, 5));
cLenOutUnit = new JComboBox<String>();
cLenOutUnit.addItem("First");
cLenOutUnit.addItem("Second");
cLenOutUnit.setSelectedIndex(1);
cLenOutUnit.setPreferredSize(new Dimension(120, 25));
lenMicro1.add(cLenOutUnit, new GBC(7, 0, 1, 1));
// Area part:
lenMicro2 = new JPanel();
lenMicro2.setLayout(new GridBagLayout());
bTitled2 = BorderFactory.createTitledBorder(bGreyLine, "Area", TitledBorder.LEFT, TitledBorder.TOP);
lenMicro2.setBorder(bTitled2);
tAreUnit = new JTextField("0.0");
tAreUnit.setColumns(10);
lenMicro2.add(tAreUnit, new GBC(0, 1, 2, 1).setAnchor(GBC.WEST).setInsets(5, 5, 5, 5));
cAreInUnit = new JComboBox<String>();
cAreInUnit.addItem("");
cAreInUnit.addItem("One sqm");
cAreInUnit.addItem("Two sqm");
cAreInUnit.setSelectedIndex(0);
cAreInUnit.setPreferredSize(new Dimension(120, 25));
lenMicro2.add(cAreInUnit, new GBC(2, 1, 3, 1));
tAreResult = new JTextField("");
tAreResult.setColumns(10);
lenMicro2.add(tAreResult, new GBC(5, 1, 2, 1).setInsets(5, 5, 5, 5));
cAreOutUnit = new JComboBox<String>();
cAreOutUnit.addItem("One sqm");
cAreOutUnit.addItem("Two sqm");
cAreOutUnit.setSelectedIndex(1);
cAreOutUnit.setPreferredSize(new Dimension(120, 25));
lenMicro2.add(cAreOutUnit, new GBC(7, 1, 1, 1));
// Joining all lenMicroX panels into one:
lenMicro.add(lenMicro1, new GBC(0, 0, 8, 1).setAnchor(GBC.FIRST_LINE_START).setInsets(5, 5, 5, 5).setIpad(10, 10));
lenMicro.add(lenMicro2, new GBC(0, 1, 8, 1).setAnchor(GBC.LINE_START).setInsets(5, 5, 5, 5).setIpad(10, 10));
volume = new JPanel();
volume.setLayout(null);
// Panel definition --begin:
JTabbedPane tPane = new JTabbedPane();
tPane.addTab("Length & Area", null, lenMicro, "Length & Area units");
tPane.addTab("Volume", null, volume, "Volume units");
add(tPane);
// Panel --end.
}
public static void main(String[] args) {
TestingGround app = new TestingGround();
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.pack();
app.setVisible(true);
}
}
GridBagConstraints helper class is taken from Cay Horstmann's and Gary Cornell's Core Java and can be found here: http://www.horstmann.com/articles/GBC.java.
I managed to figure out from Gagandeep's example that panels can be put on top of, let's call it a mother-panel. This way each of child-panels can have its own border.
Second thing: I decided to use GridBagLayout, as it seems to be the most accurate to be used in this and further projects of mine. Well, I still have to learn a lot about it (for example, in order to make the components aligned to some lines ;-) [edit: just added setPreferredSize() to JComboBoxes; makes the layout better-looking ;-)]).
Thank you Everyone for help and valuable hints!
Upvotes: 3
Reputation: 24626
When using Absolute Positioning, you have to provide Location for each and every component, that will become a part of the view. Hence without looking at exactly what you doing it's hard to predict where exactly the things are going wrong. Though using Layout Managers, will remove this big burden off your shoulders regarding placement of different components on the view.
Moreover, you have to set the border for the respective component. So in no way I can assume that you added one component and it appeared between two borders (though considering the fact that you using Absolute Positioning, you might have given the wrong Co-ordinates for the said component on the view). Please have a look at this example code, that might can help you a bit in this direction :
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class BorderExample
{
private JPanel topPanel;
private JPanel centerPanel;
private JPanel bottomPanel;
private int hgap;
private int vgap;
private JTextField tfield1, tfield2;
private JComboBox cbox1, cbox2;
private String[] data = {"One", "Two"};
public BorderExample()
{
hgap = 5;
vgap = 5;
}
private void displayGUI()
{
JFrame frame = new JFrame("Border Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setOpaque(true);
contentPane.setBackground(Color.WHITE);
contentPane.setBorder(
BorderFactory.createEmptyBorder(hgap, hgap, hgap, hgap));
contentPane.setLayout(new BorderLayout(hgap, vgap));
topPanel = new JPanel();
topPanel.setOpaque(true);
topPanel.setBackground(Color.WHITE);
topPanel.setBorder(
BorderFactory.createTitledBorder("Top Panel"));
tfield1 = new JTextField(10);
tfield1.setBorder(
BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(
EtchedBorder.RAISED, Color.GRAY
, Color.DARK_GRAY), "JTextField"));
JPanel comboPanel = new JPanel();
cbox1 = new JComboBox(data);
cbox1.setBorder(
BorderFactory.createTitledBorder("JComboBox"));
topPanel.add(tfield1);
topPanel.add(cbox1);
centerPanel = new JPanel();
centerPanel.setOpaque(true);
centerPanel.setBackground(Color.WHITE);
centerPanel.setBorder(
BorderFactory.createTitledBorder("Center Panel"));
tfield2 = new JTextField(10);
tfield2.setBorder(
BorderFactory.createLoweredBevelBorder());
cbox2 = new JComboBox(data);
cbox2.setBorder(
BorderFactory.createRaisedBevelBorder());
centerPanel.add(tfield2);
centerPanel.add(cbox2);
bottomPanel = new JPanel();
bottomPanel.setOpaque(true);
bottomPanel.setBackground(Color.WHITE);
bottomPanel.setBorder(
BorderFactory.createTitledBorder("Center Panel"));
contentPane.add(topPanel, BorderLayout.PAGE_START);
contentPane.add(centerPanel, BorderLayout.CENTER);
contentPane.add(bottomPanel, BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
new BorderExample().displayGUI();
}
});
}
}
Here is the output of the same :
Upvotes: 18