I've been reading around lately on centering a JLabel in a JPanel. I've seen a lot of the following two answers:
label.setHorizontalAlignment(JLabel.CENTER);
and in the creation of the JLabel
static JLabel label = new JLabel("Some Text Here", SwingConstants.CENTER);
Neither of these options that I have tried have worked. All the text becomes left alligned with both of these answers (I've even tried using both of them at the same time, and no luck). Here is the full code for one of my labels with its instantiation and everything:
//JLabel title = new JLabel("Title", SwingConstants.CENTER);
JLabel title = new JLabel("Title");
title.setVisible(true);
title.setForeground(Color.BLACK);
title.setFont(new Font("Monospaced", Font.BOLD, 32));
//title.setHorizontalAlignment(JLabel.CENTER);
title.setLocation((int)width/2-190,10);
title.setSize(250,100);
frame.add(title);
I commented out the code that just left aligns it and is supposed to work. For the set location, I'm using:
static Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
static double width = screenSize.getWidth();
static double height = screenSize.getHeight();
to define the screen's parameters, and then use that to keep the centering somewhat abstract. However, obviously monitor size changes and 9 times out of 10, the code I have here for setLocation isn't going to center it on your screen.
I'm really curious to why this isn't working for me. Is it because I'm not adding the JLabel to a JPanel? I was under the assumption that JLabel could lay over a JFrame in the same way it layed over a JPanel.
EDIT
I just also tried
frame.add(title,BorderLayout.CENTER);
and had the same result as the other 2 options above.
This works for me (NOTE: SwingConstants.CENTER, not SwingConstraints.CENTER):
public static void main( String[] args ) {
SwingUtilities.invokeLater( new Runnable() {
#Override
public void run() {
JFrame jf = new JFrame();
jf.addWindowListener( new WindowAdapter() {
#Override
public void windowClosing( WindowEvent arg0 ) {
System.exit( 0 );
}
} );
JLabel t = new JLabel( "Centered", SwingConstants.CENTER );
jf.add( t, BorderLayout.CENTER );
jf.setSize( 300, 300 );
jf.setVisible( true );
}
} );
}
Also:
import java.awt.Color;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
public class CenterDemo2 {
public static void main(final String[] args ) {
SwingUtilities.invokeLater( new Runnable() {
#Override
public void run() {
final JFrame frame = new JFrame("Test frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JLabel label = new JLabel("Test label");
label.setBorder(new LineBorder(Color.BLUE, 2)); //Adding a border for clarity.
//Most significant two lines of code:
final JPanel containerPanel = new JPanel(new GridBagLayout());
containerPanel.add(label);
frame.getContentPane().add(containerPanel); //or: frame.setContentPane(containerPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
The JLabel is in the (horizontal and vertical) center of the JPanel.
Screenshot, after dragging with the mouse to resize the frame:
Related
Been a while since I've been here. I'm learning java and have a question as to why the panel I've created in a JSplitPane can be resized beyond the maximum that I've set:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MainWindow {
//set all components
JFrame frame;
JPanel showPanel;//displays individual contact when clicked on in the contacts panel;
JPanel listPanel;// displays the contactsPanel
JSplitPane contactsSplitPane;
public void buildMainWindow() {// open method
frame = new JFrame("Contacts");
frame.setBackground(Color.WHITE);
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
showPanel = new JPanel();
showPanel.setBackground(Color.WHITE);
listPanel = new JPanel();
listPanel.setBackground(Color.LIGHT_GRAY);
listPanel.setMaximumSize(new Dimension (300,1000));
//create SplitPane for the listPanel and showPanel
contactsSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, listPanel,showPanel);
contactsSplitPane.setOneTouchExpandable(true);
contactsSplitPane.setDividerLocation(50);
frame.setSize(1000, 1000);
frame.setVisible(true);
frame.add(BorderLayout.CENTER, contactsSplitPane);
}//close method
public static void main (String [] args) {
MainWindow MainWindow = new MainWindow ();
MainWindow.buildMainWindow();
}
}// close class
feel free to run and compile. I've set the size of the listPanel to a maximum of 300 pixels, but I can resize it way beyond that -- almost to the end of the frame. It's not possible to crate a single resizable pane, no?
Can someone let me know what I'm doing wrong? I'm obviously missing something, but I don't know what.
A JSplitPane doesn't respect the maximum size of either component.
However, it does respect the minimum size of a component.
So one approach could be do set the minimum size on the other component added to the split pane. You will need to override the getMinimumSize() method of this component since the size of the split pane can change dynamically.
Something like:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SplitPaneMaximum extends JPanel
{
JSplitPane splitPane;
public SplitPaneMaximum()
{
setLayout( new BorderLayout() );
JPanel red = new JPanel();
red.setBackground( Color.RED );
red.setPreferredSize( new Dimension(200, 100) );
red.setMinimumSize( new Dimension(100, 0) );
JPanel blue = new JPanel()
{
// Setting a minimum size here will limit the maximum size
// of the other component added to the split pane
#Override
public Dimension getMinimumSize()
{
int parentWidth = getParent().getSize().width;
Dimension d = getSize();
d.width = parentWidth - 200;
return d;
}
};
blue.setBackground( Color.BLUE );
blue.setPreferredSize( new Dimension(200, 100) );
splitPane = new JSplitPane();
splitPane.setLeftComponent( red );
splitPane.setRightComponent( blue );
splitPane.setResizeWeight(0.50);
add(splitPane, BorderLayout.CENTER);
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("SplitPaneMaximum");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new SplitPaneMaximum() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
Now the width of the red panel can only be sized between 100 and 200 pixels.
I made a Java program and part of the program's function is to track the user's mouse X and Y coordinates.
The tracking works nicely but there's a small problem that bothers me.
When I move my mouse around the screen, the other components automatically change position.
Here's a MRE(Minimal Reproducible Example):
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.event.ActionListener;
public class Test {
static Timer t;
static JLabel label1;
static InnerTest inner;
static int mouseX;
static int mouseY;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
buildFrame();
runTimer();
}
});
}
public static void buildFrame() {
JFrame frame = new JFrame();
label1 = new JLabel("Test1");
JLabel label2 = new JLabel("Test Test");
JLabel label3 = new JLabel("Test Label Label");
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(label1);
panel.add(label2);
panel.add(label3);
label1.setAlignmentX(Component.CENTER_ALIGNMENT);
label2.setAlignmentX(Component.CENTER_ALIGNMENT);
label3.setAlignmentX(Component.CENTER_ALIGNMENT);
frame.getContentPane().add(panel);
frame.setSize(400, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void runTimer() {
inner = new InnerTest();
t = new Timer(20, inner);
t.start();
}
static class InnerTest implements ActionListener {
public void actionPerformed(ActionEvent e) {
mouseX = MouseInfo.getPointerInfo().getLocation().x * 100;
mouseY = MouseInfo.getPointerInfo().getLocation().y * 100;
label1.setText(" ( "+String.valueOf(mouseX)+" , "+String.valueOf(mouseY)+" )");
}
}
}
How do I keep the components still when another component is updating?
The components are added to the same panel so each is centered based on the maximum width of all three components. As the width of the top label changes the others are also adjusted.
The solution is to separate the top label from the other two labels.
One way would be:
//panel.add(label1);
panel.add(label2);
panel.add(label3);
//label1.setAlignmentX(Component.CENTER_ALIGNMENT);
label1.setHorizontalAlignment(JLabel.CENTER); // added
label2.setAlignmentX(Component.CENTER_ALIGNMENT);
label3.setAlignmentX(Component.CENTER_ALIGNMENT);
frame.add(label1, BorderLayout.PAGE_START); // added
frame.getContentPane().add(panel);
Why does my Inner JPanel not display my JLabel text?
I have an outer JPanel, and an inner JPanel to display some text with the right dimensions. However I don't understand why it won't show?
JPanel jp = new JPanel();
jp.setBackground(Color.decode("#ffffff"));
jp.setBounds(0, 35, 400, 315);
JPanel mostInner = new JPanel();
mostInner.setForeground(Color.black);
mostInner.setBounds(207, 5, 190, 240);
jp.add(mostInner);
JLabel jltxt = new JLabel();
jltxt.setText("Test");
mostInner.add(jltxt);
Again, much better to avoid using null layouts and setBounds(...). While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't re-size your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
For example, the following code creates this GUI:
This uses a GridLayout to place a JPanel in the right hand side of another JPanel. If I wanted to add more components in different relative locations, it would be easy to do by simply nesting JPanels, each using its own layout.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.*;
public class WorkWithLayouts extends JPanel {
private static final long serialVersionUID = 1L;
private static final int PREF_W = 400;
private static final int PREF_H = 315;
private static final String BG = "#ffffff";
public WorkWithLayouts() {
JPanel mostInner = new JPanel();
mostInner.setForeground(Color.black);
mostInner.setOpaque(false); // if you want the backing jpanel's background to show through
// add title temporarily just to show where mostInner panel is
mostInner.setBorder(BorderFactory.createTitledBorder("most inner")); // TODO: delete this
JLabel jltxt = new JLabel();
jltxt.setText("Test");
mostInner.add(jltxt);
setBackground(Color.decode(BG));
setLayout(new GridLayout(1, 2));
add(new JLabel()); // empty label
add(mostInner);
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
} else {
return new Dimension(PREF_W, PREF_H);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
private static void createAndShowGui() {
WorkWithLayouts mainPanel = new WorkWithLayouts();
JFrame frame = new JFrame("Work With Layouts");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
As already mentioned by Hovercraft Full Of Eels, you can help us to help you by adding a small program to your question that shows your problem (see https://stackoverflow.com/help/mcve for more information). Then people can try to reproduce and solve the issue.
When I created a small program myself, it seemed to work fine:
import java.awt.*;
import javax.swing.*;
public class LabelNotVisible {
public static void main(String[] arguments) {
SwingUtilities.invokeLater(() -> new LabelNotVisible().createAndShowGui());
}
private void createAndShowGui() {
JFrame frame = new JFrame("Stack Overflow");
frame.setBounds(100, 100, 800, 200);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel jp = new JPanel();
jp.setBackground(Color.decode("#ffffff"));
//jp.setBounds(0, 35, 400, 315);
JPanel mostInner = new JPanel();
mostInner.setForeground(Color.black);
//mostInner.setBounds(207, 5, 190, 240);
jp.add(mostInner);
JLabel jltxt = new JLabel();
jltxt.setText("Test");
mostInner.add(jltxt);
frame.getContentPane().add(jp);
frame.setVisible(true);
}
}
For some reason i am having problems centering my panel vertically that is located inside another panel. I do exactly as the examples i studied but still no luck.
Down there is my code. Despite using setAlignmentY(0.5f) on my container panel, it still wont center when i resize the window.
Also the components inside container panel wont center either, despite setAligenmentX(0.5f).
I wonder if there is a solution for this, I pretty much tried everything out there but couldnt find a solution.
JLabel idLabel;
JLabel passLabel;
JTextField id;
JTextField pass;
JButton enter;
JPanel container;
public JournalLogin()
{
//setLayout(new FlowLayout());
//setPreferredSize(new Dimension(500, 500));
//setBorder(BorderFactory.createEmptyBorder(100, 100, 100, 100));
container = new JPanel();
container.setLayout(new MigLayout());
container.setAlignmentX(0.5f);
container.setAlignmentY(0.5f);
container.setPreferredSize(new Dimension(300, 300));
container.setBorder(BorderFactory.createTitledBorder("Login"));
add(container);
idLabel = new JLabel("ID:");
idLabel.setAlignmentX(0.5f);
container.add(idLabel);
id = new JTextField();
id.setText("id");
id.setAlignmentX(0.5f);
id.setPreferredSize(new Dimension(80, 20));
container.add(id, "wrap");
setAlignmentX and Y are not the way to go about doing this. One way to center a component in a container is to have the container use GridBagLayout and to add the component without using any GridBagConstraints, a so-called default addition. There are other ways as well.
For example to alter Nick Rippe's example (1+ to him):
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import javax.swing.*;
public class UpdatePane2 extends JPanel {
private static final int PREF_W = 300;
private static final int PREF_H = 200;
public UpdatePane2() {
JPanel innerPanel = new JPanel();
innerPanel.setLayout(new BorderLayout());
innerPanel.add(new JLabel("Hi Mom", SwingConstants.CENTER),
BorderLayout.NORTH);
innerPanel.add(new JButton("Click Me"), BorderLayout.CENTER);
setLayout(new GridBagLayout());
add(innerPanel);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("UpdatePane2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new UpdatePane2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Alignments tend to be pretty picky in Swing - they do [usually] work... but if all you're looking for is a panel that's centered, I'd recommend using Boxes in the BoxLayout (My personal favorite LayoutManager). Here's an example to get you started:
import java.awt.Dimension;
import javax.swing.*;
public class UpdatePane extends JPanel{
public static void main(String... args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
//Create Buffers
Box verticalBuffer = Box.createVerticalBox();
Box horizontalBuffer = Box.createHorizontalBox();
verticalBuffer.add(Box.createVerticalGlue()); //Top vertical buffer
verticalBuffer.add(horizontalBuffer);
horizontalBuffer.add(Box.createHorizontalGlue()); //Left horizontal buffer
//Add all your content here
Box mainContent = Box.createVerticalBox();
mainContent.add(new JLabel("Hi Mom!"));
mainContent.add(new JButton("Click me"));
horizontalBuffer.add(mainContent);
horizontalBuffer.add(Box.createHorizontalGlue()); //Right horizontal buffer
verticalBuffer.add(Box.createVerticalGlue()); //Bottom vertical buffer
// Other stuff for making the GUI
verticalBuffer.setPreferredSize(new Dimension(300,200));
JFrame frame = new JFrame();
frame.add(verticalBuffer);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
You will need to get the LayoutManager to center the layout for you. Currently it looks like the implementation of "MigLayout" does not honor the Alignment. Try changing it or creating a subclass.
Hi all!
I'm trying to solve an -apparently- simple problem, but I cannot fix it.
I'm working on a sample application with Java/Swing libraries;
I have a JFrame and a JPanel.
I just want to achieve the following objectives:
JPanel MUST be centered inside the JFrame.
JPanel MUST have ALWAYS the size that is specified with
setPreferredSize() method. It MUST NOT be resized under this size.
I tried by using a GridBagLayout: it's the ONLY way I can do it.
See the sample below:
/* file StackSample01.java */
import java.awt.*;
import javax.swing.*;
public class StackSample01 {
public static void main(String [] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(100, 100));
panel.setBackground(Color.RED);
frame.setLayout(new GridBagLayout());
frame.add(panel, new GridBagConstraints());
frame.setSize(new Dimension(200, 200));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Here a screenshot:
I would not use a GridBagLayout to do a thing too simple.
I tried a simplest solution, by using a Box, but this does not work:
Sample code:
/* file StackSample02.java */
import java.awt.*;
import javax.swing.*;
public class StackSample02 {
public static void main(String [] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(100, 100));
panel.setBackground(Color.RED); // for debug
panel.setAlignmentX(JComponent.CENTER_ALIGNMENT); // have no effect
Box box = new Box(BoxLayout.Y_AXIS);
box.add(Box.createVerticalGlue());
box.add(panel);
box.add(Box.createVerticalGlue()); // causes a deformation
frame.add(box);
frame.setSize(new Dimension(200, 200));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Here a screenshot,
Any ideas? Thanks to all :-)
BoxLayout can pretty to hold your setXxxSize(), then just add panel.setMaximumSize(new Dimension(100, 100));
and your output would be
Removed by setMinimumSize(notice if Container has greater size as ... )
import java.awt.*;
import javax.swing.*;
public class CustomComponent12 extends JFrame {
private static final long serialVersionUID = 1L;
public CustomComponent12() {
Box box = new Box(BoxLayout.Y_AXIS);
box.setAlignmentX(JComponent.CENTER_ALIGNMENT);
box.add(Box.createVerticalGlue());
box.add(new CustomComponents12());
box.add(Box.createVerticalGlue());
add(box);
pack();
setTitle("Custom Component Test / BoxLayout");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setMaximumSize(getMinimumSize());
setMinimumSize(getMinimumSize());
setPreferredSize(getPreferredSize());
setLocation(150, 150);
setVisible(true);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
CustomComponent12 main = new CustomComponent12();
}
};
javax.swing.SwingUtilities.invokeLater(r);
}
}
class CustomComponents12 extends JPanel {
private static final long serialVersionUID = 1L;
#Override
public Dimension getMinimumSize() {
return new Dimension(100, 100);
}
#Override
public Dimension getMaximumSize() {
return new Dimension(100, 100);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 100);
}
#Override
public void paintComponent(Graphics g) {
int margin = 10;
Dimension dim = getSize();
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);
}
}
First of all, thanks to all.
I reply another time to my own question, to show everyone the choice I have made.
See the sample code below;
As you can see, I have included only minimal steps which are absolutely necessary to achieve the goal.
/* file StackResponse.java */
import java.awt.*;
import javax.swing.*;
public class StackResponse {
public static void main(String [] args) {
JPanel panel = new JPanel();
Dimension expectedDimension = new Dimension(100, 100);
panel.setPreferredSize(expectedDimension);
panel.setMaximumSize(expectedDimension);
panel.setMinimumSize(expectedDimension);
panel.setBackground(Color.RED); // for debug only
Box box = new Box(BoxLayout.Y_AXIS);
box.add(Box.createVerticalGlue());
box.add(panel);
box.add(Box.createVerticalGlue());
JFrame frame = new JFrame();
frame.add(box);
frame.setSize(new Dimension(200, 200));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setMinimumSize(frame.getMinimumSize()); // cannot be resized-
frame.setVisible(true);
}
}
Here you can see a screenshot.
Problem solved.
Many thanks again to all.
IT
create a panel by name "FixedPanel" with GridBagLayout and set preferred size to frame size
then add your frame into FixedPanel.
Frame = new JFrame("CenterFrame");
Frame.setLocation(0, 0);
Frame.setSize(new Dimension(400,400));//dim
JPanel FixedPanel = new JPanel(new GridBagLayout());
FixedPanel.setPreferredSize(Frame.getSize());
JPanel myPanel = new JPanel();
myPanel.setPreferredSize(new Dimension(100,100));
myPanel.setBackground(Color.BLACK);
FixedPanel.add(myPanel);
Frame.add(FixedPanel);
Frame.setVisible(true);
You can do this. I had to make a chess game, and I wanted the chess piece piece to always go in the center of a cell which was a JlayeredPane:
private void formMouseReleased(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
if (jl != null)
{
jl.setLocation(evt.getX()+10, evt.getY()+10);
Component com = findComponentAt(evt.getPoint());
if (com instanceof JPanel)
{
// System.out.println("Yes, it's a jpanel");
((JPanel)com).add(jl);
((JPanel)com).validate();
}
}
}
Its Just Having
jPanel.setBounds(x, y, 1046, 503);
Where x is space for right side and y is space for left side.
you have to calculate the space from both side according to screen height and width
use
panel.setMaximumSize(new Dimension(200,200));
panel.setResizable(false)
instead?