Border Layout Spacing/Margins - java

for my beginner Java class we made an automated Tic-Tac-Toe game, and now we are creating a GUI to play it on. However, I'm having a lot of trouble getting the spacing/margins right. So far, I've just been trying to get the general framework for the GUI, and then I'm going to go back and actually implement the Tic-Tac-Toe game I have already made. So, far, I have this:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class ITTTGUI extends JFrame implements ActionListener{
//butimport javax.swing.border.*;tons
private JPanel sizePanel;
private JPanel buttonPanel;
private JPanel displayPanel;
private JPanel bottomPanel;
private JTextField size;
private JButton rebuildButton;
private JButton[] buttons;
private JLabel output;
//constructor
public NumberChooser(){
setTitle("BitchFace");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//content pane
Container cp = getContentPane();
//add a panel for the size
sizePanel = new JPanel();
sizePanel.setBorder(new EmptyBorder(5, 5, 5, 5) );//adds margin to panel
sizePanel.setLayout(new FlowLayout());
size = new JTextField("3",5);
sizePanel.add(new JLabel("N"));
sizePanel.add(size);
rebuildButton = new JButton("Rebuild");
rebuildButton.addActionListener(this);
sizePanel.add(rebuildButton);
//add bottom panel for output
sizePanel.add(new JButton("Player:"), BorderLayout.EAST);
sizePanel.add(new JButton("Move:"), BorderLayout.EAST);
sizePanel.add(new JButton("Winner:"), BorderLayout.EAST);
//add a panel for the numbers
buttonPanel = new JPanel();
buttonPanel.setBorder(new EmptyBorder(5, 5, 5, 5) );//adds margin to panel
buildButtonsPanel();
//add bottom panel for output
JPanel bottomPanel = new JPanel();
bottomPanel.setBorder(new EmptyBorder(5, 5, 5, 5) );//adds margin to panel
bottomPanel.add(new JButton("New Game"), BorderLayout.SOUTH);
bottomPanel.add(new JButton("Advise"), BorderLayout.SOUTH);
bottomPanel.add(new JButton("Quit"), BorderLayout.SOUTH);
//add panels to main pane
cp.setLayout(new BorderLayout());
cp.add(sizePanel, BorderLayout.EAST);
cp.add(buttonPanel, BorderLayout.CENTER);
cp.add(bottomPanel, BorderLayout.SOUTH);
pack();
}
//this is a helper method to rebuild the buttons panel
private void buildButtonsPanel(){
int n = 3;
try{
n = Integer.parseInt(size.getText());
}catch(Exception e){
e.printStackTrace();
}
buttonPanel.removeAll();
buttonPanel.setLayout(new GridLayout(n,n,4,4));
buttons = new JButton[n*n];
for(int i=0; i < buttons.length; i++){
buttons[i] = new JButton("*");
buttonPanel.add(buttons[i]);
buttons[i].addActionListener(this);
}
revalidate();
repaint();
pack();
}
public void actionPerformed(ActionEvent e){
Object s = e.getSource();
//check to see if the action came from the rebuild button
if(s == rebuildButton){
buildButtonsPanel();
}
//otherwise it came from the grid
}
//entry point
public static void main(String[] args){
//create the GUI
NumberChooser nc = new NumberChooser();
nc.setVisible(true);
}
}
It doesn't have to be exact, just generally the same.
And also there is no X or winner variable since I haven't implemented that. I also tried changing the margins from (5,5,5,5) to like (1,1,1,1), but that didn't change anything at all so that also confused me.
Any help with this, or how to generally go about this assignment would be appreciated.
(And it's not accepting my images. Sorry.)
Links are:
The problem is that is looks like this:
https://i1224.photobucket.com/albums/ee362/Devolutor/COPimage1_zps459f304b.png
And it is supposed to look like this:
http://i1224.photobucket.com/albums/ee362/Devolutor/COPimage2_zps8981c846.png

To have more space between the buttons, use a number of pixels beiiger than 4 for the grid layout:
buttonPanel.setLayout(new GridLayout(n,n,4,4));
To have a grid rather than a flow at the right side, use a GridLayout (just like you did for your buttons, but with 4 rows and 2 columns) rather than a FlowLayout.

Related

JButton array buttons not visible unless button not from array is added

I have a array of JButtons that do not want to be visible unless I add another JButton before the loop for the array of buttons.
Window class:
import javax.swing.*;
import java.awt.*;
public class Window extends JFrame {
private Container mContainer = new Container();
public Window()
{
super();
this.setTitle("Calculator");
this.setSize(200, 300);
this.setLocationRelativeTo(null);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mContainer.setBorder(null);
mContainer.setBackground(Color.GRAY);
mContainer.setOpaque(true);
this.setContentPane(mContainer);
//Panels
JPanel panel = new JPanel();
JPanel center = new JPanel();
center.setBackground(Color.GRAY);
center.setBorder(null);
JPanel displayOutput = new JPanel();
displayOutput.setBackground(Color.GRAY);
this.getContentPane().add(panel);
//TextArea
JTextArea textArea = new JTextArea(1, 20);
textArea.setForeground(Color.WHITE);
textArea.setBackground(Color.GRAY);
textArea.setPreferredSize(new Dimension(200, 60));
//Panel Layouts
panel.setLayout(new BorderLayout());
center.setLayout(new GridLayout(5, 4, 2, 2));
//Add other panel elements
displayOutput.add(textArea);
panel.add(displayOutput, BorderLayout.NORTH);
panel.add(center, BorderLayout.CENTER);
//For some reason adding this makes the array of buttons appear
JButton btnNewButton = new JButton("1");
center.add(btnNewButton);
//Create buttons
for(int i = 0; i < 20; i++){
CalcButtons cButtons[] = new CalcButtons[20];
cButtons[i] = new CalcButtons();
//Add buttons to center box below output
center.add(cButtons[i]);
//Sets fourth column of buttons in cyan.
if(((i + 1) % 4) == 0){
cButtons[i].setBackground(Color.CYAN);
}
}
//Add panel to window
getContentPane().add(panel);
this.setVisible(true);
}
}
Container Class:
import java.awt.Graphics;
import javax.swing.JPanel;
public class Container extends JPanel {
public Container() {
super();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
}
}
Button Class:
import javax.swing.*;
import java.awt.Color;
public class CalcButtons extends JButton
{
public CalcButtons()
{
this.setBackground(Color.WHITE);
this.setBorder(null);
}
}
This code then produced this:
However if I remove this:
//For some reason adding this makes the array of buttons appear
JButton btnNewButton = new JButton("1");
center.add(btnNewButton);
It produces this:
The problem is the size of your buttons are 0. You have set the border to null and there is no icon or text set. So when GridLayout calls getPreferredSize() on your buttons they return a size of 0,0 (width, height). When you add the JButton with a 1 in it then all of sudden one component has size. Since Gridlayout makes all components the same size you now can see your buttons. If you want your buttons to be blank but also be drawn set your border to an empty border with a size of 1 or greater on each edge.

How do I arrange JPanels from top to bottom?

I'm currently self-studying Java. I'm learning Graphical User Interface(GUI) programming.
I want JPanels to be arranged from top to bottom in a JFrame.First of all,I have a JLabel added to the first JPanel. The second JPanel has 5 JRadioButtions. The third JPanel has a JButton and a JLabel.
When the JButton is pressed,the JLabel in the 3rd JPanel shows some text.
I used BoxLayout(BoxLayout.X_AXIS) for all the JPanels and added all 3 of them into a JFrame which has FlowLayout(). Here is a small piece of code:
class GUI extends JFrame implements ActionListener {
JPanel pan1,pan2,pan3; //3 JPanels
JRadioButton rad1,rad2,rad3,rad4,rad5; //5 RadioButtons
JButton button; //A JButton
JLabel label; //A JLabel
public GUI(String header)
{
super(header);
setLayout(new FlowLayout()); //set FlowLayout to JFrame
setBounds(350,325,600,125);
setResizable(false);
creator();
adder();
commander();
add(pan1);
add(pan2);
add(pan3); //Add all 3 panels to JFrame
}
private void adder()
{
pan1.setLayout(new BoxLayout(pan1,BoxLayout.X_AXIS));
pan2.setLayout(new BoxLayout(pan2,BoxLayout.X_AXIS));
pan3.setLayout(new BoxLayout(pan3,BoxLayout.X_AXIS)); //Layout for all 3 JPanels
pan1.add(new JLabel("Choose a Security Level"));
ButtonGroup group=new ButtonGroup();
group.add(rad1);
group.add(rad2);
group.add(rad3);
group.add(rad4);
group.add(rad5);
pan2.add(rad1);
pan2.add(rad2);
pan2.add(rad3);
pan2.add(rad4);
pan2.add(rad5);
pan3.add(button);
pan3.add(label);
}
private void creator()
{
pan1=new JPanel();
pan2=new JPanel();
pan3=new JPanel();
rad1=new JRadioButton("Security Level 1");
rad2=new JRadioButton("Security Level 2");
rad3=new JRadioButton("Security Level 3");
rad4=new JRadioButton("Security Level 4");
rad5=new JRadioButton("Security Level 5");
button=new JButton("Move On");
label=new JLabel();
}
private void commander()
{
rad1.addActionListener(this);
rad2.addActionListener(this);
rad3.addActionListener(this);
rad4.addActionListener(this);
rad5.addActionListener(this);
rad1.setActionCommand("radio1");
rad2.setActionCommand("radio2");
rad3.setActionCommand("radio3");
rad4.setActionCommand("radio4");
rad5.setActionCommand("radio5");
button.addActionListener(this);
}
public void actionPerformed(ActionEvent evt)
{
//When button is pressed,the text in label changes
if(evt.getActionCommand().equals("radio1"))
label.setText("Very Easy to bypass");
else if(evt.getActionCommand().equals("radio2"))
label.setText("Easy to bypass");
else if(evt.getActionCommand().equals("radio3"))
label.setText("Can bypass Sometimes");
else if(evt.getActionCommand().equals("radio4"))
label.setText("Hard to bypass");
else if(evt.getActionCommand().equals("radio5"))
label.setText("Very Hard to bypass");
else
{ //Code here
}
repaint();
//More code here....
}
}
This is the output I'm getting when I select the first radiobutton(Forget the green colour):
I want the "Very easy to Bypass" text to be placed above the "Move on" button and below all the JRadioButtons. I can increase the size of the JFrame so that there will be enough space. My questions are:
Which Layout should I use to achieve this?
Should this layout be applied just for the JFrame or all 3 JPanels?
you must use GridLayout
Its very easy to use it, just add it like this. Take care of the import commands. :)
JFrame frame = new JFrame(new GridLayout(3,5));
Use GridLayout
GridLayout layout = new GridLayout(0, 1, 0, 5);
setLayout(layout);
What I would do to add 5 JPanels:
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class PanelAdd extends JFrame {
JPanel [] panels ;
public PanelAdd() {
GridLayout layout = new GridLayout(0, 1, 0, 5);
setLayout(layout);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setSize(400, 350);
}
public static void main(String [] args) {
PanelAdd add = new PanelAdd();
add.addPanels();
add.setVisible(true);
}
private void addPanels() {
panels = new JPanel[5];
for (int i = 0 ; i < panels.length ; i++) {
panels[i] = new JPanel();
panels[i].add(new JLabel("This Is Panel "+i));
add(panels[i]);
}
}
}
In this example, I made an array of 5 JPanels and add them through a loop.
I used GridLayout for the job.
This is just a hint for your answer
when you call add method from jframe,you can also give specified position to your panel in frame
like this:
JPanel pan1,pan2,pan3; //3 JPanels
JRadioButton rad1,rad2,rad3,rad4,rad5; //5 RadioButtons
JButton button; //A JButton
JLabel label; //A JLabel
public GUI(String header)
{
super(header);
setLayout(new FlowLayout()); //set FlowLayout to JFrame
setBounds(350,325,600,125);
setResizable(false);
creator();
adder();
commander();
add(pan1,BorderLayout.NORTH);
add(pan2,BorderLayout.CENTER);
add(pan3,,BorderLayout.SOUTH); //Add all panels to JFrame
}
good luck

