How to Center Jpanel in JFrame? - java

There is a class which extends JFrame. then Further JFrame have JPanel named contentPane and this Jpanel contains 2 more jpanel. as Tree shown in picture.
I Want to Center that contentPane in JFrame so that on changing size of JFrame JPanel (contentPane) will remain in center. I have tried with different Layouts but did not come up with right one. is there any way ?
Full page picture is here
Code is this.
public class Purchases extends JFrame {
private JPanel contentPane;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Purchases frame = new Purchases();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 513, 438);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
setLocationRelativeTo(null);
JPanel panel = new JPanel();
panel.setBounds(10, 10, 477, 193);
contentPane.add(panel);
panel.setLayout(null);
JPanel panel_1 = new JPanel();
panel_1.setBounds(10, 214, 477, 174);
contentPane.add(panel_1);
panel_1.setLayout(null);
}
This code is Eclipse automatically generated. I did not find where the contentPane is added in JFrame.

Set the frame's layout to GridBagLayout. Wrap your existing content in another JPanel, add this panel to the frame
For example
Take a look at Laying Out Components Within a Container and How to Use GridBagLayout for more details
You really should avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify

I have made a sample for you. Modify it as per your need. Just want to show you what you want, is working.
TestClass()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 513, 438);
contentPane = new JPanel();
contentPane.setLayout(new BorderLayout());
JButton b1 = new JButton("hello");
JPanel panel = new JPanel(new BorderLayout());
//panel.setBounds(10, 10, 477, 193);
panel.add(b1, BorderLayout.CENTER);
contentPane.add(panel, BorderLayout.EAST);
//panel.setLayout(null);
JButton b2 = new JButton("why");
JPanel panel_1 = new JPanel(new BorderLayout());
//panel_1.setBounds(10, 214, 477, 174);
panel_1.add(b2, BorderLayout.CENTER);
contentPane.add(panel_1, BorderLayout.WEST);
//panel_1.setLayout(null);
this.getContentPane().add(contentPane);
}
Hope this will help. :-)

I think you should set the maximum size of the element & set it to align center:
setAlignmentX(JComponent.CENTER_ALIGNMENT);
setMaximumSize(new Dimension(100, 100));
As explained here:
How can I properly center a JPanel ( FIXED SIZE ) inside a JFrame?

Related

Java Swing Scrollpane not scrolling

