How to add add multiple extended JPanels into one JFrame in Java? - java

I want two images from two different classes that extend JPanel to be side by side.
The problem that I'm having is that the two JPanels should be inside the JFrame but when I do framename.add(panel) it replaces the other one instead of adding two of them side by side.
I have tried adding flowlayout and other layouts inside the main class, but none of the images showed up.
So my question is, if I have two classes that extend Jpanel, how do i add those two panels inside a Jframe so that they'll be side by side (next to each other) without replacing the other panel?
Any suggestions would be greatly appreciated.
Edit: If I extend JFrame to a class, does that class automatically become a JPanel itself? I know what extends means, but I'm not sure how it works in regards to a Jframe.
Main.java
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class Main
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
Panel1 s = new Panel1(); //picture 1
Panel2 n = new Panel2(); //picture 2
frame.add(n);
frame.add(s); //here is the problem, it replaces the previous panel
f.setSize(200,100);
f.setLocation(0,400);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Panel1.java
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class image2 extends JPanel
{
ImageIcon anotherIcon;
public image2() //constructor
{
URL imageURL = Panel1.class.getResource("images/puppy.png");
anotherIcon = new ImageIcon(imageURL);
}
public void paint(Graphics g)
{
super.paintComponent(g);
anotherIcon.paintIcon(this, g, 0, 0);
}
}
Panel2.java
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class Panel2 extends JPanel
{
ImageIcon anotherIcon2;
public Panel2() //constructor
{
URL imageURL = Panel2.class.getResource("images/puppy2.png");
anotherIcon = new ImageIcon(imageURL);
}
public void paint(Graphics g)
{
super.paintComponent(g);
anotherIcon2.paintIcon(this, g, 0, 0);
}
}

JFrame has implemented BorderLayout in the API
only one JComponent can be placed to the one of 5th. areas in BorderLayout
I want two images from two different classes that extend JPanel to be
side by side.
change built_in LayoutManager to the GridLayout
or
use JLabel with Icon in the case that there aren't any JComponent added to JPanels

The JFrame's default layout manager is BorderLayout. Try changing it to use something like GridLayout instead
Take a look at A visual guide to layout managers for more ideas

Try frame.getContentPane().add(...)?
And set the layout of the contentpane to FlowLayout (or other)
JFrame f = new JFrame("This is a test");
f.setSize(400, 150);
Container content = f.getContentPane();
content.setLayout(new FlowLayout());
content.add(new JButton("Button 1"));
content.add(new JButton("Button 2"));
f.setVisible(true);

You are adding the panels directly to the JFrame, you have to adds the panels in the contentPane.
It's also recomended create a panel to be the contentPane frame.setContentPane(myPanel);
and configure it with some layout (BorderLayout, GridBagLayout, whatever...)

In frame set FlowLayout()
frame.setLayout(new FlowLayout());

