Aligning JTextFields, JLabels, and JButtons in a JPanel [duplicate] - java

I have the following code where I try to place a JLabel in a custom location on a JFrame.
public class GUI extends JFrame
{
/**
*
* #param args
*/
public static void main(String args[])
{
new GUI();
}
/**
*
*/
public GUI()
{
JLabel addLbl = new JLabel("Add: ");
add(addLbl);
addLbl.setLocation(200, 300);
this.setSize(400, 400);
// pack();
setVisible(true);
}
}
It doesn't seem to be moving to where I want it.

The problem is that the LayoutManager of the panel is setting the location of the label for you.
What you need to do is set the layout to null:
public GUI() {
setLayout(null);
}
This will make it so the frame does not try to layout the components by itself.
Then call setBounds(Rectangle) on the label. Like so:
addLbl.setBounds(new Rectangle(new Point(200, 300), addLbl.getPreferredSize()));
This should place the component where you want it.
However, if you don't have a really great reason to lay out the components by yourself, it's usually a better idea to use LayoutManagers to work in your favor.
Here is a great tutorial on getting started with using LayoutManagers.
If you must go without a LayoutManager here is a good tutorial for going without one.

You put the location code under the frame and it will work but if you want it to work for sure
put the location code in a run while loop. That's what I did to figure it out and it works.

Related

why is importing a font breaking other parts of code?

Modifiers.java:
package game;
import java.awt.*;
import java.io.*;
import javax.swing.*;
public class Modifiers extends Data{
public static void setupJcomponents(){
frame.setUndecorated(true);
frame.setSize(MW,MH);
frame.setResizable(false);
frame.setVisible(true);
frame.setLayout(null);
for(int btn=0; btn<4; btn++) {
Buttons[btn] = new JPanel();
Buttons[btn].setBounds(btn*100,0,100,100);
Buttons[btn].setVisible(true);
Buttons[btn].setBackground(new Color(btn*50,btn*50,btn*50));
frame.getContentPane().add(Buttons[btn]);
}
menuBackground.setBounds(0,0,MW,MH);
menuBackground.setVisible(true);
menuBackground.setBackground(Color.black);
healthIndicator.setText(String.valueOf(healthValue));
healthIndicator.setFont(new Font("Terminal", Font.PLAIN, 100));
healthIndicator.setBounds(600,600,100,100);
healthIndicator.setForeground(Color.blue);
try{
PixelFont = Font.createFont(Font.TRUETYPE_FONT, new File("PixelFont.ttf"));
} catch (IOException e) {
PixelFont = new Font("Terminal", Font.PLAIN, 100);
} catch(FontFormatException e) {
PixelFont = new Font("Terminal", Font.PLAIN, 100);
}
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(PixelFont);
frame.getContentPane().add(healthIndicator);
frame.getContentPane().add(menuBackground);
}
}
Data.java:
package game;
import java.awt.*;
import javax.swing.*;
public class Data {
// this is where I will declare and alter all variable that will be used
public static JFrame frame = new JFrame();
public static JLabel healthIndicator = new JLabel();
public static JPanel Buttons[] = new JPanel[5];
public static JPanel menuBackground = new JPanel();
public static final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
public static final int MW = (int) screenSize.getWidth();
public static final int MH = (int) screenSize.getHeight();
public static Font PixelFont;
public static int maxHealth = 100;
public static int healthValue = maxHealth;
}
Frame.java:
package game;
public class Frame {
public static void main(String[] args) {
Modifiers.setupJcomponents();
}
}
whenever i rum Frame.java the menu Background disappears and the text altogether stops showing up. but if the path to the .ttf file is wrong it just skips over the font and uses the default instead. How do i get this font to load properly as well as not cause my background background to disappear? I have tried changing the path to the .ttf file and turning various parts of the code into comments, but even if the font of the health indicator is a default font, these errors will still occur, however if i try removing the try-catch loop then the errors aren't there anymore.
There are all kinds of problems with the code. Not exactly sure why the Fonts is causing an issue, but it has something to do with the overall structure of your code and you aren't using Swing the way it was designed to be used.
whenever i rum Frame.java the menu Background disappears and the text altogether stops showing up
What appears to be directly related to the above question is that the setVisible(true) statement should be executed AFTER all the components have been added to the frame. This will make sure all the components are painted.
Note this will still only work by chance because you happen to add the "background" panel to the frame last. Swing paints components in the reverse order that are added to any given panel.
Regarding other problems.
your painting code only works by chance. You should not be adding all your components directly to the frame. Swing is not designed to paint components in 3 dimensions directly when the components overlap one another. Swing is designed to have a parent child relationship. So that would mean you add your "background" panel to the frame. Then you add a panel containing the buttons to the "background" and you add the "health" component to the background.
Related to above you should NOT be using a null layout. Swing was designed to be used with a layout manager. This will make sure components don't overlap. So in your case you can use a BorderLayout for the "background" panel. Then you can add the "buttons" panel to the BorderLayout.PAGE_Start and the "health" component to the `BorderLayout.PAGE_END. This will ensure that the components are at the top/bottom of the background panel.
Don't set the size of the frame. Instead you use the setExtendedState(JFrame.MAXIMIZED_BOTH) property. The frame will be the size of the screen. The "GamePanel" will be take up all the space of the frame. So there is no need to set or use hardcoded values.
Don't use static variables and method. This indicates poor design. What you should be doing is creating a GamePanel class, which would essentially be your background panel. This class would contain the instance variables needed for the game. It would create the "buttons" panel and the "health" component and add it to itself.
Variable names should NOT start with upper case characters.

