JLabel automatically centers it self inside GridBagLayout - java

I'm trying to make a custom JTextField that hosts a JLabel, So I have wrapped the JTextField and the JLabel in a custom Class that extends JPanel
The JPanel layout is set to GridBagLayout since I only need place 2 components vertically. Here is how it looks like
This is the code, I can't spot where I have instructed the GridBagLayout to center the JLabel.
setLayout(new GridBagLayout());
jLabel = new JLabel();
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.VERTICAL;
gbc.gridy = 1;
add(jLabel, gbc);
I want to have the JLabel the same position at shown in the GIF. How can I achieve this? Would also be nice if anyone can point what the exact text size would look good on the JLabel.

the JLabel does not start from line start, nor is it center. It's kinda in between
I'm not sure what your exact code is and how you nest the custom panel in another panel.
But as I mentioned above when you have weird alignment you need to make sure each component has the same x alignment so they can be aligned the same way.
I can't reproduce your problem using the simple example below:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class SSCCE extends JPanel
{
SSCCE()
{
JPanel box = new JPanel();
box.setLayout( new BoxLayout(box, BoxLayout.Y_AXIS) );
box.setBorder( new LineBorder(Color.RED) );
JTextField textField = new JTextField(10);
//textField.setAlignmentX(JComponent.LEFT_ALIGNMENT);
System.out.println( textField.getAlignmentX() );
box.add( textField );
JLabel label = new JLabel("Some text");
System.out.println( label.getAlignmentX() );
box.add( label );
add( box );
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args) throws Exception
{
java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
}
But as you can see from the output by default a text field has center alignment and the label left alignment. Try making them both left aligned.

Thanks to VGR in the comments, I have solved this issue by setting the anchor to LINE_STARTS
gbc.anchor = GridBagConstraints.LINE_STARTS;
Edit: Ended up using BoxLayout thanks to camickr for answering with an example.

Related

Contents of JScrollPane are not visible

I have a main class:
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame("Hex");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent inputs = new InputPanel();
JComponent hexGrid = new HexGridPanel(10,10,30);
JComponent outputs = new OutputPanel();
JComponent toolbar = new ToolbarPanel(); // This one is having problems
Container pane = frame.getContentPane();
pane.add(inputs, BorderLayout.LINE_START);
pane.add(hexGrid, BorderLayout.CENTER);
pane.add(outputs, BorderLayout.LINE_END);
pane.add(toolbar, BorderLayout.PAGE_END); // This one is having problems
frame.pack();
frame.setVisible(true);
}
}
And all of my other panels work except for ToolbarPanel that for some reason does not show its content:
public ToolbarPanel(){
JPanel content = new JPanel();
content.setLayout(new BoxLayout(content, BoxLayout.X_AXIS));
ButtonGroup buttonGroup = new ButtonGroup();
JRadioButton button = new JRadioButton("Test");
buttonGroup.add(button );
content.add(button );
JScrollPane scroll = new JScrollPane(content);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
content.setBorder(new LineBorder(Color.RED));
scroll.setBorder(new LineBorder(Color.GREEN));
this.add(scroll);
this.setPreferredSize(new Dimension(900, 200));
this.setBorder(new LineBorder(Color.BLACK)); // Only this is showing up in the UI
}
The ToolbarPanel itself shows up, but not the scroll pane or the radio buttons. It should show up inside of the black rectangle at the bottom of this image:
Well, you didn't include a MRE and I don't see the declaration of your class but I'm guessing you are using:
public class ToolbarPanel extends JComponent
The problem is that by default a JComponent doesn't have a layout manager so you won't see your components.
If you use:
public class ToolbarPanel extends JPanel
It will be a little better, but all the components will be displayed in a small square.
So you will also want to add
setLayout( new BorderLayout() );
to your constructor.
Note:
This is why a minimal reproducible example should be included with every question. We should not have to spend time guessing what you may or may not be doing.

Java vertical layout hugging left edge

