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
Related
I'm trying to create a pretty simple application that has a JSplitPane (which is divided into a JTabbedPane and a JPanel) above a status bar panel. I want to use a simple layout (i.e. BoxLayout, FlowLayout, or BorderLayout), but I've tried and they all give me the same error. I've simplified the code as much as possible to show the error.
The error is that there should only be 2 regions in the main box layout (the frame): a top (with the JSplitPane, which has the black border) and a bottom (with the JPanel status bar). However, when I add the status bar, a third region is created in the upper left that contains nothing. Any ideas on how to get rid of it?
public static void main(String[] args) {
JFrame frame = new JFrame("Application");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
// Create left side of the application
JTabbedPane tabby = new JTabbedPane(JTabbedPane.LEFT);
// Create right side of the application
JPanel rightPanel = new JPanel(new BorderLayout());
// Create the status bar at the bottom
JPanel statusBar = new JPanel(new BorderLayout());
JPanel statusBarPanel = new JPanel();
statusBarLabel = new JLabel("Status Bar");
statusBarPanel.add(statusBarLabel);
parent.add(statusBarPanel);
JSplitPane mainPain = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, tabby, rightPanel);
frame.add(mainPain);
frame.add(statusBar);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
I'm trying to create a pretty simple application that has a JSplitPane (which is divided into a JTabbedPane and a JPanel) above a status bar panel.
Normally you would just use the default BorderLayout of the frame and then do:
frame.add(splitPane, BorderLayout.CENTER);
frame.add(statusBar, BorderLayout.PAGE_END);
A status bar is typically one or more labels that display information so they are display in a fixed size at the bottom.
The other panel will then contain the main components of the application. These components will then get any extra space available to the frame as it is resized.
but I've tried and they all give me the same error
parent.add(statusBarPanel);
The variable "parent" doesn't exist. Get rid of it. Add the status bar to the frame as shown above.
not sure if thats it, but it seems, like you add 2 Panels when adding the Statusbar.
You got a statusBarPanel which is added to "parent", and statusBar, which is added to the frame itself. Maybe thats your 3rd Panel.
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.
Is it possible to show a Panel (e.g. Panel-A which is nearly transparent) over a panel that has a GridLayout of images?
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel gridOfImages = new JPanel(new GridLayout(3,3));//Panel with a grid of images
JPanel nearlyOpaquePanel = new JPanel(); //A panel that is almost transparent.
// assuming that all already have the required properties like size and colour.
mainPanel.add(gridOfImages,Borderlayout.CENTER);
mainPanel.add(nearlyOpaquePanel,BorderLayout.CENTER);
My thought with this idea is that the panels will stack together and the gridOfImages will be shown through the nearlyOpaquePanel, but my result is that I only got the nearlyOpaquePanel to show and I can't see the gridOfImages through it.
See How to Decorate Components with the JLayer Class
How can I get the scroller around my JList component in the code given below? It doesn't seem to work properly :(
public class JButtonO extends JFrame{
String[] values = {"henry", "Michael","Uche","John","Ullan","Nelly",
"Ime","Lekan","Austine","jussi","Ossi","Imam","Empo","Austine","Becky",
"Scholar","Ruth", "Anny"};
public JButtonO()
{
super("the button");
this.setSize(400,200);
JPanel panel = new JPanel();
JLabel label = new JLabel("Output Items:");
label.setAlignmentX(1);
label.setAlignmentY(1);
JList conList = new JList(values);
conList.setVisibleRowCount(3);
JScrollPane scroller = new JScrollPane(conList);
panel.add(label);
panel.add(scroller);
panel.add(conList);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(panel);
this.setVisible(true);
}
Adding the JScrollPane scroller that includes the JList conList to the JPanel panel is enough.
The mistake is that you are adding the JList a second time.
JScrollPane scroller = new JScrollPane(conList);
panel.add(label);
panel.add(scroller);
panel.add(conList); // <---THIS LINE SHOULD BE DELETED...
Look, I may not answering what you need, because I don´t remember to much of swing layout. I don´t work with it a long time ago...
But removing setting a layout (I remember) on your JPanel it works with this code:
public JButtonO() {
super("the button");
this.setSize(400, 200);
// Create a panel with a borderlayout
JPanel jpanel = new JPanel(new BorderLayout());
JLabel label = new JLabel("Output Items:");
label.setAlignmentX(1);
label.setAlignmentY(1);
// Add Label to top of layout
jpanel.add(label, BorderLayout.NORTH);
JList conList = new JList(values);
conList.setVisibleRowCount(3);
JScrollPane scroller = new JScrollPane(conList);
//AddScroll to center
jpanel.add(scroller);
//Add Panel to JFrame
this.add(jpanel);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
I think the problems is the default layoutmaneger of JPanel. Because of how it works your scroll was not "srink" enough to create scrolls...
Hope it helps, even without too much explanation...
ACTUALLY: After I post the answer I saw your mistake. Now I can explain what is wrong. You already added your JList inside your JScrollPane here:
JScrollPane scroller = new JScrollPane(conList);
But after that you put it inside the JPanel:
panel.add(conList);
this changes where yout JList will be displayed, and let the JScroll empty again. Without components it will be displayed with size 0x0 and will not be draw (even being there).
Now I think I helped =D
The JScrollPane has settings called the scrollbar policies which say when the scrollbars are to be displayed. You can set them using JScrolPane(Component,int,int) constructor, or by calling setVerticalScrollBarPolicy() and setHorizontalScrollBarPolicy(). The default policies are "as needed", meaning the scrollbar is only displayed if the component is too large to display whole. So if your list fits inside the window, the scrolbars will not be visible, but will become visible when you e.g. make the window smaller using the mouse. You can change one or both policies to "always" using corresponding constants in order to make the scrollbar(s) always visible if that's what you need.
I have a JPanel subclass on which I add buttons, labels, tables, etc. To show on screen it I use JFrame:
MainPanel mainPanel = new MainPanel(); //JPanel subclass
JFrame mainFrame = new JFrame();
mainFrame.setTitle("main window title");
mainFrame.getContentPane().add(mainPanel);
mainFrame.setLocation(100, 100);
mainFrame.pack();
mainFrame.setVisible(true);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
But when I size the window, size of panel don't change. How to make size of panel to be the same as the size of window even if it was resized?
You can set a layout manager like BorderLayout and then define more specifically, where your panel should go:
MainPanel mainPanel = new MainPanel();
JFrame mainFrame = new JFrame();
mainFrame.setLayout(new BorderLayout());
mainFrame.add(mainPanel, BorderLayout.CENTER);
mainFrame.pack();
mainFrame.setVisible(true);
This puts the panel into the center area of the frame and lets it grow automatically when resizing the frame.
You need to set a layout manager for the JFrame to use - This deals with how components are positioned. A useful one is the BorderLayout manager.
Simply adding the following line of code should fix your problems:
mainFrame.setLayout(new BorderLayout());
(Do this before adding components to the JFrame)
If the BorderLayout option provided by our friends doesnot work, try adding ComponentListerner to the JFrame and implement the componentResized(event) method. When the JFrame object will be resized, this method will be called. So if you write the the code to set the size of the JPanel in this method, you will achieve the intended result.
Ya, I know this 'solution' is not good but use it as a safety net.
;)
From my experience, I used GridLayout.
thePanel.setLayout(new GridLayout(a,b,c,d));
a = row number, b = column number, c = horizontal gap, d = vertical gap.
For example, if I want to create panel with:
unlimited row (set a = 0)
1 column (set b = 1)
vertical gap= 3 (set d = 3)
The code is below:
thePanel.setLayout(new GridLayout(0,1,0,3));
This method is useful when you want to add JScrollPane to your JPanel. Size of the JPanel inside JScrollPane will automatically changes when you add some components on it, so the JScrollPane will automatically reset the scroll bar.
As other posters have said, you need to change the LayoutManager being used. I always preferred using a GridLayout so your code would become:
MainPanel mainPanel = new MainPanel();
JFrame mainFrame = new JFrame();
mainFrame.setLayout(new GridLayout());
mainFrame.pack();
mainFrame.setVisible(true);
GridLayout seems more conceptually correct to me when you want your panel to take up the entire screen.