I corrected both Panel1.java and Panel2.java of minor mistakes and added an example of how you'd place them side by side using GridBagLayout/GridBagConstraints combo:
Main.java
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class Main {
public static void main(String[] args) {
GridBagConstraints gbc = new GridBagConstraints();
JFrame frame = new JFrame();
frame.setLayout(new GridBagLayout());
Panel1 s = new Panel1(); //picture 1
Panel2 n = new Panel2(); //picture 2
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
frame.add(n, gbc);
gbc.gridx = 1;
gbc.gridy = 0;
gbc.gridwidth = GridBagConstraints.REMAINDER;
frame.add(s, gbc); //here is the problem, it replaces the previous panel
frame.setSize(200,100);
frame.setLocation(0,400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Panel1.java
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class Panel1 extends JPanel {
ImageIcon anotherIcon;
public Panel1 ( ) {
URL imageURL = Panel1.class.getResource("images/puppy.png");
anotherIcon = new ImageIcon(imageURL);
}
public void paint(Graphics g) {
super.paintComponent(g);
anotherIcon.paintIcon(this, g, 0, 0);
}
}
Panel2.java
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class Panel2 extends JPanel {
ImageIcon anotherIcon;
public Panel2 ( ) {
URL imageURL = Panel2.class.getResource("images/puppy2.png");
anotherIcon = new ImageIcon(imageURL);
}
public void paint(Graphics g) {
super.paintComponent(g);
anotherIcon.paintIcon(this, g, 0, 0);
}
}
The general idea for your code was not wrong, just that the panels were placed one on top of the other, causing one to hide the other....

You can try this. Set Layout of your Frame as:
setLayout(null)
and then can add Bounds to your panel
ie. setBounds()
and then add these panels to frame

Related

Positioning JButton on JFrame won't show up [duplicate]

This question already has answers here:
How to add JTable in JPanel with null layout?
(11 answers)
Closed 8 years ago.
I know this is horrible coding but I desperately need to fix this problem. I've tried multiple ways of trying to position the button but the button still stays in the top center with all the other buttons lined up after it.
import javax.imageio.ImageIO;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.io.IOException;
import java.net.URL;
public class Template extends JFrame {
/**
* #param args
*/
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
JFrame frame = new JFrame("The Impossible Quiz");//Construct JFrame
frame.setLayout(null);//manual setting for button placement
frame.setContentPane(new JPanel() {//sets panel as background
BufferedImage image = ImageIO.read(new URL("https://pbs.twimg.com/media/BoyFVfXIUAA0Tik.png"));//uses url image
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, 1360, 690, this);//sets image as jframe background
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//closes jframe when press exit
frame.setSize(1365, 730);//sets size of jframe
JPanel buttonpanel = new JPanel();//sets panel for all buttons
buttonpanel.setBounds(0, 0, 1460, 690);//sets placing and sizing of panel
buttonpanel.setOpaque(false);//makes panel transparent
JButton next = new JButton ("Start");//contructs correct start button
next.setBounds(10, 5, 40, 50);
buttonpanel.add(next);//adds button to panel
next.addActionListener(new ActionListener()//adds actionlistener to button
{
public void actionPerformed(ActionEvent e)
{
new Introduction();//continues to next question
}
});
JButton wrongstart = new JButton("Start!!");//constructs wrong start button
wrongstart.setSize(100, 400);//setes size of button
buttonpanel.add(wrongstart);//adds button to panel
wrongstart.addActionListener(new ActionListener()//adds actionlistener to button
{
public void actionPerformed(ActionEvent e)
{
new Wrong();//direct user to wrong panel
}
});
frame.add(buttonpanel);//adds panel to jframe
frame.setVisible(true);//sets jframe as visible
}
}
Your problem is that you're trying to use absolute positioning to position a component (your JButton) in a container (the containing JPanel) that uses FlowLayout as default, and FlowLayout completely ignores the components bounds. A quick solution is to set the JPanel's layout to null allowing for absolute positioning. A correct solution is to always avoid null layouts and absolute positioning and instead to nest JPanels, each using its own layouts, in order to create complex yet flexible and pleasing GUI's.
You're setting the JFrame contentPane's layout to null as well -- don't do that either.
And then adding a JPanel as the contentPane which uses a default FlowLayout -- don't do that. Let the contentPane's layout be BorderLayout.
Edit
For example, if we leave the contentPane alone with its BorderLayout, and add another image panel on top of it, one that uses GridBagLayout, we can easily position our JButton to the top left corner of the GUI if desired. ....
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import javax.swing.*;
#SuppressWarnings("serial")
public class Template2 extends JPanel {
private static final int PREF_W = 1460;
private static final int PREF_H = 690;
private BufferedImage img;
private JButton startButton = new JButton("Start");
public Template2() {
setLayout(new GridBagLayout());
// TODO: .... read in your image here
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.insets = new Insets(5, 10, 0, 0);
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
add(startButton, gbc);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
#Override
public void paintComponents(Graphics g) {
super.paintComponents(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
}
private static void createAndShowGui() {
Template2 mainPanel = new Template2();
JFrame frame = new JFrame("Some Horrendous Program");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

JavaGUI: Box layout with width fit to container?

I'm making a GUI for a a custom source server browser with improved filtering.
This is what I have so far.
However, when I resize...
When I resize the window I want the L4D2 'filter panel' to resize to the current maximum width of the container. I also want to be able to add more of these panels in a column (such as box layout provides).
Boxlayout get's the panels to appear in a column, but it doesn't do anything for their widths.
I'm thinking I may need to override the filter panels preferred size methods so that they can retrieve the size of the parent container, but I'm not sure how to do this.
How should I approach this problem?
EDIT: Here's an example program depicting the problem.
import javax.swing.*;
import java.awt.*;
public class guiExampleProblem {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
final MyWindows wnd = new MyWindows("guiExampleProblem");
wnd.setVisible(true);
}
});
}
}
class MyWindows extends JFrame {
public MyWindows(String text) {
super(text);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
JPanel containerPanel1 = new JPanel();
JPanel containerPanel2 = new JPanel();
JPanel containerPanel3 = new JPanel();
containerPanel1.setBackground(Color.BLACK);
containerPanel2.setBackground(Color.RED);
containerPanel3.setBackground(Color.GREEN);
mainPanel.add(containerPanel1);
mainPanel.add(containerPanel2);
mainPanel.add(containerPanel3);
this.add(mainPanel);
pack();
}
}
When the window is resized, I want the panels to expand only along the x-axis, and remain at a constant height on the y-axis, however in the example the panels expand on both the x y axis.
I managed to get the desired functionality by overriding the 'filter panels' getPrefferedSize methods so that they retrieve the parent containers width and use that. Here is the code in the form of an example:
import javax.swing.*;
import java.awt.*;
public class guiExampleProblem {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
final MyWindows wnd = new MyWindows("guiExampleProblem");
wnd.setVisible(true);
}
});
}
}
class MyWindows extends JFrame {
public MyWindows(String text) {
super(text);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new FlowLayout());
JPanel containerPanel1 = new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(this.getParent().getWidth(),60);
}
};
JPanel containerPanel2 = new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(this.getParent().getWidth(),60);
}
};
JPanel containerPanel3 = new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(this.getParent().getWidth(),60);
}
};
containerPanel1.setBackground(Color.BLACK);
containerPanel2.setBackground(Color.RED);
containerPanel3.setBackground(Color.GREEN);
mainPanel.add(containerPanel1);
mainPanel.add(containerPanel2);
mainPanel.add(containerPanel3);
this.add(mainPanel);
pack();
}
}
Put the panel (with BoxLayout) that is to stretch in the CENTER of a BorderLayout -- put the panel to the right in the EAST of that BorderLayout. You have given no detail of what else you want this to do, nor any code, but this might be what you want.
--
After your solution: it seems to me that using FlowLayout here is confusing -- it lays out its components one after the other horizontally, and your trick of getting preferred size from the width of the container makes it behave differently. I also avoid getting into layout logic in my application when I can, so I looked for another way to do this and came up with:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class guiExampleProblem2
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
final MyWindows2 wnd = new MyWindows2("guiExampleProblem2");
wnd.setVisible(true);
}
});
}
}
class MyWindows2 extends JFrame
{
public MyWindows2(String text)
{
super(text);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
JPanel containerPanel1 = addContainedPanel(Color.BLACK, 60, 60, mainPanel);
JPanel containerPanel2 = addContainedPanel(Color.RED, 60, 60, mainPanel);
JPanel containerPanel3 = addContainedPanel(Color.GREEN, 60, 60, mainPanel);
this.add(mainPanel, BorderLayout.NORTH);
pack();
}
JPanel addContainedPanel(Color color, int width, int height, JPanel container)
{
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(width, height));
panel.setBackground(color);
container.add(panel);
return panel;
}
}
This uses the NORTH portion of a BorderLayout (which is the default layout for a JFrame, by the way) to do the main thing you wanted -- stretch things horizontally. The BoxLayout with a page axis is intended to lay things out top-to-bottom, so I think that's less confusing for the reader. Anyway, it's another way to do it that I think uses the components - including the layout managers - more like they were intended and documented.