I am having some issues with layout in Java, the below image represents what I am trying to accomplish. Currently I am using;
Box vBox = Box.createVerticalBox();
to vertically separate the items but they tend to group in the centre rather than
hug the left edge. What is the best way of accomplishing this?
EDIT: Setting the alignment as such;
JComboBox combo = new JComboBox<Integer>(numPlayers);
combo.setMaximumSize(new Dimension(100, 30));
combo.setAlignmentX(JComponent.RIGHT_ALIGNMENT );
vBox.add(combo);
Does not seem to align the component correctly, instead it aligns the components left edge to the centre line of the panel.
You can use a vertical box. Now you need to set the alignment of the components that you add to the box:
component.setAlignmentX( JComponent.LEFT_ALIGNMENT );
box.add( component );
...
Edit:
You can use a GridBagLayout. The components will remain at there preferred size when the space is increased. But if you shrink the frame too small the components will revert to (0, 0) which is thee minimum size. If you don't like this behaviour, then you will need to set minimum size on all the components:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
setLayout( new BorderLayout() );
JComponent component;
JPanel vBox = new JPanel( new GridBagLayout() );
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = GridBagConstraints.REMAINDER;
component = new JTextField(10);
gbc.anchor = GridBagConstraints.LINE_START;
vBox.add(component, gbc);
component = new JTextField(10);
gbc.anchor = GridBagConstraints.LINE_END;
vBox.add(component, gbc);
component = new JTextField(30);
gbc.anchor = GridBagConstraints.CENTER;
vBox.add(component, gbc);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new SSCCE() );
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}

java - swing - components not listening to bounds

I am trying to create a frame, and when I am adding some components they don't listen to the sizes I give them, or locations - whenever I resize the frame, the components stick together, one aside another. Also, I have a scrollable text area, which takes the length and width of the text written in it. Plus, if I don't resize the frame the components don't show.
My code:
public static void main(String[] args){
new Main();
}
private void loadLabel(){
label.setBounds(0,0,269,20);
//Setting the icon, not relevant to the code.
panel.add(label);
}
private void loadInput(){
input.setBounds(0,20,300,60);
JScrollPane scroll = new JScrollPane (input);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scroll.setVisible(true);
scroll.setBounds(50,20,300,60);
panel.add(scroll);
}
private JPanel panel = new JPanel();
private JLabel label = new JLabel();
private JTextArea input = new JTextArea("Enter message ");
public Main() {
super("Frame");
setLocationRelativeTo(null);
setSize(300, 400);
setContentPane(panel);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
loadLabel();
loadInput();
}
Thanks in advance!
You shouldn't arrange your components using .setBounds(,,,) but instead arrange your
components using layout ( http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html ).
Plus you haven't set your label a text or icon so it's hard to see those component correctly. Here i'm using BoxLayout to manage your components vertically and put them on the EAST side of your frame by replacing setContentPane(panel); to getContentPane().add(panel,BorderLayout.EAST); to help us see your components correctly.
import java.awt.*;
import javax.swing.*;
public class Main extends JFrame {
public static void main(String[] args){
new Main();
}
private void loadLabel(){
label.setBounds(0,0,269,20);
//Setting the icon, not relevant to the code.
panel.add(label);
}
private void loadInput(){
input.setBounds(0,20,300,60);
JScrollPane scroll = new JScrollPane (input);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scroll.setVisible(true);
scroll.setBounds(50,20,300,60);
panel.add(scroll);
}
private JPanel panel = new JPanel();
private JLabel label = new JLabel("Your Label");
private JTextArea input = new JTextArea("Enter message ");
public Main() {
super("Frame");
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
setLocationRelativeTo(null);
setSize(300, 400);
getContentPane().add(panel,BorderLayout.EAST);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
loadLabel();
loadInput();
}
}
Write like this
loadLabel();
loadInput();
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Load the content then make it visible true

Adding elements (i.e. JLabels) outside of the set layout