I want to be able to scroll down a dynamically generated list of movies. I tried adding a Scrollpane.
I have a navigation bar at the page start and in the center a jpanel with all the movies.
You can recreate this example by using this code:
private static JFrame frame;
public static void main(String[] args) throws HeadlessException {
frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.setBackground(new Color(32, 32, 32));
JPanel navigationPanel = createNavigationBar();
frame.add(navigationPanel, BorderLayout.PAGE_START);
JPanel moviePanel = createMoviePanel();
frame.add(moviePanel, BorderLayout.CENTER);
frame.setPreferredSize(new Dimension(1920, 1080));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Example App");
frame.pack();
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
}
// MoviePanel Class
public static JPanel createMoviePanel() {
JPanel parentMoviePanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 25));
JPanel contentPanel = new JPanel(new GridLayout(0, 1));
JPanel moviePanel = new JPanel(new GridLayout(0, 9, 8, 5));
JScrollPane scrollPane = new JScrollPane(moviePanel);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.getVerticalScrollBar().setPreferredSize(new Dimension(0, 0));
scrollPane.setBorder(new EmptyBorder(0, 0, 0, 0));
parentMoviePanel.setBackground(new Color(32, 32, 32));
contentPanel.setBackground(new Color(32, 32, 32));
moviePanel.setBackground(new Color(32, 32, 32));
final File root = new File("");
for (int i = 0; i < 70; i++) {
// Get the image and scale it down
BufferedImage movieCover=new BufferedImage(150,200,BufferedImage.TYPE_INT_RGB);
Graphics2D g2d=(Graphics2D)movieCover.getGraphics();
g2d.setColor(Color.GRAY);
g2d.fillRect(0,0,movieCover.getWidth(),movieCover.getHeight());
// Create button and change settings
JButton movieButton = new JButton("Movie " + i, new ImageIcon(movieCover));
movieButton.setMargin(new Insets(0, 0, 0, 0));
movieButton.setPreferredSize(new Dimension(180, 250));
movieButton.setForeground(Color.WHITE);
movieButton.setContentAreaFilled(false);
movieButton.setBorderPainted(false);
movieButton.setFocusPainted(false);
movieButton.setHorizontalTextPosition(JButton.CENTER);
movieButton.setVerticalTextPosition(JButton.BOTTOM);
moviePanel.add(movieButton);
scrollPane.revalidate();
}
contentPanel.add(moviePanel);
contentPanel.add(scrollPane);
parentMoviePanel.add(contentPanel);
return parentMoviePanel;
}
// Navbar Class
public static JPanel createNavigationBar() {
JPanel navBar = new JPanel();
navBar.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 20));
navBar.setBackground(new Color(25, 25, 25));
JButton homeButton = new JButton("Home");
homeButton.setContentAreaFilled(false);
homeButton.setBorderPainted(false);
homeButton.setFocusPainted(false);
JButton movieButton = new JButton("Movies");
movieButton.setContentAreaFilled(false);
movieButton.setBorderPainted(false);
movieButton.setFocusPainted(false);
// Add all the buttons to the navbar
navBar.add(homeButton);
navBar.add(movieButton);
return navBar;
}
What I'm trying to do is to scroll down this list of movies, using my mouse wheel without seeing any kind of scrollbar. It should look exactly how it looks now, but I want to be able to scroll down and see all the movies.
I don't know why it isn't working that's why I'm asking here in hope someone can explain to me what I'm doing wrong.
Your usage of a scroll pane is incorrect.
A Swing component can only have a single parent. The following code is creating the scroll pane with a child component. However you then remove the moviePanel from the scroll pane when you add it to the content pane.
So the scroll pane has no child component and will never work.
JScrollPane scrollPane = new JScrollPane(moviePanel);
...
contentPanel.add(moviePanel);
contentPanel.add(scrollPane);
However, even that won't solve your problem because you are now using a FlowLayout on your top level panel so all the child components will always be displayed at their preferred size so there is no need for scroll bars.
Get rid of all the scroll pane logic in your createMoviePanel() method.
Instead you probably want to add the scroll pane to the content pane:
//frame.add(moviePanel, BorderLayout.CENTER);
frame.add(new JScrollPane(moviePanel), BorderLayout.CENTER);
Now the scroll pane will dynamically resize as the frame size changes. Scrollbars will then appear as required.

Trying to add ScrollPane in Jpanel with null layout inside BorderLayout