How to add a JPanel to a JFrame?

I am creating a minefield game. I need to add two buttons, Clear and Done in their own separate JPanel below the grid and cannot figure out how. Below is the code for the game grid. Thanks!
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MineField extends JPanel implements ActionListener{
public static void main(String[] args) {
MineField g = new MineField();
JFrame frame = new JFrame("Mine Field");
frame.add(g);
frame.setSize(400,400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private JButton squares[][];
public MineField(){
this.setSize(400,400);
this.setLayout(new GridLayout(5,5));
squares = new JButton[5][5];
buildButtons();
}
int [][] num = new int [5][5];
private void buildButtons(){
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
squares[i][j] = new JButton();
squares[i][j].setSize(400,400);
this.add(squares[i][j]);
}
}
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
By default a JFrame uses a BorderLayout.
So currently your MineField class is added to the CENTER of the border layout.
If you want another panel on the frame you can use:
JPanel south = new JPanel();
south.add(clearButton);
south.add(doneButton);
frame.add(south, BorderLayout.SOUTH);
Read the section from the Swing tutorial on How to Use BorderLayout for more information and examples to better understand how layout managers work.
We can add components to each other by using the .add() method.
Two practical usages of this would be:
mainPanel.add(topPanel); //panel to panel
or as Quincunx said
JFrame.add(Component c); //component to jframe
You should modify your code a litte bit, well you can add those few lines :
JPanel thePanel = (JPanel)frame.getContentPane(); // this variable will manage the JFrame content
thePanel.setLayout(new BorderLayout()); // BorderLayout to seperat the Frame on 5 section Center, North, South, Est, West
JPanel btnPanel = new JPanel(new FlowLayout(FlowLayout.Right)); // this JPanel made to contain the buttons
btnPanel.add(clearBtn);
btnPanel.add(doneBtn);
thePanel.add(g, BorderLayout.CENTER);
thePanel.add(btnPanel, BorderLayout.SOUTH);
hope that helps, Salam

Java Swing setting JPanel Size

Could anyone point out where I am going wrong with this java swing gui code. I am trying to add two buttons to a JPanel and then add it into a frame after setting the size but it seems to not be responding to the setSize values passed to it
public Test() {
GridLayout layout = new GridLayout(1, 2);
//this.setLayout(layout);
this.setSize(700, 700);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buttonPanel = new JPanel();
buttonPanel.setSize(new Dimension(30, 100));
JButton rectButton = new JButton("Rectangle");
JButton ovalButton = new JButton("Oval");
buttonPanel.add(rectButton);
buttonPanel.add(ovalButton);
this.add(buttonPanel);
this.add(new PaintSurface());
this.setVisible(true);
}
This may not answer your immediate question...but...
GridLayout layout = new GridLayout(1, 2);
this.setLayout(layout);
// You're original code...
// Why are you using `BorderLayout.CENTER` on a `GridLayout`
this.add(new PaintSurface(), BorderLayout.CENTER);
You set the layout as a GridLayout, but you are using BorderLayout constraints to apply one of the components??
Also, make sure that there are not calls to Test#pack else where in your code, as this will override the values of setSize
UPDATED (from changes to question)
Remember, the default layout manager for JFrame is BorderLayout, so even though you're calling buttonPanel.setSize, it's likely that it's begin overridden by the layout manager anyway.
I would take a read through A Visual Guide to Layout Managers and Using Layout Managers to find a layout manager that best meets your requirements.
If you can't find a single one, consider using compound components with different layout managers to bring the layout closer to what you want to achieve.
Ok, I'll just give you a solution:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Cobie extends JFrame{
JButton rectButton = new JButton("Rectangle");
JButton ovalButton = new JButton("Oval");
JPanel buttonPanel = new JPanel();
JPanel paintSurface = new JPanel();
public Cobie(){
setLayout(new GridLayout(2,1));
buttonPanel.setBackground(Color.RED);
paintSurface.setBackground(Color.BLUE);
buttonPanel.add(rectButton);
buttonPanel.add(ovalButton);
add(buttonPanel);
add(paintSurface);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable(){
public void run(){
Cobie c = new Cobie();
c.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
c.setSize(600,400); //Avoid using this method
c.setVisible(true);
}
});
}
}
According to your updated answer, you are not setting your layout on anything.
Anyway, if you use LayoutManager's (which you should), it is pointless to call setSize()/setBounds()/setLocation() since it will be overriden by the LayoutManager (that is actually its job).
And guessing that your Test class extends JFrame, by calling this.add(buttonPanel); this.add(new PaintSurface()); you are adding two components with the same constraint (BorderLayout.CENTER, since BorderLayout is the default LayoutManager of the content pane of the JFrame) to the content pane.
Consider reading the LayoutManager tutorial.
Just for information, although far from perfect, this shows something "working":
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test extends JFrame {
private JPanel buttonPanel;
public class PaintSurface extends JButton {
public PaintSurface() {
super("Paint surface dummy");
}
}
public Test() {
GridLayout layout = new GridLayout(1, 2);
this.setLayout(layout);
this.setSize(700, 700);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buttonPanel = new JPanel();
buttonPanel.setSize(new Dimension(30, 100));
JButton rectButton = new JButton("Rectangle");
JButton ovalButton = new JButton("Oval");
buttonPanel.add(rectButton);
buttonPanel.add(ovalButton);
this.add(buttonPanel);
this.add(new PaintSurface());
this.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test();
}
});
}
}

