I have a header on a section of my swing layout, and I want to have text centered horizontally across the whole width of the section, but also have a button on only the right side. It should look like this:
/------Same width------\ /------Same width------\
[------------------------]Text here[----------------[Button]]
I am currently using a BorderLayout, with the text in the center and the button at the line end, but the text is centered not counting the button, as such:
/----Same width----\ /---Same width----\
[--------------------]Text here[-------------------][Button]]
I'm not sure if this is the answer you really want, but you could use a different layout manager, like GridBagLayout
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class JavaApplication295 {
public static void main(String[] args) {
new JavaApplication295();
}
public JavaApplication295() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
// gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
add(new JLabel("Look ma, no hands"), gbc);
gbc.anchor = GridBagConstraints.EAST;
add(new JButton("No Allowance"), gbc);
}
}
}
Now, the problem with this, is both components are actually positioned at the same location, the difference is, the button is anchored to the right position of the cell, this means that when the layout is been calculated, they will overlap....
Here is an approach using the OverlayLayout which was designed to have multiple components painted on the z axis:
import java.awt.*;
import javax.swing.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
JLabel label = new JLabel("I'm a Centered Label");
Box labelBox= Box.createHorizontalBox();
labelBox.add(Box.createHorizontalGlue());
labelBox.add(label);
labelBox.add(Box.createHorizontalGlue());
JButton button = new JButton("Button");
Box buttonBox= Box.createHorizontalBox();
buttonBox.add(Box.createHorizontalGlue());
buttonBox.add(button);
setLayout( new OverlayLayout(this) );
add(buttonBox);
add(labelBox);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE(), BorderLayout.NORTH);
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
As the width decreases the button will paint over the label.
Related
I need to create a JFrame which has three JPanels laid out as shown:
Could anybody please tell me how I can achieve this layout? I have already tried using BorderLayout, but in BorderLayout, if I add the topmost pane at BorderLayout.NORTH, the one in the center at BorderLayout.CENTER, and the one at the bottom to BorderLayout.SOUTH, the topmost pane becomes too small (in height) and the pane in the center becomes too big (in height).
P.S. I have already made the 3 panes and set their preferred sizes properly.
You could use all sorts of things, compound layouts (using two BorderLayouts for example) or other layouts, it will depend on what you ultimately want to achieve.
For simplicity, I'd use a GridBagLayout, for example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestLayout {
public static void main(String[] args) {
new TestLayout();
}
public TestLayout() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
add(new ABigPanel(), gbc);
gbc.weighty = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(new ASmallPanel(), gbc);
add(new ASmallerPanel(), gbc);
}
}
public class ABigPanel extends JPanel {
public ABigPanel() {
setBackground(Color.RED);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 200);
}
}
public class ASmallPanel extends JPanel {
public ASmallPanel() {
setBackground(Color.GREEN);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 180);
}
}
public class ASmallerPanel extends JPanel {
public ASmallerPanel() {
setBackground(Color.CYAN);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 40);
}
}
}
See How to Use GridBagLayout for more details
I tried a bunch of different layouts but none are giving me the desired effect.
I want something like this:
+-----------------------------+
Centered Text
+-------+
|Button |
+-------+
+-----------------------------+
In html it might look like this:
<p align="center">Some text</p>
<input type="button" value="Press"/>
The trouble I am having is with certain layouts (BorderLayout) it likes to resize the button to fit. Other layouts (Boxlayout and GroupLayout) will do something like this:
+-----------------------------+
Centered Text
+-------+
|Button |
+-------+
+-----------------------------+
Even when I have the JLabel aligned to CENTER and the Button aligned to LEFT.
Much appreciation to my helpers.
There are a number layouts that would be able to achieve this, in fact, you might even be able to use BorderLayout and FlowLayout together to do this, but this example simply uses GridBagLayout
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ExampleLayout {
public static void main(String[] args) {
new ExampleLayout();
}
public ExampleLayout() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
JLabel center = new JLabel("Centered Text");
center.setHorizontalAlignment(JLabel.CENTER);
add(center, gbc);
gbc.gridy++;
gbc.fill = GridBagConstraints.NONE;
gbc.gridwidth = 1;
gbc.weightx = 0;
gbc.anchor = GridBagConstraints.WEST;
JButton button = new JButton("Button");
add(button, gbc);
}
}
}
Take a look at Laying Out Components Within a Container for more examples and details
Although MadProgrammer and Costis Aivalis already answered your question, here is also an answer with MigLayout:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
public class MigLayoutDemo {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JLabel label = new JLabel("Centered text");
JButton button = new JButton("Button");
public MigLayoutDemo() {
panel.setLayout(new MigLayout());
label.setHorizontalAlignment(JLabel.CENTER);
panel.add(label, "wrap, pushx, growx");
panel.add(button);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(MigLayoutDemo::new);
}
}
Same effect, but this approach is less verbose unlike in case of GridBagLayout and I personally think that MigLayout is easier to use.
FlowLayout(int align) allows you to define justification. The default is CENTER. If you just left justify the FlowLayout of the panel that contains your button it works without having to use GridBagLayout manually. NetBeans provide an excellent GridBagLayout customizer, but you do not want to touch the code it generates automatically.
import javax.swing.*;
import java.awt.*;
public class MyLooks extends JFrame {
public MyLooks() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
p = new JPanel(new GridLayout(2, 1));
p1 = new JPanel();
p2 = new JPanel(new FlowLayout(FlowLayout.LEFT));
myLabel = new JLabel("this is a label");
myButton = new JButton("press");
p1.add(myLabel);
p2.add(myButton);
p.add(p1);
p.add(p2);
setContentPane(p);
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new MyLooks().setVisible(true);
}
});
}
private JLabel myLabel;
private JButton myButton;
private JPanel p, p1, p2;
}
I have a JScrollPane and a JTextArea (editable) with 10 rows. I want the first user input to appear at the bottom of the JTextArea and the most recent input should push the previous input upward. To achieve this I use textArea.setMargin(new Insets(x,0,0,0)); and everything works as it should - except that my second input will toggle the JScrollPane.
How can I start at the bottom of the JTextArea and only enable scrolling when the entire original viewport is filled?
Basically, you could add the JTextText onto a JPanel with another JPanel which acts a filler, causing the JTextArea to occupy the smallest space it actually needs.
I did this by using GridBagLayout to force the fill to occupy the most of space it could...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestTextArea {
public static void main(String[] args) {
new TestTextArea();
}
public TestTextArea() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(new TestPane()));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTextArea ta;
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
JPanel filler = new JPanel();
filler.setBackground(Color.WHITE);
add(filler, gbc);
gbc.gridy = 1;
gbc.weighty = 0;
ta = new JTextArea(1, 20);
add(ta, gbc);
}
}
}
To achieve this I use textArea.setMargin(new Insets(x,0,0,0)); and everything works as it should - except that my second input will toggle the JScrollPane.
Well I would guess that you would need to reset the margin every time you add text to the text area to take into account the new preferred size of the text area in relation to the size of the scroll pane.
You should be able to add a DocumentListener to the text area and make your adjustment whenever text is added to the Document.
I don't think that using margins and insets is the way to go because you are using layout adjustments to achieve text (content) functionality. This should be controlled by the Document object, which is what JTextArea makes its calls to regarding its content.
If you are calling append internally, then override it in a new class extending JTextArea:
public class Test {
static MyTextArea ta = new MyTextArea();
static int x = 0;
public static void main(String[] args) {
ta.setRows(10);
ta.setText("\n\n\n\n\n\n\n\n\n");
ta.setCaretPosition(ta.getDocument().getLength());
JButton append = new JButton("Append");
append.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
ta.append("\n" + x);
x++;
}
});
JFrame frame= new JFrame();
frame.setContentPane(new JPanel(new BorderLayout()));
frame.getContentPane().add(new JScrollPane(ta), BorderLayout.CENTER);
frame.getContentPane().add(append, BorderLayout.LINE_START);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
static class MyTextArea extends JTextArea {
#Override
public void append(String str) {
super.append(str);
try {
if (getDocument().getText(0, 1).equals("\n"))
getDocument().remove(0, 1);
} catch (BadLocationException e) {
e.printStackTrace();
}
}
}
}
If you are editing it manually, add a DocumentListener:
public class Test {
public static void main(String[] args) {
JTextArea ta = new JTextArea();
ta.setRows(10);
ta.setText("\n\n\n\n\n\n\n\n\n");
ta.setCaretPosition(ta.getDocument().getLength());
ta.getDocument().addDocumentListener(new MyDocListener());
JFrame frame= new JFrame();
frame.setContentPane(new JPanel(new BorderLayout()));
frame.getContentPane().add(new JScrollPane(ta), BorderLayout.CENTER);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
static class MyDocListener implements DocumentListener {
#Override
public void insertUpdate(DocumentEvent e) {
final DocumentEvent de = e;
Runnable pushUp = new Runnable() {
#Override
public void run() {
String t = null;
try {
t = de.getDocument().getText(de.getOffset(), de.getLength());
if (t.equals("\n") && de.getDocument().getText(0, 1).equals("\n"))
ta.getDocument().remove(0, 1);
} catch (BadLocationException e1) {
e1.printStackTrace();
}
}
};
SwingUtilities.invokeLater(pushUp);
}
#Override
public void removeUpdate(DocumentEvent e) {}
#Override
public void changedUpdate(DocumentEvent e) {}
}
}
Note that all you need from the code are the inner classes, the rest is just so you can see it working. I also don't have information regarding the initial state of the text area. Here I just set the number of rows to 10 and the text to 10 empty lines. I'm also not sure what you're allowed to do in the text area. This solution assumes that you can't jump lines and each time you insert a line it's not blank and it follows the previous line.
I have worked hard on writing my GUI in swing however I am trying to improve it further since I feel it still looks a little off.
I would ideally like:
the button to snap to the top right,
the textfield to be the same height as the button and stretch from the top left to the button edge
the scrollpane to stretch from the bottom of the textfield and the button to the edges of the window even when stretched.
I'm unsure how to "snap" the components to the top right, top left and rest of the area respectively.
#SuppressWarnings("serial")
class TFrame extends JFrame
{
TFrame()
{
super("Huffman Compression");//setTitle
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 300);
setResizable(true);
jPanel = new JPanel();
jTextField = new JTextField("Enter string to compress...");
jButton = new JButton("Compress");
jButton.setFocusable(false);
jTextArea = new JTextArea("LOG AREA", 30, 30);
jTextArea.setWrapStyleWord(true);
jTextArea.setLineWrap(true);
jTextArea.setEditable(false);
jTextArea.setFocusable(false);
jTextArea.setOpaque(false);
jScrollPane = new JScrollPane(jTextArea);
jScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
jScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
jPanel.add(jTextField, BorderLayout.WEST);
jPanel.add(jButton, BorderLayout.EAST);
jPanel.add(jScrollPane, BorderLayout.SOUTH);
add(jPanel);
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException
| InstantiationException
| IllegalAccessException
| UnsupportedLookAndFeelException e)
{
e.printStackTrace();
}
setVisible(true);
}
private JPanel jPanel;
private JTextField jTextField;
private JButton jButton;
private JTextArea jTextArea;
private JScrollPane jScrollPane;
}
public static void main(String[] args)
{
TFrame frame = new TFrame();
frame.pack();
...
This is what it currently looks like:
http://i.imgur.com/90cmDl1.png
Regards.
Basically, you need to take advantage of a series of layout managers (commonly known as "compound layouts").
For example, you can accomplish the requirements for the button and field using a GridBagLayout and the by using a BorderLayout, you can accomplish the rest, for example...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class BrowserWindow {
public static void main(String[] args) {
new BrowserWindow();
}
public BrowserWindow() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JPanel topPane = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.BOTH;
topPane.add(new JTextField(10), gbc);
gbc.weightx = 0;
gbc.fill = GridBagConstraints.NONE;
gbc.gridx++;
topPane.add(new JButton("Compress"), gbc);
JTextArea ta = new JTextArea("Log...", 30, 30);
JScrollPane sp = new JScrollPane(ta);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(topPane, BorderLayout.NORTH);
frame.add(sp);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Take a look at Laying Out Components Within a Container for more details
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);