This question already has an answer here:
Only one component shows up in JFrame
(1 answer)
Closed 7 years ago.
I am trying to read a file with a scanner and create a JButton for each new line in the file. After I create a button, I add it to the frame. However once I run the program, only the most recent button appears. I'm not sure why creating the buttons in a loop causes this to happen. If anyone has an explanation for why this happens, that would be very much appreciated, thanks!
import java.awt.FlowLayout;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
public class PointOfSale extends JFrame {
ArrayList<JButton> menuButtons = new ArrayList<>();
public PointOfSale(File menu) throws IOException{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
Scanner sc = new Scanner(menu);
while (sc.hasNextLine()){
String name = sc.nextLine();
JButton menuButton = new JButton(name);
frame.add(menuButton);
menuButtons.add(menuButton);
}
sc.close();
frame.pack();
frame.setVisible(true);
}
}
Your code does not respect layout managers as the JFrame uses a BorderLayout which will only display one button. Read the layout manager tutorials, use different ones, here perhaps a GridLayout, and you'll likely have your problem solved.
//public class PointOfSale extends JFrame {
public class PointOfSale {
There is no need for your class to extend JFrame since you create the JFrame in the class.
Then you need to use:
frame.setLayout(new FlowLayout());
since this is the frame you add the buttons to.
Related
so i am using intellij and am trying to make a jbutton with text. it works fine without the text but when i put the text on it takes up the whole jframe and i do not know why. if you could help me i would greatly appreciate it. here is my code. Edit thank you Manchi for your answer it worked perfectly and i am no longer looking for answers but i do not know how to close the question.
package com.company;
import javax.swing.*;
import java.awt.*;
class Fantasyrpglifesim implements JButton {
Fantasyrpglifesim() {
}
public static void main(String[] args) {
MouseInputAdapter();
//Frame//
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
frame.setSize(1500000, 1500000);
frame.getContentPane();
frame.setVisible(true);
//Buttons//
frame.add(BUTTON).setBounds(570,500,150,150);
BUTTON.setText("Age up");
}
private static void MouseInputAdapter() {
}
}
You just need to change the layout of the JFrame. Add the next line to your code:
frame.setLayout(new FlowLayout());
I can't seem to find a solution online for why I'm getting this error on attempted run
I'm working on making a simple test system for a different program when are button press will yield value in a text box. I would like them to be on different lines to make it cleaner, so I looked into layouts. I decided a Box Layout would fit me best. I looked at different examples before attempting this and my code ended up looking like this, (apologies for the messy code)
Update
Got the box layout error to disappear but the code will not center them on the panel/frame. The label and button align left while the textfield becomes very large. I don't need it todo that
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import static javax.swing.BoxLayout.Y_AXIS;
import static javax.swing.SwingConstants.CENTER;
public class button extends JFrame {
static JFrame f;
static JButton b;
static JLabel l;
// main class
public static void main(String[] args)
{
// create a new frame to stor text field and button
f = new JFrame("panel");
BoxLayout layout = new BoxLayout(f, BoxLayout.Y_AXIS);
f.setLayout(layout);
// create a label to display text
l = new JLabel("panel label");
b = new JButton("button1");
JTextField textArea = new JTextField(5);
textArea.setEditable(false);
//textArea.append("Hello World");
// create a panel to add buttons
JPanel p = new JPanel();
// add buttons and textfield to panel
f.add(p);
f.setSize(300, 300);
p.add(l);
p.add(b);
p.setBackground(Color.white);
p.add(textArea);
f.show();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Random r = new Random();
textArea.setText(String.valueOf(r));
}
});
}
}
Error
Exception in thread "main" java.awt.AWTError: BoxLayout can't be shared
at java.desktop/javax.swing.BoxLayout.checkContainer(BoxLayout.java:461)
at java.desktop/javax.swing.BoxLayout.invalidateLayout(BoxLayout.java:245)
at java.desktop/javax.swing.BoxLayout.addLayoutComponent(BoxLayout.java:278)
at java.desktop/java.awt.Container.addImpl(Container.java:1152)
at java.desktop/java.awt.Container.add(Container.java:1029)
at java.desktop/javax.swing.JFrame.addImpl(JFrame.java:553)
at java.desktop/java.awt.Container.add(Container.java:436)
at button.main(button.java:36)
I would like the three items to all to be stacked one on top of another with a space between them. The order doesn't matter right now.
Swing was first added to the JDK in 1998 and has undergone a lot of changes since. Unfortunately, when you read Web pages about Swing, it is not obvious when that page was last updated. Consequently you may be learning outdated techniques for writing Swing code.
First of all, according to the code you posted, class button does not need to extend class JFrame since you use a static variable as your application's JFrame. Also, JFrame is a top-level container which makes it a special kind of container and not the same kind of continer as a JPanel. You need to set the layout manager for your JPanel and then add the JLabel, JTextField and JButton to that JPanel. And then add the JPanel to the JFrame.
Calling method pack() of class JFrame will automatically set the preferred sizes for the components inside the JFrame. It appears in the code below.
Please also look at Java coding conventions which allows others to more easily read and understand your code. And note that, according to these conventions, I renamed your class from button to Buttons and also because there are already several class in the JDK named Button.
Here is my rewrite of your code...
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class Buttons implements Runnable {
public void run() {
createAndShowGui();
}
private void createAndShowGui() {
JFrame f = new JFrame("Box");
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel p = new JPanel();
BoxLayout layout = new BoxLayout(p, BoxLayout.Y_AXIS);
p.setLayout(layout);
JLabel l = new JLabel("panel label");
JTextField textField = new JTextField(5);
JButton b = new JButton("button1");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Random r = new Random();
textField.setText(String.valueOf(r.nextBoolean()));
}
});
p.add(l);
p.add(textField);
p.add(b);
f.add(p);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
public static void main(String[] args) {
Buttons instance = new Buttons();
EventQueue.invokeLater(instance);
}
}
I have two files, one is Main.java and the second is frame.java.
I'm creating a desktop application so I want to add scrollpane as needed vertically or horizontally in Main.java file.
Frame.java throws the JPanel object which is being catched by Main.java and dynamically loaded into JFrame.
So anyone please tell me, how can I add the scrollpane or scrollbar. Which is best, I don't know. Thank you..
Main.java:
package pack;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
JPanel pn = null;
JFrame mainFrame = null;
frame login = new frame();
mainFrame = new JFrame("Prem");
mainFrame.setLayout(new BorderLayout());
mainFrame.setDefaultCloseOperation(mainFrame.EXIT_ON_CLOSE);
mainFrame.setSize(500,500);
mainFrame.setLocationRelativeTo(null);
pn=login.getLogin();
mainFrame.add(pn,BorderLayout.CENTER);
mainFrame.setVisible(true);
}
public Main() {
super();
}
}
This is second file which throws the panel object from method frame.java
package pack;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.AbstractAction;
import java.awt.*;
import java.awt.event.*;
public class frame {
JPanel pane = null,pane1=null;
JTextField userText=null,passText=null;
JLabel userLabel =null,passLabel=null,errorLabel=null;
JButton submitLogin = null;
public frame()
{
pane = new JPanel();
pane.setLayout(null);
}
public JPanel getLogin()
{
userLabel = new JLabel("UserName");
pane.add(userLabel);
userLabel.setBounds(5,10,100, 30);
userText = new JTextField();
pane.add(userText);
userText.setBounds(110,10,120,30);
passLabel = new JLabel("PassWord");
pane.add(passLabel);
passLabel.setBounds(5,60,100, 30);
passText = new JTextField();
pane.add(passText);
passText.setBounds(110,60,120,30);
errorLabel = new JLabel("");
pane.add(errorLabel);
errorLabel.setBounds(5,150,180,30);
submitLogin = new JButton("Submit");
pane.add(submitLogin);
submitLogin.setBounds(80,110,90,30);
submitLogin.addActionListener(new AbstractAction(){
public void actionPerformed(ActionEvent e)
{
if(submitLogin.getActionCommand() == "Submit")
{
if(userText.getText().isEmpty() || passText.getText().isEmpty())
{
errorLabel.setText("Enter UserName And Password");
}
else
{
//connection
}
}
else
{
System.exit(0);
}
}
});
return pane;
}
}
You have several issues with that code including:
You don't show us in your code where you're trying to use a JScrollPane or even where it's needed. If you show us your attempt to use this, we'll get a much better understanding of your problem.
You are using a null layout and setBounds(...), something you should avoid at almost all costs, and something which absolutely must be avoided if you want to use a JScrollPane, since JScrollPane's do not work well with null layouts. Instead read up on and use layout managers.
You're comparing Strings using the == operator. You don't want to compare Strings using ==. Use the equals(...) or the equalsIgnoreCase(...) method instead. Understand that == checks if the two objects are the same which is not what you're interested in. The methods on the other hand check if the two Strings have the same characters in the same order, and that's what matters here.
You can find links to the Swing tutorials and other Swing resources here: Swing Info
You can find the layout manager tutorial here: Layout Manager Tutorial.
You can learn about "nesting" layouts here.
You can find specific information on how to use JScrollPanes here: JScrollPane Tutorial.
The basic use of them is that you will want to add your scrollable component to the JScrollPane's viewport, and then add the JScrollPane to the GUI. The specifics of how to do this will all depend on your needs, something we don't yet know, but again is very well explained in the tutorials that I've linked to above.
I am attempting to learn more about creating more dynamic GUI's. I am hoping to add different panels with different content and as you press buttons on one main panel, it changes the adjacent panels. I have added two panels and some buttons and when I test the program, it displays correctly. The problem is when I add a JTextField (or JTextArea) the panels are blank and there are no buttons. The strange thing is I haven't added the JTextField to either panel. I have only created a global variable. If I comment it out, the program runs correctly. Am I missing something very simple?
Here is the gameWindow class that has the JTextField
package rpgcreator;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
class gameWindow extends JPanel {
JPanel startWindowPanel;
JPanel settingsPanel;
JPanel characterPanel;
JPanel scenarioPanel;
JPanel mapPanel;
JButton CharacterButton = new JButton("Create your character");
JButton StoryButton = new JButton("Choose your Story line");
JButton MapButton = new JButton("Choose your World");
//JTextField nameField = new JTextField(15); //comment or uncomment to see issue
public gameWindow() {
setLayout(new GridLayout(0,2,5,0));
startWindowPanel = new JPanel(new FlowLayout());
settingsPanel = new JPanel(new GridLayout(2,1));
startWindowPanel.setBackground(Color.blue);
settingsPanel.setBackground(Color.black);
startWindowPanel.add(MapButton);
startWindowPanel.add(StoryButton);
startWindowPanel.add(CharacterButton);
add(startWindowPanel);
add(settingsPanel);
}
}
Here is main
package rpgcreator;
import javax.swing.JFrame;
public class RPGCreator extends JFrame{
private static void mainWindow(){
RPGCreator mainwindow = new RPGCreator();
mainwindow.setSize(1200, 800);
mainwindow.setResizable(false);
mainwindow.setLocationRelativeTo(null);
mainwindow.setTitle("RPG Creator");
mainwindow.setVisible(true);
mainwindow.add(new gameWindow());
mainwindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
// TODO code application logic here
mainWindow();
}
}
setVisible should go at the end. You're currently setting visible to true, and then adding a panel.
mainwindow.setVisible(true);
mainwindow.add(new gameWindow());
Put setVisible at the end after setDeaultCLoseOperation
I'm not entirely sure why it does it, maybe someone else can explain.
What I do know, is I usually call pack() which seems to make your problem go away.
private static void mainWindow(){
final RPGCreator mainwindow = new RPGCreator();
mainwindow.setMinimumSize(new Dimension(1200, 800));
mainwindow.setResizable(false);
mainwindow.setTitle("RPG Creator");
mainwindow.setVisible(true);
mainwindow.add(new gameWindow());
mainwindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainwindow.pack(); //This usually goes after you've added all of your components
mainwindow.setLocationRelativeTo(null);
}
Some notes:
I had to change to mainwindow.setMinimumSize(new Dimension(1200, 800)); to avoid the frame looking squashed. Although I would usually let the layout manager deal with the sizes of things.
Call setLocationRelativeTo(null) after you call pack() so that it has the desired effect. Again not sure why, but I've learnt that through some hardship.
I have to make a game for school and I've been having some trouble with switching JPanels with a click on the JButton. I want to use a CardLayout, but I'm new to Java which makes it very hard. My goal is to have all my Panels in different classes, like class 'Panel 1', class 'Panel 2' etc. (instead of creating my JPanels in my main (JFrame) class, so my code is easier to read. Is it possible to put your CardLayout container in the class which contains my JFrame? And also, where do I put that darn ActionPerformed? Here is my code, hope you guys can help me!
MAIN (JFrame) CLASS
package invers;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class InversMain extends JFrame implements ActionListener
{
public CardLayout cardlayout;
public Container contentPane = this.getContentPane();
public InversMain()
{
JFrame frame = new JFrame();
frame.setLayout(cardlayout);
frame.setSize(1366,768);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Invers");
frame.setResizable(true);
frame.setVisible(true);
contentPane.setPreferredSize(new Dimension(600, 400));
contentPane.add(new InversMainPaneel(), "Panel 1");
contentPane.add(new InstellingenPaneel(), "Panel 2");
settingsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
cardlayout.show(contentPane, "Panel 1");
}
});}
public static void main ( String [] args)
{
new InversMain();
}
}
Note that the settingsButton is my button from the PANEL 1 class. Because it isn't created in my main class, it gives an error. I want to refer to my settingsButton from PANEL 1 class, from within my main class. Is this possible?
PANEL 1, PANEL CONTAINING MY BUTTONS, THIS IS MY MAIN MENU PAGE
package invers;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JButton;
import javax.swing.JPanel;
public class InversMainPaneel extends JPanel
{
private JButton nieuwSpelKnop = new JButton("Nieuw spel");
private JButton laadSpelKnop = new JButton("Laad Spel");
private JButton settingsButton = new JButton("Settings");
private JButton handleidingKnop = new JButton("Handleiding");
public InversMainPaneel()
{
this.setLayout(null);
nieuwSpelKnop.setSize(300,40);
nieuwSpelKnop.setFont(new Font("Arial", Font.BOLD, 25));
nieuwSpelKnop.setLocation(520,250);
nieuwSpelKnop.setVisible(true);
laadSpelKnop.setSize(300,40);
laadSpelKnop.setFont(new Font("Arial", Font.BOLD, 25));
laadSpelKnop.setLocation(520,350);
laadSpelKnop.setVisible(true);
settingsButton.setSize(300,40);
settingsButton.setFont(new Font("Arial", Font.BOLD, 25));
settingsButton.setLocation(520,450);
settingsButton.setVisible(true);
handleidingKnop.setSize(300,40);
handleidingKnop.setFont(new Font("Arial", Font.BOLD, 25));
handleidingKnop.setLocation(520,550);
handleidingKnop.setVisible(true);
this.add(nieuwSpelKnop);
this.add(laadSpelKnop);
this.add(settingsButton);
this.add(handleidingKnop);
this.setBackground(new Color(178,143,79));
}
}
}
PANEL 2, FOR TESTING IF THE CARDLAYOUT WORKED
package invers;
import java.awt.Color;
import javax.swing.JPanel;
public class InstellingenPaneel extends JPanel
{
public InstellingenPaneel()
{
this.setBackground(new Color(178,143,79));
}
}
Have you tried setting the JFrame contentpane using the setContentPane method?
Because I can see you declaring JFrame and a contentpane object, but not setting it, or setting it with your panels.
Note that the settingsButton is my button from the PANEL 1 class. Because it isn't created in my main class, it gives an error.
I'm guessing that the error you're getting is telling you that cardlayout is referenced in an inner class and thus must be made final. To fix this problem, simply insert the final keyword on your creation of cardlayout.
Second - yes, it is perfectly acceptable (and in line with best practices) to define your panel types in separate classes and then create instances of those classes to place in your JFrame.
Third, it appears that you have "that darned actionPerformed" in the right place (i.e. as a method in your ActionListener inner-class), but you should add the #Override annotation to it. Do you know what I mean by that?
Finally, if you want to refer to the settingsButton from another class, you have several options. I would recommend declaring settingsButton as an instance variable of your JFrame class, and passing a reference to the JFrame to the constructor of the InversMainPanel class:
public InversMainPanel(InversMain im) {
...
im.settingsButton. //do something with the settings button.
having created an InversMainPanel from the InversMain class like this:
InversMainPanel imp = new InversMainPanel(this)
with this referring to the InversMain instance from which the call is being made.
Let me know if I can explain any of this further.
PS: Check out this tutorial on Java naming conventions