Java Swing BorderLayout resize difficulties

I want to have my screen split in two so I used a BorderLayout with East and West sections. I had problems resizing and here I eventually found out that width is not changed in the East and West panels and height is not changed in the North and South panels and both are changed in the Center panel.
However, I want both width and height to be changed upon resize, and have two panels side by side. I have tried various levels of nesting to try getting it to work but I do not think it will work with BorderLayout.
It seems like this should be easy for the default layout manager but maybe I should try a different layout (e.g. BoxLayout) to achieve what I want.
Also here is some code which replicates the problem I am talking about (try resizing the window):
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main extends JFrame {
public static void main(String[] args) {
JFrame window = new Main();
window.setVisible(true);
}
public Main() {
JButton east = new JButton("East");
JButton west = new JButton("West");
JPanel content = new JPanel();
content.setLayout(new BorderLayout());
content.add(east, BorderLayout.EAST);
content.add(west, BorderLayout.WEST);
setContentPane(content);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
}
}
Edit: I do not want the two sides to be equal, roughly 2:1 is the ratio which I want.
What you can use in your case is GridLayout, here two JButtons will resize themselves as the JFrame resizes.
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Main extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
JFrame window = new Main();
window.setVisible(true);
}
});
}
public Main() {
JButton east = new JButton("East");
JButton west = new JButton("West");
JPanel content = new JPanel();
content.setLayout(new GridLayout(1, 2));
content.add(east);
content.add(west);
setContentPane(content);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
}
}
Moreover, it's always best to run your GUI related code from the EDT - Event Dispatch Thread, and not from the Main Thread. Do read Concurrency in Swing, for more info on the topic.
LATEST EDIT : As per requested comment
Use GridBagLayout to specify the size that you want to give
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Main extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
JFrame window = new Main();
window.setVisible(true);
}
});
}
public Main() {
JPanel east = new JPanel();
east.setOpaque(true);
east.setBackground(Color.WHITE);
JPanel west = new JPanel();
west.setOpaque(true);
west.setBackground(Color.BLUE);
JPanel content = new JPanel();
content.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 0.3;
gbc.weighty = 1.0;
gbc.gridx = 0;
gbc.gridy = 0;
content.add(east, gbc);
gbc.weightx = 0.7;
gbc.gridx = 1;
content.add(west, gbc);
setContentPane(content);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
}
}
Why don't you try with JSplitPane:
import javax.swing.*;
import java.awt.*;
public class AppDemo {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame();
JButton eastButton = new JButton("East");
JButton westButton = new JButton("West");
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, eastButton, westButton);
JPanel content = new JPanel();
content.setLayout(new BorderLayout());
content.add(splitPane, BorderLayout.CENTER);
frame.setContentPane(content);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setPreferredSize(new Dimension(500, 400));
frame.pack();
frame.setVisible(true);
});
}
}
You will get this:
If you want to keep your BorderLayout you can use something like the following object:
public class ResizablePanel extends JPanel {
public ResizablePanel(JComponent body) {
setLayout(new BorderLayout());
JButton resize = new JButton();
resize.setPreferredSize(new Dimension(Integer.MAX_VALUE, 4));
resize.addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
Dimension preferredSize = ResizablePanel.this.getPreferredSize();
ResizablePanel.this.setPreferredSize(new Dimension(preferredSize.width, preferredSize.height-e.getY()));
ResizablePanel.this.revalidate();
}
});
add(resize, BorderLayout.PAGE_START);
add(body, BorderLayout.CENTER);
}
}
Now wrap the part you want to resize with an instance of ResizablePanel and you'll be able to resize it by dragging the thin button.
Note that this is code is for resizing the height of a panel that you put at the bottom (PAGE_END) part of a border layout, but it should be fairly straightforward to change it for resizing the width.
Sorry about replying to an old post.
My fix is to still use BorderLayout but to throw in the following line after the Component is resized
getLayout().layoutContainer(this);

Categories