How set text field location in Java GUI?
I tried this:
public Apletas()
{
inputLine.setLocation(null);
inputLine.setLocation(80, 80);
add(inputLine);
}
But not working.
First, set the layout of your applet to null:
...
public void init()
{
setLayout(null);
}
...
Ignore setLocation()/setBounds() & most especially setLayout(null). Abandon all hope (& the last remnants of sanity), ye' who enter there.
Set locations of components using layout managers.
For sizing of components, it is usually sufficient to provide the appropriate arguments in the constructor (e.g. new JTextArea(rows, columns)), or in some cases, using layout constraints (e.g BorderLayout.CENTER).
For spacing between components, look into both the javax.swing.border package and arguments to the constructor of layout managers, or in some cases, layout constraints (e.g GridBagLayout & GridBagConstraints).
Example:
//<applet code='Apletas' width='600' height='400'></applet>
import java.awt.BorderLayout;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class Apletas extends JApplet {
private JTextField inputLine;
public Apletas()
{
inputLine = new JTextField(20);
JPanel mainGui = new JPanel(new BorderLayout(20,20));
mainGui.setBorder(new EmptyBorder(80,80,80,80));
mainGui.add(inputLine, BorderLayout.NORTH);
mainGui.add(new JScrollPane(new JTextArea(20,10)), BorderLayout.CENTER);
JTree tree = new JTree();
tree.expandRow(2);
mainGui.add(new JScrollPane(tree), BorderLayout.WEST);
setContentPane(mainGui);
validate();
}
}
To compile & run
prompt> javac Apletas.java
prompt> appletviewer Apletas.java
See also
Laying Out Components Within a Container & How to Use Borders in the Java Tutorial.
I'm not sure why you would .setLocation(null) on a text field and then set it again.
Is inputLine declared elsewhere (in which case post the full code here please) or are you missing a line like
TextField inputLine = new TextField("Hello world");
You have to null the default layout as by using the code
setLayout(null);
and then can use the setBounds method to locate your swings
it goes like this
JTextField jt = new JTextField();
jt.setBounds(x,y,width,height);
Related
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);
}
}
I have the following the Java code for the window with two text fields: one editable, the other - not. I would like to gray out the non-editable text field. I use setBackground() function and it seems to work in the Eclipse design viewer:
However, when I export it to jar, the resulting application looks like this:
I am using Eclipse 4.4.1 under MacOS 10.9.3.
My code:
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JTextField;
#SuppressWarnings("serial")
public class TestFrame extends JFrame {
GridBagConstraints constraints;
JTextField text0;
public TestFrame() {
super("Test window");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
Container container = getContentPane();
container.setLayout(new GridBagLayout());
JTextField editableTextField, nonEditableTextField;
constraints = new GridBagConstraints();
editableTextField = new JTextField("Enter text here");
constraints.gridx=0;
constraints.gridy=0;
container.add(editableTextField, constraints);
constraints = new GridBagConstraints();
nonEditableTextField = new JTextField("See result here");
nonEditableTextField.setBackground(getForeground());
nonEditableTextField.setEditable(false);
constraints.gridx=0;
constraints.gridy=1;
container.add(nonEditableTextField, constraints);
pack();
}
public static void main(String args[]) {
new TestFrame();
}
}
Therefore, I have two questions:
Why the behavior is different in the viewer and jar?
How to 'gray out' a text field in jar?
If you set the background color to the foreground color (which is black here), you get everything in the same color.
setBackground(getForeground());
Try setting some other Color.
setBackground(UIManager.getColor("TextField.inactiveBackground"));
For your First Question:
As someone said it above It could have something to do with the look and feel and or the UI Defaults been installed
As for the Second Question:
You can use UIManager.getColor OR
You can use Color class for setting the gray color for your non editable text field. Just use Color.LIGHT_GRAY or Color.GRAY or any other constants that you would want to use.
Both methods will work the same in both the Eclipse IDE and the JAR File.
Modification:
1) nonEditableTextField.setBackground(UIManager.getColor(Color.lightGray));
2) nonEditableTextField.setBackground(UIManager.getColor(Color.LIGHT_GRAY));
OR
nonEditableTextField.setBackground(Color.LIGHT_GRAY);
However, First method is more preferable than the second one.
It turned out that there is actually a difference between getBackground() and getContentPane().getBackground(). However, neither of them is responsible the actually seen grayish default window background. getForeground() also does not code for this color; however, for some reason it is initialized to the coinciding value in the viewer.
Nevertheles, it is possible to override the default background color through getContentPane().setBackground() (though its initial value does not match):
...
Container container = getContentPane();
container.setBackground(new Color(240,240,240));
...
nonEditableTextField.setBackground(container.getBackground());
...
This generates the desirable effect both in the design viewer and jar:
I'm trying to learn Java and want to program a GUI. Trying to start with a simple calculator I ran into a problem while experimenting with JTextField. Compiling the following code sometimes results in an empty frame and sometimes in one with the panel and buttons in it.
This happens no matter if I use javac or eclipse.
I use the following code:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Mainframe extends JFrame {
private JButton button1;
private JPanel mainpanel;
private JLabel headline;
private Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
JTextField number1;
JTextField number2;
public Mainframe(String s) {
super(s);
setSize(screenSize.width, screenSize.height);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainpanel = new JPanel(new BorderLayout(100, 100));
number1 = new JTextField(20);
number2 = new JTextField(20);
headline = new JLabel("Simple Calculator");
button1 = new JButton("1");
mainpanel.add(headline, BorderLayout.NORTH);
mainpanel.add(number1, BorderLayout.SOUTH);
mainpanel.add(button1, BorderLayout.EAST);
mainpanel.add(number2, BorderLayout.CENTER);
mainpanel.validate();
getContentPane().add(mainpanel);
}
public static void main(String[] args) {
Mainframe mainframe1 = new Mainframe("Title");
}
}
I want to repeat: This is not about differences between javac and eclipse but about a problem/occurence I have with both compilers - sometimes the result is as wanted, sometimes not. Why does that happen?
Thanks in advance!
Make sure that the call to JFrame.setVisible(true) is the last line you invoke.
So just move the line:
setVisible(true);
to the end of your constructor.
A few more remarks:
Don't extend if not needed (here it is not needed)
Make sure that all the UI-related operations are done on the EDT (use a SwingUtilities.invokeLater() block to start your UI)
Don't call setSize(screenSize.width, screenSize.height); but frame.setExtendedState(Frame.MAXIMIZED_BOTH); to make a window take the whole screen space. Consider also calling pack() before making the frame visible (but before calling frame.setExtendedState(Frame.MAXIMIZED_BOTH);) so that all components are properly laid out and this will also set the size of the frame to its computed preferred size.
Move your setVisible( true ) to a moment where you have added all your components.
If you do not do this, you need to re-validate the layout as indicated in the javadoc of the Container#add method:
This method changes layout-related information, and therefore, invalidates the component hierarchy. If the container has already been displayed, the hierarchy must be validated thereafter in order to display the added component.
Most layout managers have no-argument constructors (that is, you can create a FlowLayout with new FlowLayout (), a GridLayout with new GridLayout (), a GridBagLayout with new GridBagLayout (), etc.). However, BoxLayout requires that you pass both the container that it will be managing and the axis along which the components should be laid out.
My question is: since you're already telling the layout manager which component to lay out, why do you need to write
BoxLayout bl = new BoxLayout(myPanel, BoxLayout.Y_AXIS);
myPanel.setLayout(bl);
instead of just the first line?
I took a quick look at the BoxLayout source code and saw that the constructor I use (lines 178-185) doesn't make a call to target.setLayout(this) or anything of the sort. It seems like it would be really simple to just add that. Is there a reason why it's not included in the Swing library?
If it matters, I'm using
java version 1.7.0
Java(TM) SE Runtime Environment (build 1.7.0-b147)
on Win7Pro.
Thanks!
SSCCE:
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
public class BoxLayoutSSCCE extends JFrame {
// Change this to see what I mean
public static final boolean CALL_SET_LAYOUT = true;
public BoxLayoutSSCCE () {
super("Box Layout SSCCE");
JPanel panel = new JPanel();
BoxLayout bl = new BoxLayout(panel, BoxLayout.Y_AXIS);
if (CALL_SET_LAYOUT) {
panel.setLayout(bl);
}
panel.add(new JButton("Button 1"));
panel.add(new JButton("Button 2"));
}
public static void main (String[] args) {
BoxLayoutSSCCE blsscce = new BoxLayoutSSCCE();
blsscce.pack();
blsscce.setVisible(true);
}
}
The Container must exist before it can be passed to BoxLayout. Typically one writes something like this:
JPanel myPanel = new JPanel();
BoxLayout bl = new BoxLayout(myPanel, BoxLayout.Y_AXIS);
myPanel.setLayout(bl);
It's tempting to combine the last two lines, but the principle of least astonishment suggests that the layout's constructor should not otherwise alter the container's state.
Convenienly, javax.swing.Box provides "A lightweight container that uses a BoxLayout object as its layout manager."
public class Box extends JComponent implements ... {
public Box(int axis) {
super();
super.setLayout(new BoxLayout(this, axis));
}
}
Now a single line will do:
Box myBox = new Box(BoxLayout.Y_AXIS);
BoxLayout makes sure that the layout methods are applied to the correct container. It enforces that the same container that was specified in the constructor is used in various methods, such as layoutContainer(Container target), preferredLayoutSize(Container target), etc. It boils down to the checkContainer() method that does the verification:
void checkContainer(Container target) {
if (this.target != target) {
throw new AWTError("BoxLayout can't be shared");
}
}
BoxLayout implementation probably caches some details about the container and tries to maintain state, so it cannot be shared.
EDIT:
BoxLayout implements LayoutManager2.invalidateLayout() where it does reset its cached details. Other layout implementations follow the same pattern. For example, GroupLayout and OverlayLayout also require container argument in their constructors.