I have a main panel that looks like this:
JPnael mainPanel = new JPanel();
mainPanel .setLayout(new BorderLayout());
And I include sub panels, like this:
mainPanel.add(new JPanel(), BorderLayout.NORTH));
mainPanel.add(new JPanel(), BorderLayout.CENTER));
I want to create another JPanel, but not in BorderLayout, it needs to be absolute position. How can I do this?
Update:
I tried this variant, but it not suitable for BorderLayout
JPanel absPanel = new JPanel();
JLabel absLbl = new JLabel("aaaaaaaaa");
absPanel.setLayout(null);
absPanel.add(absLbl);
absPanel.setBounds(0, 0, 100, 100);
mainPanel.add(absPanel, ???);
It's not really clear what is the visual effect you're trying to achieve, but you may try using the layered pane
Related
I am trying to create a JPanel that is resizable & scrollable and contains x smaller inner panels. Each inner panel can be as wide as it wants/needs. BUT the depth should be a preferred size.
Like:
So far my code is:
public class TestSize {
public static void main(String[] args) {
JFrame F = new JFrame();
F.setVisible(true);
JPanel P = new JPanel();
P.setLayout(new BorderLayout());
JScrollPane scrollPane = new JScrollPane(P);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setPreferredSize(new Dimension(900,900));//.setBounds(50, 30, 300, 50);
JPanel S = new JPanel();
S.setBackground(Color.GREEN);
S.setPreferredSize(new Dimension(900,200));
JPanel S2 = new JPanel();
S2.setBackground(Color.GREEN);
S2.setPreferredSize(new Dimension(900,200));
P.add(S,BorderLayout.NORTH);
P.add(S2,BorderLayout.NORTH);
F.add(scrollPane);
F.pack();
F.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
But when I have added a single inner panel it fills all the space vertically - which is not what I want:
//P.setLayout(new BorderLayout());
Why did you set the layout to a BorderLayout? You can only add 1 component to the NORTH. Is that what you want? Read the section from the Swing tutorial on Using Layout Managers and pick a more appropriate layout manager. Bookmark the tutorial link as it provides the basics for Swing programming.
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
Why did you set these properties? These are the default values.
scrollPane.setPreferredSize(new Dimension(900,900));
Why would you set the height to be 900. You only want the scrollpane to contain components of height 200? In general you should NOT be setting the preferred size. Let the frame.pack() method do its job.
S.setBackground(Color.GREEN);
Why would you set the background color of both panels to be the same. How can you tell if the two panels get added? Make them different color for an easy visual.
In BoxLayout, there are different methods of using invisible components as filler. I don't think you will want to use a "rigid area", since I think you want to have a variable number of inner panels. You may want to try using vertical glue or custom Box.Filler.
Another solution might be to put a JPanel between your JFrame and your ScrollPane that uses a BorderLayout, and put the scrollpane in the BorderLayout.NORTH of that panel. Components in BorderLayout.NORTH get resized horizontally, but they do not get resized vertically. Essentially, they just get pushed to the top of the panel.
Edit:
I think you will want something like this:
JFrame F = new JFrame();
F.setVisible(true);
F.setLayout(new BorderLayout());
JPanel P = new JPanel(new BoxLayout(P, BoxLayout.PAGE_AXIS));
JScrollPane scrollPane = new JScrollPane(P);
JPanel S = new JPanel();
S.setBackground(Color.GREEN);
JPanel S2 = new JPanel();
S2.setBackground(Color.BLUE);
P.add(S);
P.add(S2);
F.add(scrollPane, BorderLayout.NORTH);
F.pack();
F.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
You said you want it resizeable, so I don't see why you would set the preferred size of the frame. This way it will just fit to the panels inside.
I try to order my elements with Borderlayout since Gridlayout makes everything the same size.
What I see is this:
while manually resizing it, I can have the following
Here's part of my code
public InputPanel() {
tfield = new TextField("Search your terms here!");
add(tfield, BorderLayout.PAGE_START);
searchButton = new JButton("Search");
searchButton.addActionListener(this);
add(searchButton, BorderLayout.LINE_START);
clearButton = new JButton("Clear Text");
clearButton.addActionListener(this);
add(clearButton, BorderLayout.LINE_END);
resultsArea = new TextArea();
add(resultsArea, BorderLayout.PAGE_END);
}
It seems like it does not help in arranging. It's just like I have used FlowLayout.
How can I format it properly?
For BorderLayout you should be using NORTH, SOUTH, EAST, WEST and CENTER to place your components. To achive the above layout, you should create one panel that has FLOWLAYOUT, where you add the textfield, seachbutton and clear button. This panel will then be placed inside BorderLayout.NORTH. After this you place the JTextArea inside BorderLayout.NORTH
public InputPanel() {
JPanel topPanel = new JPanel(); // Create a new panel
topPanel.setLayout(FlowLayout()); //Left to right alignment is default for FlowLayout
//Add your textfield and buttons to the panel with flowlayout
tfield = new TextField("Search your terms here!");
topPanel.add(tfield);
searchButton = new JButton("Search");
searchButton.addActionListener(this);
topPanel.add(searchButton);
clearButton = new JButton("Clear Text");
clearButton.addActionListener(this);
topPanel.add(clearButton);
add(topPanel, BorderLayout.NORTH); // Add the panel containing the buttons and textfield in the north
resultsArea = new TextArea();
add(resultsArea, BorderLayout.CENTER); //Add the textarea in the Center
}
This gives me the below appearance:
Seems you have missed GridBagLayout, which is the number one choice for a truly flexible layout manager. With BorderLayout you can also achieve a lot, but only with many levels of nesting, and the code to build it is quite unmanageable.
I have a simple problem when I want to add tabs in my jpanel. The alignment of the tabs get horizontal instead of vertical, wich looks like crap =/.
It looks like this:
If I discard the panel instead and add the tabbedPane directly to the frame, everything works fine.
If you uncomment the three lines of code and remove the getContentPane().add(jtp); you can reproduce my probleme.
working Code:
public class TabbedPane extends JFrame
{
public TabbedPane()
{
setTitle("Tabbed Pane");
setSize(300, 300); // set size so the user can "see" it
JTabbedPane jtp = new JTabbedPane();
// JPanel panel = new JPanel();//uncomment all three lines
// panel.add(jtp);
// getContentPane().add(panel);
getContentPane().add(jtp);//remove me
JPanel jp1 = new JPanel();// This will create the first tab
JPanel jp2 = new JPanel();// This will create the second tab
JLabel label1 = new JLabel();
label1.setText("This is Tab 1");
jp1.add(label1);
jtp.addTab("Tab1", jp1);
jtp.addTab("Tab2", jp2);
JButton test = new JButton("Press");
jp2.add(test);
setVisible(true); // otherwise you won't "see" it
}
public static void main(String[] args)
{
TabbedPane tab = new TabbedPane();
}
}
Thanks a lot!
If I discard the panel instead and add the tabbedPane directly to the frame, everything works fine.
The default layout of JPanel is FlowLayout, which "lets each component assume its natural (preferred) size." The default layout of JFrame is BorderLayout, the CENTER of which ignores preferred size. In either case, invoking setSize() precludes the layout from functioning initially; re-size the frame to see the effect. Instead, use pack(), which "Causes this Window to be sized to fit the preferred size and layouts of its subcomponents."
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setVisible(true); // otherwise you won't "see" it
There are many things I would change in that code, starting with the recommendations of #trashgod. OTOH this is the minimal change needed in order to stretch the tabbed pane to the width/height of the parent container.
// give the panel a layout that will stretch components to available space
JPanel panel = new JPanel(new GridLayout());//uncomment all three lines
panel.add(jtp);
getContentPane().add(panel);
//getContentPane().add(jtp);//remove me
For more details see this answer.
Well firstly you can try this:
JPanel panel = new JPanel();//uncomment all three lines
panel.setLayout(new GridLayout());
JPanel jp1 = new JPanel();// This will create the first tab
JPanel jp2 = new JPanel();// This will create the second tab
JLabel label1 = new JLabel();
label1.setText("This is Tab 1");
jp1.add(label1);
jtp.addTab("Tab1", jp1);
jtp.addTab("Tab2", jp2);
JButton test = new JButton("Press");
jp2.add(test);
getContentPane().add(jtp);
and in the main:
TabbedPane tab = new TabbedPane();
tab.pack();
tab.setVisible(true);
May I suggest using MigLayout to set layouts, it will make your life easier. Hope it helps.
Try GridbagLayout. Once you have mastered it, you can design UI of any sort with this layout.
I agree with prasanth regarding the use of GridBagLayout
I have gone through this problem once and I solved it by adding the JTabbedPaneto the panel via GridBagLayout, make sure you add the JTabbedPane using the ipadx and ipady according to your requirements in your GridBagConstraints object
e.g.
JPanel myPanel=new JPanel();
myPanel.setLayout(new GridBagLayout());
JTabbedPane jTP=new JTabbedPane();
jTP.add("Tab1",new JPanel());//substitute your component instead of "new JPanel"
GridBagConstraints myConstraints=new GridBagConstraints();
myConstraints.ipadx=400;//streches the component being added along x axis - 200 px on both sides
myConstraints.ipady=600;//streches the component being added along y axis - 200 px on both sides
myPanel.add(jTP,myConstraints);
You can adjust both these properties according to what is perfect for your need
Is there any way that I could add panels in bottom-to-top order?..
I've tried some layout managers, but still i couldn't get it..
need help.
JPanel mainpanel = new JPanel();
JPanel panel_1 = new JPanel();
JPanel panel_2 = new JPanel();
JPanel panel_3 = new JPanel();
mainpanel.add(panel_1);
mainpanel.add(panel_2);
mainpanel.add(panel_3);
mainpanel.add(panel_4);
mainpanel.add(panel_5);
mainpanel.add(panel_n);
You should be able to specify an index for adding the panel. Ie:
mainpanel.add(panel_1, 0);
mainpanel.add(panel_2, 0);
mainpanel.add(panel_3, 0);
This will always add each panel in the first position.
MigLayout works here as well - and increases maintainabilty:
JPanel mainpanel = new JPanel(new MigLayout();
private void addPanel(JPanel newPanel) {
mainpanel.add(newPanel, "dock north");
}
Add the panel in order, In which order you want to display in the frame.
Let p1,p2,p3 are the subv-panels and p is main panel.
You want order of panel as folowing : p2,p3,p1
p.add(p2);
p.add(p3);
p.add(p1);
then finally add it to your frame.
I think this will help you.
I have a JTextField, and right below it I want to show a JLabel placed in a JLayeredPane (I will use it for autosuggestions later on).
How can I place my JLabel in JLayeredPane right below the JTextField?
Here is some code I have, and the current result shown in the screenshot below:
public static void main(String[] args) {
JTextField field = new JTextField();
JLabel lbl = new JLabel("Hello");
lbl.setBackground(Color.YELLOW);
lbl.setOpaque(true);
JLayeredPane layeredPane = new JLayeredPane();
layeredPane.setLayout(new GridLayout(0,1));
layeredPane.add(lbl, (Integer) (JLayeredPane.POPUP_LAYER - 10));
layeredPane.setPreferredSize(field.getPreferredSize());
JPanel panel = new JPanel(new BorderLayout());
panel.add(field, BorderLayout.NORTH);
panel.add(layeredPane, BorderLayout.SOUTH);
JFrame frame = new JFrame();
frame.add(panel);
frame.setSize(200, 360);
frame.setVisible(true);
}
Second try:
public static void main(String[] args) {
JTextField field = new JTextField();
JLabel lbl = new JLabel("Hello");
lbl.setBackground(Color.YELLOW);
lbl.setOpaque(true);
lbl.setBounds(field.getBounds().x, field.getBounds().y,
field.getBounds().width, field.getBounds().height);
JPanel popPanel = new JPanel(new BorderLayout());
popPanel.add(lbl, BorderLayout.NORTH);
popPanel.setLocation(field.getLocation().x+10, field.getLocation().y+20);
popPanel.setPreferredSize(field.getPreferredSize());
JFrame frame = new JFrame();
JLayeredPane layeredPane = frame.getRootPane().getLayeredPane();
layeredPane.setLayout(new GridLayout(0,1));
layeredPane.add(popPanel, (Integer) (JLayeredPane.POPUP_LAYER - 10));
JPanel panel = new JPanel(new BorderLayout());
panel.add(field, BorderLayout.NORTH);
frame.add(panel);
frame.setSize(200, 360);
frame.setVisible(true);
}
Add the layeredPane to the "CENTER", not the SOUTH.
However, your understanding a layed pane seems to be a little confused. You use a layered pane when you want multiple components to be displayed on top (stacked?) of one another. You are still using the layered pane in 2 dimensions which is unnecessary. YOu can just use a panel for this.
If you want to popup a list of suggestions then you should just use a JPopupMenu and position it below the text field. Read the section from the Swing tutorial on Bringing up Popup Menus.
First of all, I don't think you should use a JLayeredPane for that, but just a permanent label.
If you do use a layered pane, you'll have to compute where the text field ends (y = field.getY() + field.getHeight()) and set your JPanel at 'panel.setLocation(0, y)' inside the JLayeredPane (provided the JLayeredPane has the same starting position as the underlying JFrame). You could equivalently position the JLayeredPane at (0, y) and put the label at (0, 0) within that layered pane.
You have to make sure this is done every time the components are resized.
why not using AutoComplete ComboBox / JTextField and if you don't want to display JComboBox, then there is AutoCompleted JTextField, and for somehow reduced autosuggestions, would be better look for undecorated JDialog/Window with JTable with one TableColum and without TableHeaded in the JScrollPane, just with plain RowSorter, very simle job