Java - how to center vertical column of components? - java

It's very simple, what I want to do, but I can't figure out a way to do it. In a JFrame or JPanel, how do you center components vertically? That is, analogous to using the center tag in HTML. The components are in a column and they are all centered.
I have tried BoxLayout, with Y_AXIS and PAGE_AXIS, but it aligns the components in a strange way for me. I have tried to use FlowLayout with preferred size set so it wraps around, but it doesn't center it. I'd rather not resort to something powerful like GridBagLayout for such a simple thing unless it is really the only option. Help!

If I had to make a guess I would say that you are using components with a different "x alignment". Try using:
component.setAlignmentX(JComponent.CENTER_ALIGNMENT);
See the section from the Swing tutorial on Fixing Alignment Problems for more information.
If you need more help then post your SSCCE showing what you have tried.
Edit:
import java.awt.*;
import javax.swing.*;
public class BoxLayoutTest extends JFrame
{
public BoxLayoutTest()
{
Box box = new Box(BoxLayout.Y_AXIS);
add( box );
JLabel label = new JLabel("I'm centered");
label.setAlignmentX(JComponent.CENTER_ALIGNMENT);
box.add( Box.createVerticalGlue() );
box.add( label );
box.add( Box.createVerticalGlue() );
}
public static void main(String[] args)
{
BoxLayoutTest frame = new BoxLayoutTest();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.setSize(300, 300);
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}

Related

Setting Background of a JTextPane leads to visual artifacts (Java)

this is my first question on stackoverflow so pls don't be so hard with me (and my English), I'll try my best asking a good question.
The problem is about what the title suggests -> setting the background of a JTextpane (specifically setting it transparent). As the setBackground-method takes a color argument, the way i went was with an alpha value = 0. This leads to the following visual artifacts:
example picture of the visual artifacts when running the code below
I will describe it in detail now, say what i've already tried and then post a minimal example for everyone to be able to recreate the bug easily.
I have a JFrame (myFrame) holding a JPanel (Test()) in which i paint. The background of this JPanel is set to green as you can see in the code. I did this to differ between the background of the TextPane and the actual background of the panel.
We also have a JTextPane inputfield -> which takes user input (it displays what you write). This is held by a JScrollPane scrollpane.
So the Target (meaning what i try to achieve): is a User input field, which is transparent, but still displays the text the user puts in. I tried to achieve this by setting the background of the inputfield and the scrollpane to a transparent color.
I would really appreciate it, if you don't just type something like (you need to setOpague(false) for ....) if you don't know exactly what you're talking about, because i nearly tried everything i can think of and read every post i could find in the internet about the problem. I will post some of them at the end. So...
What i already tried:
The usual way i found while searching for something like "How to make TextPane transparent" was to setOpague(false) at itself as well as the scrollpane and the viewport of the scrollpane. 1. Reading about what the method actually does i don't think that is a proper solution. 2. setting Opague(false) on these three leads to everything being invisible so, that's not good. Packing the frame again after setting the background. Either nothing was fixed or the components became completely invisible.
I also tried: setBackground(null), setting the Background of just the inputfield (just every single component and every possible combination amongst the three (scrollpane, viewport, inputfield)), mixing setOpague(true)/setOpague(false)/setBackground(...) in every way i could think of. Overriding the paintComponent method of the textpane and scrollpane seemed like a good approach, but i did not come very far with it.
So here is the code:
public class Test extends JPanel {
JTextPane inputField = new JTextPane();
JScrollPane scrollpane = new JScrollPane(inputField);
#Override
public void paint(Graphics g) {
super.paint(g);
inputField.setBounds(10,10,100,100);
scrollpane.setBounds(10,10,100,100);
}
public Test(){
this.setOpaque(true);
this.setBackground(Color.GREEN);
inputField.setBounds(10,10,100,100);
scrollpane.setBounds(10,10,100,100);
inputField.setBackground(new Color(0,0,0,0));
scrollpane.setBackground(new Color(0,0,0,0));
scrollpane.getViewport().setBackground(new Color(0,0,0,0));
this.add(scrollpane);
}
public static void main(String[] args) {
JFrame myFrame = new JFrame();
myFrame.add(new Test());
myFrame.pack();
myFrame.setSize(640,480);
myFrame.setPreferredSize(new Dimension(640,480));
myFrame.setVisible(true);
}
}
And here some links to posts I read which describe similar problems:
Java - Transparent JScrollPane
Transparent JEditorPane in a JScrollPane over a background JPanel
setOpaque(true/false); Java
I would really appreciate if someone can help me with the problem or even only suggest me an alternative solution. I'm writing a little chat-program atm for a project for my university and i think transparent message fields are a neat idea. I will try to answer here as fast as i can. Thx in advance.
Do not use transparent color as background - kind of hard to delete with it (e.g. when component is being repaint (and opaque)).
Do not use setBounds (unless using null LayoutManager). In below example I used setPreferredSize but still better to correctly use LayoutManager (I am a bit lazy, and lot of work to do at the moment).
public class Test extends JPanel {
JTextPane inputField = new JTextPane();
JScrollPane scrollpane = new JScrollPane(inputField);
public Test(){
this.setOpaque(true);
this.setBackground(Color.GREEN);
inputField.setPreferredSize(new Dimension(300, 100));
inputField.setOpaque(false);
scrollpane.setOpaque(false);
scrollpane.getViewport().setOpaque(false);
this.add(scrollpane);
}
public static void main(String[] args) {
JFrame myFrame = new JFrame();
myFrame.add(new Test());
myFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
myFrame.setPreferredSize(new Dimension(640,480));
myFrame.pack();
myFrame.setVisible(true);
}
}
The whole code of main should be called on the EDT (e.g. SwingUtilities.invokeLater) since it is manipulating swing components but that is not part of the question (and not that relevant here since setVisible is the last command - components not being displayed while changed).
Your program gave me some errors when launching, occasionally. Make sure to run a swing GUI from the EDT (invokeLater()).
The line that is causing your issue is:
scrollpane.getViewport().setBackground(new Color(0,0,0,0));
Also - is there some reason you are setting bounds manually instead of using a layout manager?
Maybe I didn't understand your question, or you want to have an image in the background - but could you not just set the color of your text area to be the same color as your JPanel?
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
public class Test extends JPanel {
JTextPane inputField = new JTextPane();
JScrollPane scrollpane = new JScrollPane(inputField);
public Test(){
this.setBackground(Color.GREEN);
scrollpane.setPreferredSize(new Dimension(300, 300));
inputField.setBackground(Color.GREEN);
this.add(scrollpane);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame myFrame = new JFrame();
myFrame.add(new Test());
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setPreferredSize(new Dimension(640,480));
myFrame.pack();
myFrame.setVisible(true);
}
});
}
}