Runtime error when implementing Java gui sliders

My first time posting a question here. Been coming here a while and enjoyed reading the threads. Was hoping someone on here could help me with a program I've been doing to learn Java. The program calls to implement sliders to change the background color in a gui background. It compiles fine, but when I run it, I get a few errors, which I commented in at the end of the code.
Code is as follows:
import java.awt.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.*;
public class sliderDemo extends JFrame
{
private JSlider redSlider, greenSlider, blueSlider;
private JPanel labels, sliders, colors;
private JLabel redlabel,greenlabel, bluelabel, colorlabel;
JTextArea colorPanel;
public sliderDemo()
{
setTitle("Slider Excercise");
setLayout(new BorderLayout(5, 5));
ChangeListener event = new eventListener();
colorlabel = new JLabel("Sliders to change colors:");
redlabel = new JLabel("Red slider");
greenlabel = new JLabel("Green slider");
bluelabel = new JLabel("Blue slider");
labels = new JPanel();
labels.setLayout(new GridLayout(3,1));
labels.add(redlabel);
labels.add(greenlabel);
labels.add(bluelabel);
redSlider = new JSlider(JSlider.HORIZONTAL, 0, 255, 0);
redSlider.addChangeListener(event);
redSlider.setMaximum(255);
redSlider.setPaintLabels(true);
redSlider.setPaintTicks(true);
redSlider.setMajorTickSpacing(25);
redSlider.setMinorTickSpacing(5);
redSlider.setPaintTrack(false);
greenSlider = new JSlider(JSlider.HORIZONTAL, 0, 255, 0);
greenSlider.addChangeListener(event);
greenSlider.setMaximum(255);
greenSlider.setPaintLabels(true);
greenSlider.setPaintTicks(true);
greenSlider.setMajorTickSpacing(25);
greenSlider.setMinorTickSpacing(5);
greenSlider.setPaintTrack(false);
blueSlider = new JSlider(JSlider.HORIZONTAL, 0, 255, 0);
blueSlider.addChangeListener(event);
blueSlider.setMaximum(255);
blueSlider.setPaintLabels(true);
blueSlider.setPaintTicks(true);
blueSlider.setMajorTickSpacing(25);
blueSlider.setMinorTickSpacing(5);
blueSlider.setPaintTrack(false);
sliders = new JPanel();
sliders.setLayout(new GridLayout(3,1));
sliders.add(colorlabel);
sliders.add(redSlider);
sliders.add(greenSlider);
sliders.add(blueSlider);
colorPanel = new JTextArea(10, 10);
colorPanel.setEditable(false);
colorPanel.setBackground(Color.WHITE);
colorPanel.add(sliders, BorderLayout.CENTER);
colorPanel.add(colors, BorderLayout.NORTH);
colorPanel.add(labels, BorderLayout.WEST);
colors = new JPanel(new BorderLayout(5, 5));
colors.add(colorlabel);
colors.add(colorPanel, BorderLayout.NORTH);
}
public static void main(String[] args)
{
JFrame myFrame = new sliderDemo();
myFrame.setSize(500, 500);
myFrame.setVisible(true);
myFrame.setLocationRelativeTo(null);
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public class eventListener implements ChangeListener
{
public void stateChanged(ChangeEvent e)
{
int r = redSlider.getValue();
int g = greenSlider.getValue();
int b = blueSlider.getValue();
colorPanel.setBackground(new Color(r, g, b));
}
}
}
/*
Exception in thread "main" java.lang.NullPointerException
at java.awt.Container.addImpl(Container.java:1090)
at java.awt.Container.add(Container.java:966)
at sliderDemo.<init>(sliderDemo.java:79)
at sliderDemo.main(sliderDemo.java:89)
Press any key to continue . . .
add JComponents that are initialized
you tried to add JPanel colors to JTextArea (quite nonsence) and its intialization colors = new JPanel(new BorderLayout(5, 5)); is in the next code lines
rename JTextArea colorPanel; to JTextArea textArea
then you miss 4th JPanel, because JTextArea colorPanel is called textArea and JTextArea isn't container for JPanels, is designated for user keys input
As mKorbel answer is not yet ticked as solution I will try to make it clearer (probably to late anyway):
In the lines
colorPanel.add(sliders, BorderLayout.CENTER);
colorPanel.add(colors, BorderLayout.NORTH);
colorPanel.add(labels, BorderLayout.WEST);
you add your JPanels to your text area that was meant for the color display (as mentioned by mKobel you should choose a better name). Remove the leading "colorPanel.". That will add the panels to the main panel instead (as was intended).
Also you have to move
colors = new JPanel(new BorderLayout(5, 5));
colors.add(colorlabel);
colors.add(colorPanel, BorderLayout.NORTH);
in front of the first code snippet as "colors" has to be instantiated first, before you add it to the layout.
After those changes the program is working (tested it myself). :)

GUI not showing as intended

I'm trying to draw a gui like shown in the figure, but somehow I'm not able to place the objects in right place (I guess that the problem is with the layout) the textArea is suppose to go in the middle... but is not showing at all
package Chapter22Collections;
import javax.swing.*;
import java.awt.*;
public class Exercise226 extends JFrame {
private JButton jbSort;
private JButton jbReverse;
private JButton jbAdd;
private JButton jbShuffle;
private JLabel jlAddnum;
private JTextArea jTextDisplay;
private JTextField jTextAdd;
public Exercise226() {
jbSort = new JButton("Sort");
jbReverse = new JButton("Reverse");
jbShuffle = new JButton("Shuffle");
jbAdd = new JButton("Add");
jlAddnum = new JLabel("Add number here: ");
jTextDisplay = new JTextArea();
jTextAdd = new JTextField(8);
setLayout(new BorderLayout());
JPanel p1 = new JPanel(new GridLayout(1,3));
p1.add(jlAddnum);
p1.add(jTextAdd);
p1.add(jbAdd);
JPanel p2 = new JPanel(new GridLayout(1,3));
p2.add(jbSort);
p2.add(jbReverse);
p2.add(jbShuffle);
add(p1, BorderLayout.NORTH);
add(jTextDisplay, BorderLayout.CENTER);
add(p2, BorderLayout.SOUTH);
}
public static void main(String... args) {
Exercise226 gui = new Exercise226();
gui.setTitle("Numbers");
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setSize(300, 200);
gui.setLocationRelativeTo(null);
gui.setVisible(true);
}
}
The JTextArea is actually where you expect it to be but has no outline border. It is usual to place the component in a JScrollPane which will give this effect:
add(new JScrollPane(jTextDisplay), BorderLayout.CENTER);
or simply
add(new JScrollPane(jTextDisplay));
To make the textArea re-size with the window, try BoxLayout. Box is "A lightweight container that uses a BoxLayout object as its layout manager."
Box p1 = new Box(BoxLayout.X_AXIS);
How could I add spacing/padding between the elements in the frame? So the text area is more visible and centered.
Borders and padding. E.G.
Compared with:
import javax.swing.*;
import java.awt.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
public class Exercise226 {
private JButton jbSort;
private JButton jbReverse;
private JButton jbAdd;
private JButton jbShuffle;
private JLabel jlAddnum;
private JTextArea jTextDisplay;
private JTextField jTextAdd;
private JPanel gui;
public Exercise226() {
gui = new JPanel(new BorderLayout(5,5));
jbSort = new JButton("Sort");
jbReverse = new JButton("Reverse");
jbShuffle = new JButton("Shuffle");
jbAdd = new JButton("Add");
jlAddnum = new JLabel("Add number here: ");
// set the size constraints using columns/rows
jTextDisplay = new JTextArea("Here I am!", 6,20);
jTextAdd = new JTextField(8);
JPanel p1 = new JPanel(new GridLayout(1,3,3,3));
p1.add(jlAddnum);
p1.add(jTextAdd);
p1.add(jbAdd);
JPanel p2 = new JPanel(new GridLayout(1,3,3,3));
p2.add(jbSort);
p2.add(jbReverse);
p2.add(jbShuffle);
JPanel textAreaContainer = new JPanel(new GridLayout());
textAreaContainer.add(new JScrollPane(jTextDisplay));
textAreaContainer.setBorder(new TitledBorder("Text Area Here"));
gui.add(p1, BorderLayout.PAGE_START);
gui.add(textAreaContainer, BorderLayout.CENTER);
gui.add(p2, BorderLayout.PAGE_END);
gui.setBorder(new EmptyBorder(4,4,4,4));
}
public Container getGui() {
return gui;
}
public static void main(String... args) {
JFrame f = new JFrame();
Exercise226 gui = new Exercise226();
f.setContentPane(gui.getGui());
f.setTitle("Numbers");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
}
This code:
Primarily provides 'white space' in the GUI using different constructors for the layouts that accept 2 int arguments for horizontal & vertical spacing.
Also adds 2 borders:
An empty border around the entire GUI to provide some spacing between it and the frame decorations.
A titled border around the text area, to make it very obvious.
Does implement a change for one unnecessary part of the original code. Instead of extending frame, it simply retains an instance of one.
Uses the JScrollPane container for the text area, as suggested by #Reimeus. It adds a nice beveled border of its own to an element that needs no scroll bars.
Creates a textAreaContainer specifically so that we can set a titled border to surround the scroll pane - without interfering with its existing border. It is possible to use a CompoundBorder for the scroll pane that consists of the existing border (scroll.getBorder()) & the titled border. However that gets complicated with buttons & other elements that might change borders on selection or action. So to set an 'outermost border' for a screen element (like the text area here) - I generally prefer to wrap the entire component in another container first.
Does not create and show the GUI on the EDT. Swing GUIs should be created and modified on the EDT. Left as an exercise for the user. See Concurrency in Swing for more details.
Old Code
The original code on this answer that provides the 'comparison GUI image' seen above. IT is closely based on the original code but with the text area wrapped in a scroll pane (and gaining a beveled border because of that) & given some text to display.
import javax.swing.*;
import java.awt.*;
public class Exercise226 extends JFrame {
private JButton jbSort;
private JButton jbReverse;
private JButton jbAdd;
private JButton jbShuffle;
private JLabel jlAddnum;
private JTextArea jTextDisplay;
private JTextField jTextAdd;
public Exercise226() {
jbSort = new JButton("Sort");
jbReverse = new JButton("Reverse");
jbShuffle = new JButton("Shuffle");
jbAdd = new JButton("Add");
jlAddnum = new JLabel("Add number here: ");
// set the size constraints using columns/rows
jTextDisplay = new JTextArea("Here I am!", 6,20);
jTextAdd = new JTextField(8);
setLayout(new BorderLayout());
JPanel p1 = new JPanel(new GridLayout(1,3));
p1.add(jlAddnum);
p1.add(jTextAdd);
p1.add(jbAdd);
JPanel p2 = new JPanel(new GridLayout(1,3));
p2.add(jbSort);
p2.add(jbReverse);
p2.add(jbShuffle);
add(p1, BorderLayout.NORTH);
add(new JScrollPane(jTextDisplay), BorderLayout.CENTER);
add(p2, BorderLayout.SOUTH);
}
public static void main(String... args) {
Exercise226 gui = new Exercise226();
gui.setTitle("Numbers");
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//gui.setSize(300, 200);
gui.pack();
//gui.setLocationRelativeTo(null);
gui.setLocationByPlatform(true);
gui.setVisible(true);
}
}

Resize makes things wrong

I want to create a JInternalFrame with some components in it.
My aim is to design a bash console in Java.
My frame is made of 4 components:
JTextArea included into a JScrollPane
JLabel with the text "Cmd:"
JTextField
JButton with the text "Send"
And I have the following code:
Box box = Box.createHorizontalBox();
box.add(Box.createVerticalStrut(5));
box.add(this.cmd_label);
box.add(Box.createVerticalStrut(5));
box.add(this.cmd_input);
box.add(Box.createVerticalStrut(5));
box.add(this.submit);
box.add(Box.createVerticalStrut(5));
Box mainBox = Box.createVerticalBox();
mainBox.add(Box.createHorizontalStrut(5));
mainBox.add(this.result_scroll);
mainBox.add(Box.createHorizontalStrut(5));
mainBox.add(box);
mainBox.add(Box.createHorizontalStrut(5));
add(mainBox);
So when the frame has not been maximized, I have a correct look:
But when I maximize it, all components are incorrectly located:
So, here is my question: How can I set a weight to the components to fix their location every time, or, how can I fix it?
Thanks.
I think this would be better done with a BorderLayout. In a BorderLayout, the component specified as the center component will expand to fill as much space as possible, and the other components will remain at their preferred sizes.
int hgap = 5;
int vgap = 5;
internalFrame.getContentPane().setLayout(new BorderLayout(hgap, vgap));
internalFrame.getContentPane().add(this.result_scroll, BorderLayout.CENTER);
JPanel bottomPanel = new JPanel();
bottomPanel.add(this.cmd_label);
bottomPanel.add(this.cmd_input);
bottomPanel.add(this.submit);
internalFrame.getContentPane().add(bottomPanel, BorderLayout.SOUTH);
Here try this code, is this behaviour exceptable :
import java.awt.*;
import javax.swing.*;
public class LayoutExample
{
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("LAYOUT EXAMPLE");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel centerPanel = new JPanel();
centerPanel.setLayout(new BorderLayout(5, 5));
centerPanel.setBorder(
BorderFactory.createEmptyBorder(2, 2, 2, 2));
JTextArea tarea = new JTextArea(10, 10);
tarea.setBackground(Color.DARK_GRAY.darker());
tarea.setForeground(Color.WHITE);
tarea.setCaretColor(Color.WHITE);
tarea.setLineWrap(true);
JScrollPane scrollPane = new JScrollPane(tarea);
centerPanel.add(scrollPane, BorderLayout.CENTER);
JPanel footerPanel = new JPanel();
footerPanel.setLayout(new BorderLayout(5, 5));
footerPanel.setBorder(
BorderFactory.createEmptyBorder(2, 2, 2, 2));
JLabel cmdLabel = new JLabel("Cmd : ");
JTextField tfield = new JTextField(10);
JPanel buttonPanel = new JPanel();
buttonPanel.setBorder(
BorderFactory.createEmptyBorder(2, 2, 2, 2));
JButton sendButton = new JButton("SEND");
footerPanel.add(cmdLabel, BorderLayout.LINE_START);
footerPanel.add(tfield, BorderLayout.CENTER);
buttonPanel.add(sendButton);
footerPanel.add(buttonPanel, BorderLayout.LINE_END);
frame.getContentPane().add(centerPanel, BorderLayout.CENTER);
frame.getContentPane().add(footerPanel, BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new LayoutExample().createAndDisplayGUI();
}
});
}
}
OUTPUT :
Base problem here is what I consider a bug in JTextField's max layout hint: it's unbounded in both horizontal and vertical dimension. The latter is pure nonsense for a component designed for showing a single line of text. To fix, subclass and let it return its pref for the height, like:
JTextField cmdInput = new JTextField() {
#Override
public Dimension getMaximumSize() {
Dimension max = super.getMaximumSize();
max.height = getPreferredSize().height;
return max;
}
};
As BoxLayout respects maxSize, the excess height now will be given to the top box only.
On the long run, consider switching to a third party manager which allows fine-tuning in a all-in-one-panel approach. Yeah, here comes my current favourite: MigLayout. Compare the following lines to all the nesting and border tricks above and have fun :-)
MigLayout layout = new MigLayout("wrap 3, debug",
"[][grow, fill][]", // 3 columns, middle column filled and allows growing
"[grow, fill][]"); // two rows, first filled and allows growing
JComponent content = new JPanel(layout);
// the scrollPane in the first row spanning all columns
// and growing in both directions
content.add(new JScrollPane(new JTextArea(20, 20)), "span, grow");
// auto-wrapped to first column in second row
content.add(new JLabel("Cmd:"));
content.add(new JTextField());
content.add(new JButton("Submit"));

Categories