I am writing a small program just for personal use to double check strategies on a mobile based game. I created a Board class and frame and whatnot, then I created a new Panel class in my package (I use Eclipse). I figured it would be as simple as creating the two and implementing the Panel and adding it to the main frame of the Board class. Alas, I was mistaken.
TubePanel - my secondary panel
package ballSort;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerListModel;
import javax.swing.JLabel;
public class TubePanel extends JPanel {
/**
* Create the panel.
*/
public TubePanel() {
setBackground(new Color(47, 79, 79));
setBounds(10, 10, 30, 40);
}
}
**This is an excerpt from my main Board class.... **
panel_1 = new JPanel();
panel_1.setBounds(118, 164, 726, 466);
frame.getContentPane().add(panel_1);
JButton btnNewButton_1 = new JButton("X");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.dispose();
}
});
btnNewButton_1.setFont(new Font("Tahoma", Font.PLAIN, 89));
btnNewButton_1.setBounds(10, 122, 85, 124);
frame.getContentPane().add(btnNewButton_1);
}
public void Create(int tubes) {
TubePanel tube = new TubePanel();
panel_1.add(tube);
System.out.println(tube);
System.out.println(panel_1);
}
Am I the idiot here? This should've worked, as far as I'm concerned, but clearly I know not the ways of the Java. [Only been coding java for 4 years.] Anyway the problem is that it doesn't show the tubePanel.
It doesn't give any errors either so I had to use Sysout to see if there was anything wrong with it and panel_1 for a comparison...
ballSort.TubePanel[,10,10,30x40,**invalid**,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
javax.swing.JPanel[,118,164,726x466,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
Aside from the invalid (to which I tried to follow it to its root, I couldn't figure it out) there's nothing different from panel_1 compared to tube.
Any help is much appreciated.
Refer to the lesson entitled Laying Out Components Within a Container from trail Creating a GUI With JFC/Swing which is part of Oracle's Java tutorials.
The default layout of the content pane of a JFrame is BorderLayout. When you add a component to the content pane, it gets added to the center area of the BorderLayout. The center area (and all other areas) of BorderLayout can only contain a single component. So when you add two components to the center area, only one will be displayed. Refer to method add(Component, Object) in class java.awt.Container
So study the layout managers and decide which is suitable.
Related
I want do design a simple login format and in order to do so I want two JTextFields for Username/Password and a Login Button. The Login button is display as expected but when I add the JTextField, nothing shows in my JFrame. Would be nice if someone could help a beginner out...
Here's my code (I know it's ugly but this is just a "code sketch"):
package bucketlistpackage;
import java.awt.Container;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class GameFrame extends JFrame {
public GameFrame(String title) {
super(title); //sets title of frame
startFrame(); //sets details of main frame
final Container logincont = getContentPane(); //creates content pane
JFrame loginframe = new JFrame();
usernameField(loginframe);
loginButton(loginframe);
logincont.add(loginframe);
}
private void usernameField(JFrame loginframe) {
JTextField usernameF = new JTextField("Username", 1);
usernameF.setBounds(50, 50, 50, 20);
loginframe.add(usernameF);
usernameF.setVisible(true);
}
private void startFrame() {
this.setSize(1000, 1000);
this.setVisible(true);
}
private void loginButton(Container cont) {
JButton loginB = new loginButton();
loginB.setSize(300, 150);
loginB.setText("Login");
cont.add(loginB);
}
}
The problem lies on how you are adding component to one another in your case.
You are adding a JFrame to a Container, when in all case it should be the other way around.
The other problem is that you are not using Layouts to manage the components positions on the JFrame.
Another problem as well is that you are not refreshing the windows after adding all the stuff on it.
A bit of a resume on how Java works with native UIs:
Java creates a new thread for the UI. So if you open the debugger you will see AWT threads as well as the main threads and others. This means that you have to manage this in a correct way, because after the application starts SWING and the functions you determine for reactions will lay the ground on how it will behave. Your main thread will die, but the visual threads will keep active.
If you are just starting to program I would encourage you to practice a bit more native java language before moving to SWING or AWT. This libraries can be really painful and tricky to use.
The other thing is SWING library follows a hierarchy for the components:
JFrame > JPanels > Components
In your code you have already worked with all of them but in a disorganized way. JFrame is the main application window, where the graphics will be displayed (can also be a Canvas or whatever class you want to use for that matter). JPanels are organizers, you can use different layouts to organize whatever is inside it. And finally the Components are well... everything! A component can be a JTextField, but it can also be a JPanel, or JButton.
The idea with SWING is to create multiple Panels and organize the end components inside them, using the help of the different layouts to see whats the best approach to make them attractive in many different window sizes.
Finally, if you are using Eclipse, there is a plugin called WindowBuilder which might help you. I don't recommend you using it if you are very new to Java since it will make you depend a lot on it instead of learning how to actually code with SWING.
Hope this helps!!!
Btw, to fix the code above I would do something like this:
public GameFrame(String title) {
super(title); //sets title of frame
startFrame(); //sets details of main frame
final Container logincont = getContentPane(); //creates content pane
logincont.setLayout(new BorderLayout());
usernameField(logincont, BorderLayout.NORTH);
loginButton(logincont, BorderLayout.CENTER);
this.revalidate();
this.repaint();
}
private void usernameField(Container loginframe, String direction) {
JTextField usernameF = new JTextField("Username");
// usernameF.setBounds(50, 50, 50, 20);
loginframe.add(usernameF, direction);
usernameF.setVisible(true);
}
private void startFrame() {
this.setSize(1000, 1000);
this.setVisible(true);
}
private void loginButton(Container cont, String direction) {
JButton loginB = new JButton();
loginB.setSize(300, 150);
loginB.setText("Login");
cont.add(loginB, direction);
}
I'm fairly new to JFrame and I want to know why my items are not showing up on the window. I know i dont have a ActionHandler but I just want my textfield's to show up on my window. Here's my code:
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
public class FirstGUI extends JFrame{
public void GUI(){
setTitle("Welcome");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setSize(600,600);
JLabel title = new JLabel();
title.setText("Apple Inc. Member Login Port");
title.setFont(new Font("Arial", Font.PLAIN, 24));
JTextField login = new JTextField("Login",10);
JPasswordField pass = new JPasswordField("Password");
add(title);
add(login);
add(pass);
}
public static void main(String[] args){
FirstGUI a = new FirstGUI();
a.GUI();
}
}
but when i run it i get this:
but when i run it i get this:
You get an empty screen because you add the components to the frame after the frame is visible.
As has already been suggested you need to use an appropriate layout manager. FlowLayout is the easiest to start with.
invoke setVisible(true) AFTER adding the components to the frame.
So the code should be more like:
panel.add(...);
panel.add(...);
add(panel);
pack();
setVisible(true);
I agree to MadProgrammer's suggestions (+1)
Well, lets take a look at your program though
You actually have created a JFrame with components in it. Its working fine as well, but your question of "why are my items not showing up in the JFrame" is not because you did something wrong but because missed out something i.e. revalidate()
Try:
public static void main(String[] args){
FirstGUI a = new FirstGUI();
a.GUI();
a.revalidate();
}
I'm not saying this will give you perfect UI.. what I'm trying to say is this will help you understand the Swing better. Learn about Swing Layout managers and then work on your UI to have better results
revalidate(): This component and all parents above it are marked as needing to be laid out. This means the Layout Manager will try to realign the components. Often used after removing components. It is possible that some really sharp swing people may miss this. I would think that you will only know this if you are actually using Swing.
The default layout manager for JFrame is BorderLayout.
This means that your components are essentially all been added ontop of each other.
Try changing the layout manager to something like FlowLayout (for example)...
Take a look at A Visual Guide to Layout Managers and Using Layout Managers for more details.
Also, avoid setSize where possible, use Window#pack instead
Update
I'd also like to introduce you to Initial Threads which should be used to launch your UI code...
The only one reason :
setVisible(True); method for the frame should be put on the end of the code.
if you give this line on the top of the code that is when you create a frame. This will cause that problem.
Don't add the components directly to your frame. Instead add to the content pane, which is where a JFrame stores all of the components that it draws. Usually this is a JPanel.
Here is an example:
public class GUI
{
private JPanel content;
public void GUI
{
/*Other code*/
content = new JPanel();
add(content); //make content the content pane
content.add(title);
content.add(login);
content.add(pass);
}
If that fails, call setVisible(true) and setEnabled(true) on all of your components.
On a side note you may want to make your GUI function a constructor.
import javax.swing.*;
import java.awt.*;
class Myframec extends JFrame
{
Myframec()
{
Container c = this.getContentPane();
c.setLayout(null);
this.setBounds(10,10,700,500);
this.setTitle("Welcome");
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setBounds(0,0,700,500);
panel.setBackground(Color.gray);
panel.setLayout(null);
c.add(panel);
Font f = new Font("Arial",Font.BOLD,25);
Font f1 = new Font("Arial",Font.BOLD,20);
JLabel lable = new JLabel();
lable.setBounds(130,10,400,100);
lable.setText("Apple Inc. Member Login Port");
lable.setFont(f);
panel.add(lable);
JTextField login = new JTextField("Login",10);
login.setBounds(120,150,400,30);
login.setFont(f1);
panel.add(login);
JPasswordField pass =new JPasswordField("Password");
pass.setBounds(120,200,400,30);
pass.setFont(f1);
lable.setFont(f);
panel.add(pass);
c.setVisible(true);
this.setVisible(true);
}
public static void main(String[] argm)
{
Myframec frame = new Myframec();
frame.setVisible(true);
}
}
I'm fairly new to JFrame and I want to know why my items are not showing up on the window. I know i dont have a ActionHandler but I just want my textfield's to show up on my window. Here's my code:
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
public class FirstGUI extends JFrame{
public void GUI(){
setTitle("Welcome");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setSize(600,600);
JLabel title = new JLabel();
title.setText("Apple Inc. Member Login Port");
title.setFont(new Font("Arial", Font.PLAIN, 24));
JTextField login = new JTextField("Login",10);
JPasswordField pass = new JPasswordField("Password");
add(title);
add(login);
add(pass);
}
public static void main(String[] args){
FirstGUI a = new FirstGUI();
a.GUI();
}
}
but when i run it i get this:
but when i run it i get this:
You get an empty screen because you add the components to the frame after the frame is visible.
As has already been suggested you need to use an appropriate layout manager. FlowLayout is the easiest to start with.
invoke setVisible(true) AFTER adding the components to the frame.
So the code should be more like:
panel.add(...);
panel.add(...);
add(panel);
pack();
setVisible(true);
I agree to MadProgrammer's suggestions (+1)
Well, lets take a look at your program though
You actually have created a JFrame with components in it. Its working fine as well, but your question of "why are my items not showing up in the JFrame" is not because you did something wrong but because missed out something i.e. revalidate()
Try:
public static void main(String[] args){
FirstGUI a = new FirstGUI();
a.GUI();
a.revalidate();
}
I'm not saying this will give you perfect UI.. what I'm trying to say is this will help you understand the Swing better. Learn about Swing Layout managers and then work on your UI to have better results
revalidate(): This component and all parents above it are marked as needing to be laid out. This means the Layout Manager will try to realign the components. Often used after removing components. It is possible that some really sharp swing people may miss this. I would think that you will only know this if you are actually using Swing.
The default layout manager for JFrame is BorderLayout.
This means that your components are essentially all been added ontop of each other.
Try changing the layout manager to something like FlowLayout (for example)...
Take a look at A Visual Guide to Layout Managers and Using Layout Managers for more details.
Also, avoid setSize where possible, use Window#pack instead
Update
I'd also like to introduce you to Initial Threads which should be used to launch your UI code...
The only one reason :
setVisible(True); method for the frame should be put on the end of the code.
if you give this line on the top of the code that is when you create a frame. This will cause that problem.
Don't add the components directly to your frame. Instead add to the content pane, which is where a JFrame stores all of the components that it draws. Usually this is a JPanel.
Here is an example:
public class GUI
{
private JPanel content;
public void GUI
{
/*Other code*/
content = new JPanel();
add(content); //make content the content pane
content.add(title);
content.add(login);
content.add(pass);
}
If that fails, call setVisible(true) and setEnabled(true) on all of your components.
On a side note you may want to make your GUI function a constructor.
import javax.swing.*;
import java.awt.*;
class Myframec extends JFrame
{
Myframec()
{
Container c = this.getContentPane();
c.setLayout(null);
this.setBounds(10,10,700,500);
this.setTitle("Welcome");
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setBounds(0,0,700,500);
panel.setBackground(Color.gray);
panel.setLayout(null);
c.add(panel);
Font f = new Font("Arial",Font.BOLD,25);
Font f1 = new Font("Arial",Font.BOLD,20);
JLabel lable = new JLabel();
lable.setBounds(130,10,400,100);
lable.setText("Apple Inc. Member Login Port");
lable.setFont(f);
panel.add(lable);
JTextField login = new JTextField("Login",10);
login.setBounds(120,150,400,30);
login.setFont(f1);
panel.add(login);
JPasswordField pass =new JPasswordField("Password");
pass.setBounds(120,200,400,30);
pass.setFont(f1);
lable.setFont(f);
panel.add(pass);
c.setVisible(true);
this.setVisible(true);
}
public static void main(String[] argm)
{
Myframec frame = new Myframec();
frame.setVisible(true);
}
}
so I have this problem. I wrote this code in Java Eclipse SDK 4.2.1. I haven't wrote it all here, actionPerformed method is irrelevant now and it is called from Main once. The problem is sometimes when I run it, one of the components just fills the whole window and overlaps all others. I tried changing sizes by random numbers for example from 400 to 350 and sometimes it worked and then it broke again. I'm probably missing something, I just don't know what. I searched other forums, but found nothing about it.
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collections;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class Window extends JFrame implements ActionListener
{
JTextField field1;
JTextField field2;
public Window()
{
super("Main Window");
setVisible(true);
setSize(500, 500);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Initialize();
}
private void Initialize()
{
field1 = new JTextField();
field2 = new JTextField();
field1.setBounds(0, 0, 400, 100);
field2.setBounds(0,100,400,100);
add(field1);
add(field2);
field1.setBackground(Color.PINK);
field1.setForeground(Color.RED);
field2.setBackground(Color.PINK);
field2.setForeground(Color.RED);
JButton button = new JButton("Create");
button.setBounds(0, 200, 400, 100);
add(button);
button.setBackground(Color.BLACK);
button.setForeground(Color.YELLOW);
button.addActionListener(this);
}
Your problem is that your code does not respect the layout manager being used as you're trying to add components as if the layout being used were null when in fact it isn't. The solution is to read up on and learn about layout managers, and use them; this includes avoiding calling setBounds(...). Note that a JFrame's contentPane uses BorderLayout by default. This information should help you get started. Also note that a wrong solution is to use a null layout. So if anyone suggests this, I urge you to ignore them.
I'm developping a Java application.
I created this interface with MockupScreens.
Please look at these pictures.
At first time, there's only one element, the user have to enter informations (title and description) then he starts adding elements as he needs.
He can edit elemnt infomrations at any time.
He can too delete or change the order of this elements ...
How can I do to create something like the pictures up?????
Thanks in advance.
Best regards,
Ali.
I know these parts in Java Swing.
My problem is how to insert this block of buttons dynamically.
I get an idea, I must put JButtons on a JPanel then manipulate the JPanel by adding, removing and reodering...
So a Grid Layout will be efficient to add each panel after each one, but thinking on reordering the order will be so hard ...
Any suggestions please. :)
After searching, I get an idea:
Let us put these JButtons in a JPanel called btnsUnit, then manipulate it by adding, removing and reodering... So a GridLayout will be efficient to add each JPanel after each one ..
Thats why I created a new JPanel which will contain an unknown number of ListbtnsUnit JPanel, I fixed 10 as the max number.
I'm just doing these steps when you reply me. I didn't arrived to add btnsUnit JPanel in ListbtnsUnit JPanel.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTextField;
public class setupDeviceList extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
setupDeviceList frame = new setupDeviceList();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public setupDeviceList() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 742, 335);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
final JPanel ListbtnsUnit = new JPanel();
ListbtnsUnit.setBackground(Color.RED);
ListbtnsUnit.setBounds(55, 56, 243, 191);
contentPane.add(ListbtnsUnit);
ListbtnsUnit.setLayout(new GridLayout(10, 0));
final JButton btnAdd = new JButton("Add");
btnAdd.setBounds(161, 11, 56, 23);
btnAdd.setVisible(true);
btnAdd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
final JPanel btnsUnit = new JPanel();
btnsUnit.setBounds(343, 71, 243, 147);
contentPane.add(btnsUnit);
btnsUnit.setBackground(Color.ORANGE);
btnsUnit.setLayout(null);
btnsUnit.add(btnAdd);
ListbtnsUnit.add(btnsUnit);
ListbtnsUnit.revalidate();
ListbtnsUnit.repaint();
}
});
}
}
Please can you help me in this code.
I need just the first push to go on.
but thinking on reordering the order will be so hard ...
In your ActionListener for the button:
use getSource() method to get the button that was clicked
use the getParent() method of the button to find the panel the button belongs to
use the getParent() method of the buttons panel to find its parent panel
use the getComponents method to get an Array of all the button panels. Then loop through the Array to find the index of the panel you are search for.
once you find the index you increase of decrease the index, then you can add the panel back to its parent panel at the new index.
then you revalidate() and repaint() the parent panel to display the panel in its new location.
Nice images :-)
You need these parts, if you want to do this in Swing:
javax.swing.JButton (the several buttons)
javax.swing.JTextField (the one line text input component)
javax.swing.JTextArea (the multi-line text input component)
javax.swing.JLabel (labels for your input fields)
javax.swing.JPanel (a container to group several components together, like your lines of buttons, or the editing components at the right)
javax.swing.JFrame (the window for all together)
javax.swing.Action (actions to be performed when a button is clicked - they also can contain an icon and/or text for the button)
Look at these, start to code, and then come back if you have concrete problems. Good luck!
I think you are using a wrong idiom here. What you are trying to accomplish is usually done using JList (scrollable list of items). This way you need just one set of operations such as reorder, add and delete, next to the JList. Operations should operate on selected item in JList (otherwise they should be disabled)
Your interface may look sort of like
The idiom you're currently using is mostly done on web pages. Desktop UIs, (especially Swing) are much richer.
You can find more about how to use JList at http://download.oracle.com/javase/tutorial/uiswing/components/list.html