How to make a Jframe containing a Jpanel scrollable?

So I have this JFrame that contains a JPanel and in there I add JLabels with information I want but since I'll be adding labels all the time at some point the text is too long to appear so I want to add a scrollbar. Basically I want to make my JFrame with a JPanel in it scrollable. I have this code but my problem is that even though the scrollbar appears but it doesnt move and doesn't really work when the text is a lot, meaning the text still gets cut out and the scrollbar is there not moving. Does anyone know how to fix this?
import javax.swing.*;
import java.awt.*;
import java.util.*;
public class Bar {
JFrame info = new JFrame("Information");
JLabel ballinf = new JLabel();
JPanel contentPane = new JPanel();
JScrollPane scrolling = new JScrollPane();
public Bar(){
contentPane.setOpaque(true);
contentPane.setBackground(Color.WHITE);
contentPane.setLayout(null);
scrolling = new JScrollPane(contentPane,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
info.add(scrolling);
info.setSize(750, 600);
info.setLocationByPlatform(true);
info.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
info.setVisible(true);
}
public void adding(int pos){
ballinf = new JLabel("Something ",JLabel.CENTER);//assume the text will be bigger here and have more info
ballinf.setSize(700, 30);
ballinf.setForeground(Color.green);
ballinf.setLocation(5, 5+pos);
contentPane.add(ballinf);
info.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
info.setVisible(true);
}
public static void main(String[] args){
Bar stats = new Bar();
stats.adding(0);
stats.adding(20);//this will be done in a for loop for more than 2 times so the text ends up to be a lot
}
}
contentPane.setLayout(null);
Don't use a null layout!!!
You need to use an appropriate layout manager. Read the section from the Swing tutorial on Layout Managers for more information and working examples. The layout manager will then determine the preferred size of the panel as you add components to the panel.
The scrollpane will then display the scrollbars when necessary.
If you dynamically add components to the panel (after the GUI is visible) then the code should be something like:
panel.add(...);
panel.revalidate();
panel.repaint();

How to use setBounds method for a JLabel?

I'm making a window application with Swing. I am using the setBounds() method for the JLabel spacing but it's not working.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FullScreenJFrame extends JFrame
{
public FullScreenJFrame( String title )
{
super(title);
//JFrame frame = new JFrame();
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setUndecorated(true);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setBounds(0,0,screenSize.width, screenSize.height);
getContentPane()
.add(new JLabel(" HIGHCOURT OF JUDICATURE AT ALLHAHABAD"), BorderLayout.NORTH);
JLabel label = new JLabel("JJ");
label.setBounds(20, 20, 150, 20);
// label.setText(s);
add(label);
}
public static void main( String[] args )
{
FullScreenJFrame frame = new FullScreenJFrame("");
//JFrame frame1 = new JFrame();
//JLabel label = new JLabel("dd");
//label.setBounds(370, 340, 150, 20);
//frame1.add(label);
frame.setVisible(true);
}
}
One advice, It seems you are going to show your application using all screen so try to avoid the use of absolute positions like setBoundMethod.
You should fit your application within a layout that uses other layouts within it. Check this link.
http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
Don't use setBounds() to resize a component. Use a Layout Manager and you won't be worried about manually doing this.
Why?
Why are going for absolute positioning, when Layout Managers do it for you.
One more thing, If your JFrame does not contain any title so there is no need to add empty title as it is bad practice.
Replace
FullScreenJFrame frame = new FullScreenJFrame("");
By
FullScreenJFrame frame = new FullScreenJFrame();
And
public FullScreenJFrame( String title )
By
public FullScreenJFrame()
No need to call
super(title);
Or in order to set your layout as null right click on your form and click set layout then click null layout.
Are null layouts recommended? As other have suggested, the answer is NO.
See Laying out Components in a Container to get some practice in with LayoutManagers
Will I still answer your question? Sure. Just so you know.
"I am using the setBounds() method for the JLabel spacing but it's not working. Please, can any one tell me why it is not working?"
Yes, your bounds aren't working because the JFrame has a default Borderlayout. In order for setBounds to work, the layout needs to be null.
setLayout(null);
Also, keep in mind that when you do use a null layout, any components in which you don't setBounds for will not appear.
See Laying out Components in a Container to get some practice in with LayoutManagers

Java align JLabel in center of JPanel

I have a bar at the top of my application that has a number of buttons either side of a JLabel. The button's visibility is dependent upon the current task a user is carrying out and one of the button's text may also change depending on the current state.
What I would like to do is have a number of buttons stick to the left of the JPanel, the JLabel's center to be in the very center of the JPanel and the rest of the buttons to be to the right of the JPanel.
So far I have managed to get the buttons sticking to the left and the right using various methods and layout managers but I cannot get the JLabel's center to be in the dead center of the JPanel. The best I have managed to get is the label near enough to the center but it would then move around as the buttons are set to visible or their text changes.
Is it possible to force the JLabel to remain dead center?
Note: the buttons will never become big enough to meet either edge of the JLabel, so that is not a problem.
You could also use a BoxLayout, with X_AXIS layout, and add to the container
Edit: Here's an example
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.add(Box.createHorizontalGlue());
panel.add(innerPanel);
panel.add(Box.createHorizontalGlue());
As I see it you need the label to be displayed at its preferred size and then you need a left and right panel to equally fill the remaining space available in the window.
You can use the Relative Layout class.
import java.awt.*;
import javax.swing.*;
public class RelativeSSCCE extends JPanel
{
public RelativeSSCCE()
{
JPanel left = new JPanel( new FlowLayout(FlowLayout.LEFT) );
left.add( new JButton("L1") );
left.add( new JButton("L2") );
left.add( new JButton("L3") );
JLabel center = new JLabel("Centered");
JPanel right = new JPanel( new FlowLayout(FlowLayout.RIGHT) );
right.add( new JButton("Right1") );
right.add( new JButton("Right2") );
right.add( new JButton("Right3") );
// choose your layout manager here
setLayout( new RelativeLayout() );
Float ratio = new Float(1);
add(left, ratio);
add(center);
add(right, ratio);
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("Basic RelativeSSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new RelativeSSCCE() );
frame.setSize(600, 100);
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
Use BorderLayout. Add the JLabel with the BorderLayout.CENTER constraint and add a pair of JPanels with the BorderLayout.EAST and BorderLayout.WEST constraints. Add your additional buttons to the appropriate JPanel.
To have the text appear centered, you also need to set the Label's horizontalAlignment to JLabel.CENTER.
setAlignmentX(java.awt.Component.CENTER_ALIGNMENT)
and
setAlignmentY(java.awt.Component.CENTER_ALIGNMENT)
may help if used with the elements which have to be centered, e.g. JPanel
may be I`m necroposting, but setAlignmentX(java.awt.Component.CENTER_ALIGNMENT) and setAlignmentY(java.awt.Component.CENTER_ALIGNMENT) may help...

Java Swing - JLabel Location

I have problem while setting the Jlabel location.
I set the content pane to some JPanel, I created and tried to add my JLabel.
JLabel mainTitle = new JLabel("SomeApp");
mainTitle.setFont(new Font("Arial",2 , 28));
mainTitle.setBounds(0,0, 115, 130);
getContentPane().add(mainTitle);
I want that my JPanel will be on the top left corner on my application and what I am getting is "SomeApp" on the top center.(and not top left).
btw I tried to add JButton the and the I can`t change the width,height,x,y of the JButton.
Swing uses Layout Managers to place the components.
You have to understand how they work to use them effectively. You can set the layout manager to null, and do the layout your self, but is not recommendable because you'll have to keep track of new components each time, and perform layout computation your self when the window moves shrink etc.
Layout managers are a bit hard to grasp at first.
Your windows could be like this:
Using this code:
import javax.swing.*;
import java.awt.Font;
import java.awt.FlowLayout;
class JLabelLocation {
public static void main( String [] args ) {
JLabel mainTitle = new JLabel("SomeApp");
mainTitle.setFont(new Font("Arial",2 , 28));
//mainTitle.setBounds(0,0, 115, 130); //let the layout do the work
JFrame frame = new JFrame();
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));// places at the left
panel.add( mainTitle );
frame.add( panel );// no need to call getContentPane
frame.pack();
frame.setVisible( true );
}
}
Where a particular widget ends up in its container depends on the layout manager that it's using. The layout manager determines how to resize and arrange the widgets to make them fit appropriately. Obviously, the default layout for the content pane decided that the top center was the best place to put the JLabel.
If you want to get to not use a layout manager and just place everything yourself (which generally isn't the best way to lay things out btw), then add:
getContentPane().setLayout(null);
Using layouts is usually a better idea since they allow for dynamic resizing of components. Here's how you'd do it with a BorderLayout:
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add (new JLabel ("Main title"), BorderLayout.NORTH);
If you want to add something to the right of the label you could create an additionnal panel with it's own layout :
// Create a panel at the top for the title and anything else you might need
JPanel titlePanel = new JPanel (new BorderLayout());
titlePanel.add(new JLabel ("Main title"), BorderLayout.WEST);
// Add the title panel to the frame
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add(titlePanel, BorderLayout.CENTER);
Here are some usefull links to get started with layouts:
http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/uiswing/layout/visual.html
http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/uiswing/layout/using.html

Categories

Resources