I am trying to add a scrollbar in jpanel with null layout.
I want to create a form. This should should display few buttons at the bottom at all times.Any content inside form should maintain it's size and ratio even if the parent container is resized.
Here is what I've come with. I have a panel with borderlayout and added buttons at the south of border. Then created another jpanel to contain form that is added at the center of parent jpanel. Since I want form to maintain it's ratio I went with null layout for inner panel. But I want it to display scrollbar when content is not fully visible. enter image description here
Now adding inner jpanel into scrollpane and adding scrollpanel into parent panel (.add(scrollpane, BorderLayout.CENTER)) doesn't give desired format.
Is there any thing that I can do to get desired format?
Here is code Sample:
public static void main(String[] args) {
JFrame jFrame = new JFrame();
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setSize(new Dimension(1000, 700));
Container c = jFrame.getContentPane();
c.setLayout(new BorderLayout());
bottomPanel(c);
centerPanel(c); //scrollbar should go in this panel
jFrame.setVisible(true);
}
private static void centerPanel(Container c) {
JPanel centerPanel = new JPanel();
centerPanel.setLayout(null);
JButton button = new JButton("This jObject should not resize when window resizes and also should maintain relative position.");
button.setBounds(new Rectangle(10, 10, 600, 50));
JButton button1 = new JButton("Just like it works in this code. Just Add ScrollPane to centerPanel That is in green backround");
button1.setBounds(new Rectangle(10, 70, 600, 50));
JButton button2 = new JButton("For clearity");
button2.setBounds(new Rectangle(10, 130, 600, 50));
centerPanel.add(button);
centerPanel.add(button1);
centerPanel.add(button2);
centerPanel.setBackground(Color.GREEN);
c.add(centerPanel, BorderLayout.CENTER);
}
private static void bottomPanel(Container c) {
JPanel bottomPanel = new JPanel(); //Buttons that goes at the bottom of screen will go in here
JPanel bottomInnerPanel = new JPanel();
bottomInnerPanel.setLayout(new BorderLayout());
bottomPanel.setLayout(new GridLayout());
bottomInnerPanel.add(new JButton("Add"), BorderLayout.WEST);
bottomInnerPanel.add(new JButton("Search"), BorderLayout.EAST);
bottomPanel.add(bottomInnerPanel);
bottomPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
c.add(bottomPanel, BorderLayout.SOUTH);
}

Move a JLabel inside of JPanel without losing hierarchy

