Below is a Java program which does not work properly. I wanted the JTextfield to go to the bottom, and be 50x50, but it is not working. I was wondering if I could get some help.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
public class Main {
public static JTextField intext = new JTextField();
public static JPanel panel = new JPanel();
public static boolean running = true;
public static String runtext;
public static String word = "HELLO";
public static String guesses = "";
public static void main(String[] args) {
intext.setBounds(5,667,50,50);
panel.add(intext);
JFrame frame = new JFrame("Hangman");
frame.setBounds(10,10,600,750);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setResizable(false);
frame.setVisible(true);
I inferred that when using the .setBounds() method the JTextfield would go where it was needed, though it remains at the top, and extremely thin.
Try editing your code this way:-
panel.setLayout(null); // setting layout for panel
panel.setBounds(0,0,600,650); // setting bounds for panel with respect to frame
intext.setBounds(5,557,50,50); //setting bounds for textfield with respect to panel
panel.add(intext);
JFrame frame= new JFrame("Hangman");
frame.setBounds(10,10,600,750);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setResizable(false);
frame.setLayout(null); // setting layout for frame
frame.setVisible(true);
Make sure to include layouts for your components and set the bounds for your JPanel's and JTextField's properly.
Related
I am quite new to Java GUI, and I have a question about JScrollPane:
Why does my scroll_pane not show up?
package good_Package;
public class Class_Operation
{
public static void main(String[] args)
{
Class_Frame frame = new Class_Frame();
frame.setVisible(true);
}//END MAIN
}//END CLASS
And the frame class is below.
package good_Package;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class Class_Frame extends JFrame
{
JTextArea text_area;
JScrollPane scroll_pane;
public Class_Frame()
{
//Basics
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("This is a title.");
getContentPane().setPreferredSize(new Dimension(500, 500));
pack();
setResizable(false);
setLayout(null);//This is a null Layout
getContentPane().setBackground(Color.GREEN);//frame has a different color from the scroll_pane
//END Basics
text_area = new JTextArea(20, 20);
scroll_pane = new JScrollPane(text_area);
scroll_pane.setBackground(Color.CYAN);//scroll_pane has a different color from the frame
scroll_pane.setVisible(true);
getContentPane().add(scroll_pane);
}//END CONSTRUCTOR
}//END CLASS
Thank you for all suitable answers come from the future.
Can't figure out why this wont work, I get a blank panel added to my gridbag panel.
I added a JLabel("test") between the frames I'm trying to add just to see that something IS getting added, it just isn't visible?
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Label;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
public class Workspace extends JTabbedPane {
static JFrame frame = new JFrame();
private JPanel grid;
private String text = new String("testing.");
Workspace() {
this.addTab("title", growPanel());
}
public static void main(String[] args) throws IOException {
createAndShowGUI();
}
private JPanel growPanel() {
JPanel gp = new JPanel(false);
gp.setPreferredSize(new Dimension(800,600));
//Add a button that adds my frame
JButton addComponentBtn = new JButton("Add Component");
addComponentBtn.addActionListener(e-> {
try {
addComponent();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
});
gp.add(addComponentBtn, BorderLayout.PAGE_START);
grid = new JPanel(new GridLayout(0, 2, 10, 10)); //any number of rows, 2 columns, H and V gap
JScrollPane sp = new JScrollPane(grid);
sp.setPreferredSize(new Dimension(800,600));
gp.add(sp, BorderLayout.CENTER);
this.setVisible(true);
return gp;
}
void addComponent() throws IOException {
System.out.println("adding");
grid.add(new JLabel("test"));
grid.add(new intf());
this.repaint();
frame.pack();
}
private static void createAndShowGUI() throws IOException {
//Create and set up the window.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Add content to the window.
frame.add(new Workspace(), BorderLayout.CENTER);
//Display the window.
frame.pack();
frame.setVisible(true);
}
}
And the intf.java class for the JInternalFrame:
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class intf extends JInternalFrame {
public intf () {
super("Document",
true, //resizable
true, //closable
true, //maximizable
true);//iconifiable
JPanel jp = new JPanel();
JLabel jl = new JLabel("Hi I'm a label");
jp.add(jl);
this.add(jp);
this.pack();
this.repaint();
}
}
Edit:
The JPanel is used to hold the Layout, I don't think I can assign one to the TabbedPane?
Users will load in images which will appear on the left side of the GridLayout (I will upgrade this to a GridBag). After selecting regions on said images, graphs will appear on the right side. This is also why we use a scrollPane so that there is no limit to the number of images loaded. The TabbedPane will be used to split the load if a user loads in too many images (this is all not in the demo code shown here and not relevant to the problem).
The code I posted is for testing why the JInternalFrame doesn't show, so it only shows what is relevant to getting that to work.
Thank you all for your input.
It turned out to be a simple mistake of not having a necessary .setVisible(true)
Under the addComponent() method, the problem is solved when I replace
grid.add(new intf());
with
intf a = new intf();
a.setVisible(true);
grid.add(a);
The search bar is 'search_bar', I'm trying to move it to the left hand side of the box with 'j_panel.add(search_bar, BorderLayout.WEST);' but it doesn't move from the middle. Any ideas on how to do this? Thanks
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SpringLayout;
public class Main {
public static void main(String args[]) {
JFrame jfrm = new JFrame("Test");
jfrm.setSize(1024, 600);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfrm.setResizable(false);
JTextField search_bar = new JTextField("Search...", 25);
search_bar.setPreferredSize(new Dimension(1,35));
JTextArea body = new JTextArea(32,83);
body.setPreferredSize(new Dimension());
body.setEditable(false);
JButton search_button = new JButton("Search");
JPanel j_panel = new JPanel();
j_panel.setLayout(new FlowLayout());
j_panel.add(search_bar, BorderLayout.WEST);
j_panel.add(search_button, null);
j_panel.add(body, BorderLayout.EAST);
j_panel.setBackground(Color.gray);
search_button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
final String text = search_bar.getText();
body.setText(text);
}
});
jfrm.setContentPane(j_panel);
jfrm.setVisible(true);
}
}
j_panel.setLayout(new FlowLayout());
j_panel.add(search_bar, BorderLayout.WEST);
BorderLayout.WEST is not applicable for FlowLayout. If you want to use a BorderLayout, use one instead of FlowLayout.
You cannot position components exactly the way you'd like when using FlowLayout.
By using BorderLayout you are bound to have only 5 components, because BorderLayout can handle 5 components max.
I'm creating a login system and when I made my login button, it took up the entire frame. I tried the .setBounds(); but it did not work. Not sure what I did wrong, please help.
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class Main extends JFrame{
public Main(){
JTextField name = new JTextField("Username");
JTextField pass = new JTextField("Password");
JButton login = new JButton("Login");
name.setBounds(230, 110, 100, 25);
pass.setBounds(230, 145, 100, 25);
login.setBounds(230, 165, 100, 25);
add(name);
add(pass);
add(login);
}
public static void main(String [] args) {
Main a = new Main();
a.setDefaultCloseOperation(EXIT_ON_CLOSE);
a.setSize(500, 300);
a.setLocationRelativeTo(null);
a.setVisible(true);
a.setTitle("Login System");
a.setResizable(false);
a.setLayout(new FlowLayout());
}
}
in your constructor, try setLayout(new FlowLayout());.
This will likely not lead to what you want, but from there on you can investigate further. i recommend you read about layouts here:
https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
By default, Frame has a BorderLayout installed. When the items are added they are all added to "centre" because constraints are not passed. And the centre component occupies all free space in the BorderLayout. You can either change the layout manager or provide constraints while adding components.
FlowLayout or BoxLayout are good candidates for this.
Problem is by default the layout manager for JFrame is BorderLayout. Once you add components with method add() it gets added to the center region. So the last component added is shown. In your case its the login button. Also setBounds() don't work with the said layout manager.
You have to work a lot on your coding style. What you did is first created the frame and added components to it and later in the main() you have set the size, made it visible and then you set the layout manager to FlowLayout.
Ideally, you must construct the frame, set layout, add components to frame, use pack() to set frame size, set frame's location and finally make frame visible.
Using BorderLayout:
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Main implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Main());
}
#Override
public void run() {
JFrame frame = new JFrame("BorderLayout");
frame.getContentPane().add(new JTextField(15), BorderLayout.WEST);
frame.getContentPane().add(new JPasswordField(15), BorderLayout.CENTER);
frame.getContentPane().add(new JButton("Login"), BorderLayout.EAST);
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
}
Using FlowLayout:
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Main implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Main());
}
#Override
public void run() {
JFrame frame = new JFrame("FlowLayout");
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(new JTextField(15));
frame.getContentPane().add(new JPasswordField(15));
frame.getContentPane().add(new JButton("Login"));
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
}
P.S. If you still want to use absolute positions, I would recommend you using SpringLayout or GroupLayout.
I am trying to add a JPanel to a JFrame with FlowLayout, but continue to get this exception: "Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: illegal component position". I would like to be able to implement a JPanel with a few buttons in the near future, so please let me know what I can do to allow that.
package textadv;
import java.awt.FlowLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Label;
import java.awt.event.KeyEvent;
import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TextAdv {
private JFrame frame = new JFrame("Text Adventure");
private JPanel mainPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
private JButton b1 = new JButton("Left");
public TextAdv() {
mainPanel.setBackground(Color.RED);
int FRAME_WIDTH = 400;
int FRAME_HEIGHT = 400;
b1.setEnabled(true);
b1.setVisible(true);
b1.setPreferredSize(new Dimension(40, 40));
mainPanel.setVisible(true);
mainPanel.setPreferredSize(new Dimension (50, 50));
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setVisible(true);
mainPanel.add(b1, FlowLayout.CENTER);
frame.add(mainPanel);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
TextAdv fS = new TextAdv();
}
});
}
You cant specify FlowLayout options to the add method of Container. This resolves to the add() overload which accepts Component, and an int, index. Other layouts let you use the add(Component, Object) overload, like the GridBagLayout and its GridBagConstraints. For the FlowLayout you specify the options to the constructor of the layout only.
Replace this
mainPanel.add(b1, FlowLayout.CENTER);
with this
mainPanel.add(b1);
Consider revisiting the tutorial here: http://docs.oracle.com/javase/tutorial/uiswing/layout/flow.html
See Container here : http://docs.oracle.com/javase/7/docs/api/java/awt/Container.html#add%28java.awt.Component,%20int%29