JTextArea is repositioning and reziseing itself

i just started to use Java to build a GUI. Now i ran in an error that causes very strange behaviour with the JTextArea. I used this to create the TextArea:
`
public class gui{
JTextArea ausgabe;
public gui(){
//Some other Stuff in here
//
//
ausgabe = new JTextArea("Test \n Text",15,50);
ausgabe.setSize(110, 170);
ausgabe.setVisible(true);
mainFrame.add(ausgabe);
ausgabe.setLocation(170,20);
ausgabe.setEnabled(false);
}
}
Now until this point everything just works fine. But I want another method to change the text of the area (with ausgabe.setText("String");) the area relocates itself to x,y = 0 of the JFrame and layers itself above all other JFrame elements. Thanks for help!
I highly recommend not trying to fight the Layout Managers
For a simple fix, use the default layout manager for a JFrame like so
public class gui
{
JTextArea ausgabe;
public gui()
{
ausgabe = new JTextArea("Test \n Text");
mainFrame.add(ausgabe, BorderLayout.CENTER);
}
}
You also don't need to set Swing Components other than the JFrame itself visible.
You can then call setText() in an action listener or such and the TextArea should stay in the same position.

Show the hidden JFrame

When I run my JFrame it shows me in hidden size. I have to resize to see JFrame.
Why I cannot get fully sized JFrame.
I used: Pack(); setVisible(true); but it doesn't work.
Here is my code:
public class Mytest extends JFrame{
JLabel label=new JLabel();
JLabel label2=new JLabel();
Timer myTimer;
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
new Mytest().show();
}
public Mytest(){
getContentPane().setLayout(new GridBagLayout());
setTitle("test");
GridBagConstraints gridCon=new GridBagConstraints();
gridCon.gridx=0;
gridCon.gridy=0;
getContentPane().add(label,gridCon);
gridCon.gridx=0;
gridCon.gridy=1;
getContentPane().add(label2,gridCon);
myTimer = new Timer(1000,new ActionListener(){
public void actionPerformed(ActionEvent e){
myTimerActionPerformed(e);
}
});
pack();
myTimer.start();
setLocationRelativeTo(null);
}
private void myTimerActionPerformed(ActionEvent e){
Date today=new Date();
label.setText(DateFormat.getDateInstance(DateFormat.FULL).format(today));
label2.setText(DateFormat.getTimeInstance().format(today));
}
}
There are two basic problems...
The first is, when you create and add your JLabels, they have no content, therefore their preferred size is 0x0...
The second is the use of pack, from the JavaDocs
Causes this Window to be sized to fit the preferred size and layouts
of its subcomponents. The resulting width and height of the window are
automatically enlarged if either of dimensions is less than the
minimum size as specified by the previous call to the setMinimumSize
method. If the window and/or its owner are not displayable
yet, both of them are made displayable before calculating the
preferred size. The Window is validated after its size is being
calculated.
So, basically, you are adding two labels, whose total combined size is 0x0 and pack is doing exactly what it was designed to, packing the frame to meet the requirements of the layout manager.
You need to seed the values of the labels before you call pack, for example, add a method that updates the labels, for example...
public void updateLabels() {
Date today = new Date();
label.setText(DateFormat.getDateInstance(DateFormat.FULL).format(today));
label2.setText(DateFormat.getTimeInstance().format(today));
}
Then in your constructor, before you call pack, call this method...
updateLabels();
pack();
myTimer.start();
setLocationRelativeTo(null);
(You should also call this updateLabels method from the Timers actionPerformed method to keep it consistent).
This will seed the labels with some content, which pack and the layout manager can use to determine size of the window...
You should also use setVisible over show as show is deprecated and may be removed at some time in the future
You can maximize frame like this :
setExtendedState(JFrame.MAXIMIZED_BOTH);
or you can size frame as per your requirement like
setSize(500,500);
and you have to add below statement as i cant see this in your code
setVisible(true);

Displaying an image in a JFrame

I am currently learning Java, and I am stuck with something at the moment.
I was looking for a way to add an image to my JFrame.
I found this on the internet:
ImageIcon image = new ImageIcon("path & name & extension");
JLabel imageLabel = new JLabel(image);
And after implementing it to my own code, it looks like this (this is only the relevant part):
class Game1 extends JFrame
{
public static Display f = new Display();
public Game1()
{
Game1.f.setSize(1000, 750);
Game1.f.setResizable(false);
Game1.f.setVisible(true);
Game1.f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Game1.f.setTitle("Online First Person Shooter");
ImageIcon image = new ImageIcon("C:\\Users\\Meneer\\Pictures\\image.png");
JLabel imageLabel = new JLabel(image);
add(imageLabel);
}
}
class Display extends JFrame
{
}
When running this code, it doesn't give me any errors, but it also doesn't show the picture. I saw some questions and people having the same problem, but their code was completely different from mine, they used other ways to display the image.
You don't need to use another JFrame instance inside the Game JFrame:
Calling setVisible(flag) from the constructor is not preferable. Rather initialize your JFrame from outside and put your setVisible(true) inside event dispatch thread to maintain Swing's GUI rendering rules using SwingUtilities.invokeLater(Runnable)
Do not give size hint by setSize(Dimension) of the JFrame. Rather use proper layout with your component, call pack() after adding all of your relevant component to the JFrame.
Try using JScrollPane with JLabel for a better user experience with image larger than the label's size can be.
All of the above description is made in the following example:
class Game1 extends JFrame
{
public Game1()
{
// setSize(1000, 750); <---- do not do it
// setResizable(false); <----- do not do it either, unless any good reason
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Online First Person Shooter");
ImageIcon image = new ImageIcon("C:\\Users\\Meneer\\Pictures\\image.png");
JLabel label = new JLabel(image);
JScrollPane scrollPane = new JScrollPane(label);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
add(scrollPane, BorderLayout.CENTER);
pack();
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Game1().setVisible(true);
}
});
}
}
do this after creating Jlabel
imageLabel.setBounds(10, 10, 400, 400);
imageLabel.setVisible(true);
also set the layout to JFrame
Game.f.setLayout(new FlowLayout);
You are adding the label to the wrong JFrame. Also, move the setVisible() to the end.
import javax.swing.*;
class Game1 extends JFrame
{
public static Display f = new Display();
public Game1()
{
// ....
Game1.f.add(imageLabel);
Game1.f.setVisible(true);
}
}
Also try to use image from resources, and not from hardcoded path from your PC
You can look in here, where sombody asked similar question about images in Jframe:
How to add an ImageIcon to a JFrame?
Your problem in next you add your JLabel to Game1 but you display another Frame(Display f). Change add(imageLabel); to Game1.f.add(imageLabel);.
Recommendations:
1)according to your problem: Game1 extends JFrame seems that Display is also a frame, use only one frame to display content.
2) use pack() method instead of setSize(1000, 750);
3)call setVisible(true); at the end of construction.
4)use LayoutManager to layout components.

Trying to add a JLabel, but it is stuck in the middle of Jframe

I am trying to add a JLabel but the problem is that it is eith stuck in the middle or to the left of the jframe.
Here is my code;
public class test extends JFrame{
public test(){
JLabel text = new JLabel("test")
text.setLocation(100,100);
setTitle("Help me");
setSize(500,500);
add(text);
}
}
public class Runner{
public static void main (String[] args){
test a = new test();
}
}
Every container has a layout manager that set the position and size of the elements it contains according to its own rules. JFrame default layout is BorderLayout, which put things by default on the left.
To position components absolutely, you have to set the layout manager to null and explicitely call repaint() on your JFrame every time you add/remove/modify your components. You also have to set the size of the components, not only their position (use for example setBounds to set them all in one call.
As an example, The following code does what you want:
public class Test extends JFrame {
public Test() {
// remove any layout manager.
setLayout(null);
setTitle("Help me");
setSize(500, 500);
JLabel text = new JLabel("test");
// set size and position of component.
text.setBounds(new Rectangle(100, 100, 200, 200));
// add component.
add(text);
// explicitely call repaint().
repaint();
}
public static void main(String[] args) {
new Test().setVisible(true);
}
}
For more informations, you can look at the Oracle tutorial on working without a layout manager.
Edit: I would still advise you to use normal layout managers to achieve what you want, as positioning everything absolutely is usually a pain.
add(text);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);

Categories