So I'm moving a JLabel inside of JPanel and I want the JPanel to automatically show scrolls bars that lead you to the JLabel wich I moved out of it.
The problem is that when I set the new JLabel location and this location is out of the JPanel, it loses its hierarchy so the JLabel stops being part of the JPanel and as a result the panel doesn't scrolls and you can't see the JLabel. So this is my code if you can tell how can I do this. Thanks.
//Panel creation
JPanel panel = new JPanel();
panel.setSize(500, 500);
panel.setAutoscrolls(true);
//Label creation
JLabel label = new JLabel();
label.setText("Hi");
label.setSize(40, 40);
//Adding Jlabel to Panel
panel.add(label);
label.setLocation(800, 200);//this invalidates inherancy
What you need to do it encapsulate the JPanel inside a JScrollPane and increase its size with setPreferredSize()
Note that using setSize() setWidth() or setHeight() will be ignored by the scroll pane
A example code of how to set it up follows:
public class TestFrame extends JFrame {
public TestFrame() {
setLayout(null);
setSize(500, 500);
JPanel panel = new JPanel();
panel.setBackground(Color.BLUE);
JScrollPane scroll = new JScrollPane();
scroll.setViewportView(panel);
add(scroll);
scroll.setBounds(100, 100, 200, 200);
panel.setPreferredSize(new Dimension(800, 800));
}
public static void main(String[] args) {
TestFrame frame = new TestFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
In this example, the JScrollPane is fixed with 200x200 size, while the JPanel inside it has a size of 800x800. You can change this value dynamically as you move your JLabel around.
Also, I'd like to mention that null layouts is not the correct approach. In this example, I wanted to minimize the influence of LayoutManagers and underlying calls to setBounds() by them to emphasize the point I'm trying to get across, which is a pure change of size inside a JScrollPane. The whole JFrame is just a "vessel" for the example.

What am I doing wrong with setVertical/HorizantalAlignment?

I am playing around with Java GUIs, and I came across JLabel.setVerticalAlignment. I have set something up so that curlLeft and curlRight would go to the corners. However, it does not seem to have ny effect. Why is that so?
private void prepareGUI() throws IOException {
mainFrame = new JFrame("Holy Bible");
mainFrame.setSize(700, 500);
mainFrame.setLayout(new GridLayout(1, 2));
mainFrame.setLocationRelativeTo(null);
mainFrame.setIconImage(new ImageIcon(getClass().getResource("/assets/bible/textures/icon.png")).getImage());
mainFrame.getContentPane().setBackground(Color.WHITE);
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent) {
System.exit(0);
}
});
mainFrame.addKeyListener(this);
leftPanel = new JPanel();
leftPanel.setBackground(Color.WHITE);
leftPanel.setLayout(new FlowLayout());
rightPanel = new JPanel();
rightPanel.setBackground(Color.WHITE);
rightPanel.setLayout(new FlowLayout());
leftLabel = new JLabel("", JLabel.CENTER);
leftLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 12));
leftPanel.add(leftLabel);
rightLabel = new JLabel("", JLabel.CENTER);
rightLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 12));
rightPanel.add(rightLabel);
leftCurl = new JLabel();
leftCurl.setHorizontalAlignment(JLabel.LEFT);
leftCurl.setVerticalAlignment(JLabel.BOTTOM);
leftCurl.setIcon(new ImageIcon(getClass().getResource("/assets/bible/textures/curlleft15.png")));
leftPanel.add(leftCurl);
rightCurl = new JLabel();
rightCurl.setHorizontalAlignment(JLabel.RIGHT);
rightCurl.setVerticalAlignment(JLabel.BOTTOM);
rightCurl.setIcon(new ImageIcon(getClass().getResource("/assets/bible/textures/curlright15.png")));
rightPanel.add(rightCurl, BorderLayout.SOUTH);
mainFrame.add(leftPanel);
mainFrame.add(rightPanel);
mainFrame.setExtendedState(JFrame.MAXIMIZED_BOTH); // Maximizes frame
mainFrame.setUndecorated(fullScreen);
mainFrame.setVisible(true);
}
All the variables needed are initialized at class level.
Your JLabels are not going to the corners because you are adding them to JPanels that have a FLowLayout. With FlowLayout your components don't occupy the 100% of the space of the JPanel, they only occupy the necessary.
I changed the 2 FlowLayouts to GridLayouts and now I can see the different orientations.
(Also, as your objective is learning how this works, I recommend you set a border on each component so you can see where their bounds are. This is quite good for understanding Swing's layout management).

Dynamically resize outer JPanel depending on JPanels inner JTextPane height

I have a JTextPane inside a JPanel, this JTextPane is at runtime being populated with text. I want the JPanel that is holding the JTextPane to dynamically change in height when JTextPane gets more than one line of text.
This is what ive got so far:
pnlChatMsgs = new JPanel(new BorderLayout());
pnlChatMsgs.setBackground(new java.awt.Color(244, 244, 244));
pnlMainTable.add(pnlChatMsgs, c);
pnlMidLiveType = new JPanel(new BorderLayout());
pnlMidLiveType.setPreferredSize(new Dimension(100, 30));
JTextPane.setFont(new java.awt.Font("Lucida Grande", 0, 13));
JTextPane.setText("<html></html>");
JTextPane.setContentType("text/html");
JTextPane.setForeground(new java.awt.Color(153, 153, 153));
JTextPane.setBackground(new java.awt.Color(250, 250, 250));
pnlMidLiveType.add(JTextPane, BorderLayout.NORTH);
pnlChatMsgs.add(pnlMidLiveType, BorderLayout.SOUTH);
pnlMidLiveType.setVisible(false);
So when JTextPane grows in size i want to change the height of the pnlMidLiveType JPanel.
How could i accomplish this?
Consider the following example. It demonstrates expandable JFrame and JPanel:
final JFrame frame = new JFrame();
JPanel panel = new JPanel(new BorderLayout());
JTextPane pane = new JTextPane();
pane.addKeyListener(new KeyAdapter() {
#Override
public void keyTyped(KeyEvent e) {
frame.pack();
}
});
panel.add(pane, BorderLayout.CENTER);
frame.setContentPane(panel);
frame.pack();
frame.setVisible(true);
JFrame#pack() triggers resize event and does the trick.

Categories