As part of a project we've got to have 9 boxes, here I've just implemented alternating colors as an example in place of the images we should be using. But whilst I want these 9 JLabels in this grid layout (3,3), I also want to have a message at the top (a JLabel) that I can just centralize, like a welcoming message as well as having around four JButtons underneath? Can somebody please point me in the right direction as to how to achieve this?
Thank you!
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class HomeController extends JPanel implements MouseListener
{
HomeController()
{
setLayout(new GridLayout(3,3));
JLabel apl1 = new JLabel("");
apl1.setBackground(Color.WHITE);
apl1.setOpaque(true);
this.add(apl1);
JLabel apl2 = new JLabel("");
apl2.setBackground(Color.BLACK);
apl2.setOpaque(true);
this.add(apl2);
JLabel apl3 = new JLabel("");
apl3.setBackground(Color.WHITE);
apl3.setOpaque(true);
this.add(apl3);
JLabel apl4 = new JLabel("");
apl4.setBackground(Color.BLACK);
apl4.setOpaque(true);
this.add(apl4);
JLabel apl5 = new JLabel("");
apl5.setBackground(Color.WHITE);
apl5.setOpaque(true);
this.add(apl5);
JLabel apl6 = new JLabel("");
apl6.setBackground(Color.BLACK);
apl6.setOpaque(true);
this.add(apl6);
JLabel apl7 = new JLabel("");
apl7.setBackground(Color.WHITE);
apl7.setOpaque(true);
this.add(apl7);
JLabel apl8 = new JLabel("");
apl8.setBackground(Color.BLACK);
apl8.setOpaque(true);
this.add(apl8);
JLabel apl9 = new JLabel("");
apl9.setBackground(Color.WHITE);
apl9.setOpaque(true);
this.add(apl9);
JLabel message = new JLabel("hello world");
this.add(message);
}
}
You can combine multiple panels with different layouts. For details take a look at A Visual Guide to Layout Managers.
For example, default layout of JFrame is BorderLayout. Using BorderLayout, you can place the title at BorderLayout.NORTH, panel with buttons at BorderLayout.SOUTH and panel with grid of labels at BorderLayout.CENTER. Each panel may have its own more complex layout. For example, grid of labels is using GridLayout, and buttons panel is using FlowLayout.
Here is a very simple example based on the posted code that demonstrates this approach:
import java.awt.*;
import javax.swing.*;
public class TestGrid {
public TestGrid() {
final JFrame frame = new JFrame("Grid");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel(new GridLayout(3, 3));
for (int idx = 0; idx < 9; idx++) {
JLabel label = new JLabel();
label.setBackground(idx % 2 == 0 ? Color.WHITE : Color.BLACK);
label.setOpaque(true);
mainPanel.add(label);
}
mainPanel.setPreferredSize(new Dimension(200, 200));
frame.add(mainPanel, BorderLayout.CENTER);
frame.add(new JLabel("Title", JLabel.CENTER), BorderLayout.NORTH);
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(new JButton("Start"));
buttonsPanel.add(new JButton("Stop"));
frame.add(buttonsPanel, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestGrid();
}
});
}
}

How to set the height and the width of a textfield in Java?

I was trying to make my JTextField fill the width and set a height for it but still failed. I tried adding the code setPreferredSize(new Dimension(320,200)); but still failed. Is there any way I can make my JTextField fill the width and set the height to 200 or something?
You should not play with the height. Let the text field determine the height based on the font used.
If you want to control the width of the text field then you can use
textField.setColumns(...);
to let the text field determine the preferred width.
Or if you want the width to be the entire width of the parent panel then you need to use an appropriate layout. Maybe the NORTH of a BorderLayout.
See the Swing tutorial on Layout Managers for more information.
set the height to 200
Set the Font to a large variant (150+ px). As already mentioned, control the width using columns, and use a layout manager (or constraint) that will respect the preferred width & height.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class BigTextField {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
// the GUI as seen by the user (without frame)
JPanel gui = new JPanel(new FlowLayout(5));
gui.setBorder(new EmptyBorder(2, 3, 2, 3));
// Create big text fields & add them to the GUI
String s = "Hello!";
JTextField tf1 = new JTextField(s, 1);
Font bigFont = tf1.getFont().deriveFont(Font.PLAIN, 150f);
tf1.setFont(bigFont);
gui.add(tf1);
JTextField tf2 = new JTextField(s, 2);
tf2.setFont(bigFont);
gui.add(tf2);
JTextField tf3 = new JTextField(s, 3);
tf3.setFont(bigFont);
gui.add(tf3);
gui.setBackground(Color.WHITE);
JFrame f = new JFrame("Big Text Fields");
f.add(gui);
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See http://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}
There's a way which maybe not perfect, but can meet your requirement. The main point here is use a special dimension to restrict the height. But at the same time, width actually is free, as the max width is big enough.
package test;
import java.awt.*;
import javax.swing.*;
public final class TestFrame extends Frame{
public TestFrame(){
JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
p.setPreferredSize(new Dimension(500, 200));
p.setMaximumSize(new Dimension(10000, 200));
p.add(new JLabel("TEST: "));
JPanel p1 = new JPanel();
p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));
p1.setMaximumSize(new Dimension(10000, 200));
p1.add(new JTextField(50));
p.add(p1);
this.setLayout(new BorderLayout());
this.add(p, BorderLayout.CENTER);
}
//TODO: GUI CREATE
}
xyz.setColumns() method is control the width of TextField.
import java.awt.*;
import javax.swing.*;
class miniproj extends JFrame {
public static void main(String[] args)
{
JFrame frame=new JFrame();
JPanel panel=new JPanel();
frame.setSize(400,400);
frame.setTitle("Registration");
JLabel lablename=new JLabel("Enter your name");
TextField tname=new TextField(30);
tname.setColumns(45);
JLabel lableemail=new JLabel("Enter your Email");
TextField email=new TextField(30);
email.setColumns(45);
JLabel lableaddress=new JLabel("Enter your address");
TextField address=new TextField(30);
address.setColumns(45);
address.setFont(Font.getFont(Font.SERIF));
JLabel lablepass=new JLabel("Enter your password");
TextField pass=new TextField(30);
pass.setColumns(45);
JButton login=new JButton();
JButton create=new JButton();
login.setPreferredSize(new Dimension(90,30));
login.setText("Login");
create.setPreferredSize(new Dimension(90,30));
create.setText("Create");
panel.add(lablename);
panel.add(tname);
panel.add(lableemail);
panel.add(email);
panel.add(lableaddress);
panel.add(address);
panel.add(lablepass);
panel.add(pass);
panel.add(create);
panel.add(login);
frame.add(panel);
frame.setVisible(true);
}
}
What type of LayoutManager are you using for the panel you're adding the JTextField to?
Different layout managers approach sizing elements on them in different ways, some respect SetPreferredSize(), while others will scale the compoenents to fit their container.
See: http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
ps. this has nothing to do with eclipse, its java.
f.setLayout(null);
add the above lines ( f is a JFrame or a Container where you have added the JTestField )
But try to learn 'LayoutManager' in java ; refer to other answers for the links of the tutorials .Or try This http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
maybe applying an EmptyBorder to your JTextField would be the simplest solution to simulate a height, and for the width use the setColumns() method
JTextField input=new JTextField();
input.setColumns(10);
input.setBorder(new EmptyBorder(15,0,15,0);
the 4 arguments of the EmptyBorder constructor are: top, left, bottom and right respectively.
Or if you want something more technical you can override the getPreferredSize, getMinimumSize and getMaximumSize methods so that it returns the values ​​you want to apply as width and height.
JTexField input=new JTextField(){
#Override
public Dimension getPreferredSize(){
return new Dimension(200,40);
};
public Dimension getMinimumSize(){
return new Dimension(200,40);
};
public Dimension getMaximumSize(){
return new Dimension(200,40);
};
};
package myguo;
import javax.swing.*;
public class MyGuo {
JFrame f;
JButton bt1 , bt2 ;
JTextField t1,t2;
JLabel l1,l2;
MyGuo(){
f=new JFrame("LOG IN FORM");
f.setLocation(500,300);
f.setSize(600,500);
f.setLayout(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
l1=new JLabel("NAME");
l1.setBounds(50,70,80,30);
l2=new JLabel("PASSWORD");
l2.setBounds(50,100,80,30);
t1=new JTextField();
t1.setBounds(140, 70, 200,30);
t2=new JTextField();
t2.setBounds(140, 110, 200,30);
bt1 =new JButton("LOG IN");
bt1.setBounds(150,150,80,30);
bt2 =new JButton("CLEAR");
bt2.setBounds(235,150,80,30);
f.add(l1);
f.add(l2);
f.add(t1);
f.add(t2);
f.add(bt1);
f.add(bt2);
f.setVisible(true);
}
public static void main(String[] args) {
MyGuo myGuo = new MyGuo();
}
}
setBounds is working only in BorderLayout use BorderLayout for frame or container or panel and use setBounds to set the width and height of text field.
see this code simple code
import java.awt.*;
import javax.swing.*;
class uni1
{
public static void main(String[] args)
{
JFrame frm = new JFrame();
TextField txt = new TextField();
txt.setBounds(0, 0, 1200, 400);
frm.add(txt,BorderLayout.NORTH);
frm.setLayout(new BorderLayout());
frm.setVisible(true);
frm.setDefaultCloseOperation(frm.EXIT_ON_CLOSE);
}
}

Categories

Resources