I am creating a program in java, similar to Quizlet.
I created a class for each Jpanel which has the layout set to null. The only class that doesn't have the null layout is the one that manages and contains all the JPanels, which has the CardLayout.
Anyways, everything was working fine, the problem occurred in one of my classes that contains a Jpanel that loads each quiz. I called it LoadMenu.
The GUI was working just fine, and I just wanted to check out the box layout, so I switched it from null layout to box. Then I realized all of my components, except for one, disappeared on that layout. Now when I changed the layout back to null, everything is still gone, and the JPanel all together completely disappeared. I hit Control-Z and undo any changes, but it's still gone.
Is there anyway I can restore it to what it looked like before?
Thank you
Not sure if this helps but this is the loadMenu class
public class LoadMenu extends JPanel implements ActionListener {
private QuizManager manager;
private FileManager file = new FileManager();
private JComboBox comboBox;
private JButton nextButton;
private JButton refreshButton;
private JButton backButton;
private ProblemSet problemSetList;
LoadMenu(ProblemSet newProblemSetList, QuizManager newManager){
manager = newManager;
problemSetList = newProblemSetList;
JPanel loadMenu = new JPanel();
loadMenu.setLayout(null);
loadMenu.setBounds(1, 0, 681, 426);
add(loadMenu);
loadMenu.setLayout(null);
loadMenu.setBounds(1, 0, 681, 426);
JLabel selectQuizLabel = new JLabel("Select Quiz");
selectQuizLabel.setFont(new Font("Times New Roman", Font.BOLD, 20));
selectQuizLabel.setBounds(261, 104, 110, 31);
loadMenu.add(selectQuizLabel);
comboBox = new JComboBox();
comboBox.setBounds(274, 194, 153, 22);
loadMenu.add(comboBox);
nextButton = new JButton("Next");
nextButton.setBounds(530, 370, 139, 43);import junit.framework.TestCase;
import junit.framework.TestCase;
loadMenu.add(nextButton);
nextButton.addActionListener(this);
listQuizNames();
refreshButton = new JButton("Refresh");
refreshButton.addActionListener(this);
refreshButton.setBounds(241, 229, 139, 31);
loadMenu.add(refreshButton);
backButton = new JButton("Back");
backButton.addActionListener(this);
backButton.setBounds(12, 370, 139, 43);
loadMenu.add(backButton);
}
public void actionPerformed(ActionEvent e) {
Object src = e.getSource();
if(src == nextButton){
manager.startQuiz((String)comboBox.getSelectedItem());
}
else if(src == refreshButton){
listQuizNames();
}
else{
manager.showNextCard("startMenu");
}
}
public void listQuizNames(){
ArrayList<String> quizList = new ArrayList<String>();
file.readQuizNames(quizList);
comboBox.setModel(new DefaultComboBoxModel(quizList.toArray()));
}
}
Try adding the panel to a JFrame, it might help
JFrame frame = new JFrame();
frame.add(loadmenu);
In the main function or the constructor - suit yourself
setVisible(true);
Hope it works!!
Related
I don't know a whole lot about programming so excuse my messy code, but I'm working on a little choice-based game and my action listeners are throwing a nasty NullPointerException. Let me know what the issue might be.
the error is
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
with a continued list of (Unknown Source) based lines
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class finalproj extends JFrame implements ActionListener
{
private static final int WIDTH = 800, HEIGHT = 800;
private static final Font STANDARD_FONT = new Font("Arial", Font.BOLD, 32);
private JButton startgame, next, endgame;
private JLabel startmenu, question;
private int chanceofdeath = 0;
private JRadioButton q1A, q1B, q1C, q2A, q2B, q2C, q3A, q3B, q3C, q4A, q4B, q4C,
q5A, q5B, q5C, q6A, q6B, q6C, q7A, q7B, q8C, q9A, q9B, q9C, q10A, q10B, q10C, q11A,
q11B, q11C, q12A, q12B, q12C, q13A, q13B, q13C, q14A, q14B, q14C, q15A, q15B, q15C;
public static void main(String[] args)
{
new finalproj();
}
public finalproj()
{
setLayout(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(WIDTH, HEIGHT);
setTitle("The Wild, Wild West");
getContentPane().setBackground(Color.BLACK);
setLocationRelativeTo(null);
setResizable(false);
JLabel startmenu = new JLabel("");
startmenu.setSize(800, 100);
startmenu.setLocation(35, 100);
startmenu.setFont(STANDARD_FONT);
startmenu.setText("Howdy Pardner! Ready to enter the Wild West?!");
startmenu.setOpaque(true);
startmenu.setBackground(Color.BLACK);
startmenu.setForeground(Color.WHITE);
startmenu.setVisible(true);
JButton startgame = new JButton("press me");
startgame.setFont(new Font("Arial", Font.BOLD, 28));
startgame.setForeground(Color.BLACK);
startgame.setSize(600, 100);
startgame.setLocation(100, 300);
startgame.setVisible(true);
JButton next = new JButton("Continue");
next.setFont(new Font("Arial", Font.BOLD, 28));
next.setForeground(Color.BLACK);
next.setSize(600, 100);
next.setLocation(100, 300);
next.setFocusable(false);
next.setVisible(false);
JLabel question = new JLabel();
question.setFont(new Font("Arial", Font.BOLD, 28));
question.setForeground(Color.BLACK);
question.setSize(600, 100);
question.setLocation(100, 300);
question.setFocusable(false);
question.setVisible(false);
question.setText("AAAAA");
startgame.addActionListener(this);
add(startmenu);
add(startgame);
add(question);
add(next);
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals("press me"))
{
startmenu.setVisible(false);
}
You are using local variable with the name 'startmenu', while the field 'startmenu' is never assigned.
You should initialize it like this
startmenu = new JLabel("");
instead of
JLabel startmenu = new JLabel("");
The same thing should be done with other fields.
Let me advice you to use IDE highlighting, it will show you what field or variable you are looking at.
First of you declare a variable name with
private JLabel startmenu, question;
in your constructor, you are creating an object using
JLabel startmenu = new JLabel("");
this object scoope only in constructor, not outside the constructor.
so you need to insitalize value of startmenu using above statement.
this.startmenu = new JLabel("");
what to do. replace
JLabel startmenu = new JLabel("");
to
this.startmenu = new JLabel("");
i read some contributions about this but nothing helped.
I try to make a little application with a gui,
but the problem is, if i click the button, no animation appears and nothing happens. I hope you can help me.
That's the code:
public class StartFrame extends JFrame{
JTextField eingabe;
JLabel inhalt;
JButton button;
JCheckBox fett;
JCheckBox kursiv;
JCheckBox groß;
JPanel panel;
StartFrame(int sizeWidth, int sizeHeight, String title){
setSize(sizeWidth, sizeHeight);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle(title);
setLocationRelativeTo(null);
setLayout(null);
inhalt = new JLabel("TeXt");
inhalt.setBounds(0, 0, 500, 60);
Font font = inhalt.getFont().deriveFont(Font.ITALIC, 15);
inhalt.setFont(font);
inhalt.setToolTipText("Das ist ein Text");
add(inhalt);
button = new JButton("HIER");
button.setBounds(100, 10, 100, 50);
button.addActionListener(new ClickListener());
button.setEnabled(false);
add(button);
eingabe = new JTextField();
eingabe.setBounds(300, 50, 150, 25);
eingabe.addCaretListener(new SchreibkopfListener());
add(eingabe);
panel = new JPanel();
panel.setLayout(null);
panel.setBounds(10, 200, 150, 100);
add(panel);
fett = new JCheckBox("Fett");
fett.setBounds(0, 0, 150, 25);
fett.addItemListener(new FettListener());
panel.add(fett);
kursiv = new JCheckBox("Kursiv");
kursiv.setBounds(0, 25, 150, 25);
panel.add(kursiv);
groß = new JCheckBox("Groß");
groß.setBounds(0, 50, 150, 25);
panel.add(groß);
setVisible(true);
}
private class ClickListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent arg0) {
inhalt.setText(eingabe.getText());
}
}
private class SchreibkopfListener implements CaretListener{
#Override
public void caretUpdate(CaretEvent arg0) {
String inTextField = eingabe.getText();
inTextField = inTextField.trim();
if(inTextField.isEmpty()){
button.setEnabled(false);
}else{
button.setEnabled(true);
}
}
}
private class FettListener implements ItemListener{
#Override
public void itemStateChanged(ItemEvent arg0) {
if(fett.isSelected()){
Font font = inhalt.getFont().deriveFont(Font.BOLD, 15);
inhalt.setFont(font);
}else{
Font font = inhalt.getFont().deriveFont(Font.ITALIC, 15);
inhalt.setFont(font);
}
}
}
}
Here's a wonderful lesson into why null layouts suck (and you should stop using them)
Let's just take a little look at these lines...
nhalt = new JLabel("TeXt");
inhalt.setBounds(0, 0, 500, 60);
inhalt.setToolTipText("Das ist ein Text");
//...
button = new JButton("HIER");
button.setBounds(100, 10, 100, 50);
So, the label starts at 0x0 and expands through 500x60, okay, the button starts at 100x10 and expands through 100x50, this means that the label and the button actually collide
Now, I know what you're thinking, but I add the button after the label, but this isn't how components actually get painted/respond to events.
Components are painted in reverse order of how they are added, this means that the label actually resides OVER the button (in terms of the Z-order), this also means that the label receives events BEFORE the button, this is important because...
inhalt.setToolTipText("Das ist ein Text");
installs a MouseListener on the JLabel, which consumes ALL mouse events, preventing the button from been notified.
So, long answer short, don't use null layouts (and take the time to better understand how the API actually works :P)
I'm writing a large Java desktop program in swing and I'm using one JFrame and around 30 JPpanels in CardLayout
There are several panels that share the same side menu panel.
In the prototype of the program, I wrote this menuPanel inside each of these JPanels. However, I realized that the code was very redundant, so trying to optimize it, I created this MenuPanel class as a JPanel and I added it to all of those other JPanels. And then I added these JPanels to the CardLayout.
When I run the program, the side panel doesn't show because in Eclipse Design Parser it says MenuPanel is added to more than one parent component.
First of all, do you think this is a good design i.e. to use CardLayout? Or do you think I should use one JFrame and one JPanel where I keep updating the JPanel (removing Components and then adding others) each time it's needed?
Second of all, is there a workaround to solve the issue that I presented above?
The code for the MenuPanel is here:
import java.awt.Font;
import javax.swing.*;
public class MenuPanel extends JPanel {
private static final long serialVersionUID = 1L;
public static JLabel lblPicture = new JLabel("New label");
public static JLabel lblName = new JLabel("Fname Lname");
public static JButton btnCourses = new JButton("Courses");
public static JButton btnChat = new JButton("Chat");
public static JButton btnSchedule = new JButton("Schedule");
public static JButton btnProfile = new JButton("Profile");
public static JButton btnAdvancedTools = new JButton("Advanced Tools");
public static JButton btnSignOut = new JButton("Sign Out");
public static JLabel lblWelcomeBack = new JLabel("Welcome Back");
public MenuPanel() {
initializeComponents();
}
private void initializeComponents() {
this.setLayout(null);
this.setVisible(true);
this.setBounds(0, 0, 129, 562);
lblPicture
.setIcon(new ImageIcon(getClass().getResource("Profile.png")));
lblPicture.setBounds(0, 11, 124, 128);
this.add(lblPicture);
lblName.setHorizontalAlignment(SwingConstants.CENTER);
lblName.setFont(new Font("Tahoma", Font.BOLD, 12));
lblName.setBounds(10, 150, 115, 20);
this.add(lblName);
btnCourses.setBounds(10, 195, 110, 25);
this.add(btnCourses);
btnChat.setBounds(10, 240, 110, 25);
this.add(btnChat);
btnSchedule.setBounds(10, 285, 110, 25);
this.add(btnSchedule);
btnProfile.setBounds(10, 325, 110, 25);
this.add(btnProfile);
btnAdvancedTools.setBounds(10, 370, 110, 25);
this.add(btnAdvancedTools);
btnSignOut.setBounds(10, 515, 110, 25);
this.add(btnSignOut);
}
}
And here is the code for one of the many panels that use this MenuPanel:
import java.awt.*;
import javax.swing.*;
public class MainPagePanel extends JPanel {
private static final long serialVersionUID = 1L;
protected static JPanel AppPanel = new JPanel();
protected static MenuPanel menuPanel = new MenuPanel();
protected static JLabel lblWelcomeBack = new JLabel("Welcome Back");
public MainPagePanel() {
initializeComponents();
}
private void initializeComponents() {
this.setLayout(null);
AppPanel.setLayout(null);
AppPanel.add(menuPanel, 0, 0);
AppPanel.setBackground(new Color(173, 216, 230));
AppPanel.setBounds(129, 0, 471, 562);
lblWelcomeBack.setHorizontalAlignment(SwingConstants.CENTER);
lblWelcomeBack.setFont(new Font("Tahoma", Font.BOLD, 55));
lblWelcomeBack.setBounds(10, 215, 435, 140);
AppPanel.add(lblWelcomeBack);
this.add(AppPanel);
}
}
I'm not going to include the class that has the CardLayout in it because it's large. Anyway, any help is appreciated.
Glancing over the code, I noticed you set layouts to null. This would definitely cause some issues to occur. A Visual Guide to Layout Managers is very useful in trying to set up a Swing interface. Try fixing the null layouts and then see if that resolves the issue. I would also recommend the GroupLayout or GridBagLayout for a complex layout. They might be difficult to learn how to use at first, but will definitely help you resolve your issues without forcing layouts to be null or sizing components haphazardly with setMin/Pref/Max.
In my case It happen because i created new JLabel inside method
and then called the method few times and added the component to the panel.
so WindowBuilder plugin thought i added the same component few times, which is incorrect.
As solution I finally created the JLabel outside the method, and method was only modify it.
I broke my code, but I cannot figure out how. At all.
At one point, compiling and running the code rendered a window every single time. Then I worked for about 15 minutes, and the frames no longer appear upon running. I've tried undoing the work, adding run methods, adding a main method, and even copying and pasting code directly from my textbook. Nothing has worked.
I tried to paste as little code as possible. Forgive me if my code is sloppy; this is my first time working with swing. Thanks!
public class LibraryFrame extends JFrame implements ActionListener
{
private JScrollPane studentScroller = new JScrollPane();
private JPanel addStudent = new JPanel();
private JTextField UID = new JTextField();
private JTextField name = new JTextField();
private JTextField email = new JTextField();
private JButton okButton = new JButton("OK");
private JButton closeButton = new JButton("Close");
private JPanel buttonPane = new JPanel();
public LibraryFrame()
{
setTitle("Student Enrollment");
setSize(500,200);
setLocationByPlatform(true);
addStudent.setLayout(new GridLayout(0, 2, 0, 0));
addStudent.add(new JLabel("Enter Student UID:"));
addStudent.add(UID);
addStudent.add(new JLabel("Enter Student Name:"));
addStudent.add(name);
addStudent.add(new JLabel("Enter Student Email:"));
addStudent.add(email);
addStudent.add(Box.createRigidArea(new Dimension(0, 5)));
addStudent.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
okButton.setActionCommand(null);
closeButton.addActionListener(new ActionListener() //implement window close only
{
#Override
public void actionPerformed(ActionEvent e)
{ dispose(); }
});
buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS));
buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
buttonPane.add(Box.createRigidArea(new Dimension(0, 0)));
buttonPane.add(okButton);
buttonPane.add(Box.createRigidArea(new Dimension(10, 0)));
buttonPane.add(closeButton);
Container studentPane = getContentPane();
studentPane.add(addStudent, BorderLayout.CENTER);
studentPane.add(buttonPane, BorderLayout.PAGE_END);
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
}
You show no main method, so we don't know how you try to run this.
You add all to studentPane. Where do you add studentPane to the JFrame, to the this object? If it's not added to the GUI, it will not show.
I've got a simple Swing GUI and I want to add a new line of text to a JTextArea after a button is pressed, simple right?
The Button and it's ActionListener function correctly (printing stuff to the console works fine), but when I use .append()or .setText() to add text to the textarea, I get a nullpointer exception.
As always, code it below. Any input would be greatly appreciated, thanks!!!
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.LineBorder;
public class GUI extends JFrame implements ActionListener {
private JFrame frame;
private JLabel paneHeader;
public JTextArea ipArea, portArea, outputLog, orderLog, cookLog;
private JButton newServer;
public String ipAddress, portNumber, cashierName, cookName;
public GUI() {
initGUI();
}
public void initGUI() {
frame = new JFrame("Restaurant Overview");
Container contentPane = frame.getContentPane();
JLabel paneHeader = new JLabel("Restaurant Monitoring System");
paneHeader.setBounds(200, 0, 200, 25);
paneHeader.setFont(new Font("Calibri", Font.BOLD, 14));
JLabel ipLabel = new JLabel("IP Address: ");
ipLabel.setBounds(25, 30, 75, 20);
ipLabel.setFont(new Font("Calibri", Font.PLAIN, 12));
final JTextArea ipArea = new JTextArea();
ipArea.setBorder(new LineBorder(Color.GRAY));
ipArea.setBounds(105, 30, 100, 20);
JLabel portLabel = new JLabel("Port Number: ");
portLabel.setBounds(25, 55, 75, 20);
portLabel.setFont(new Font("Calibri", Font.PLAIN, 12));
final JTextArea portArea = new JTextArea();
portArea.setBorder(new LineBorder(Color.GRAY));
portArea.setBounds(105, 55, 100, 20);
JButton newServer = new JButton("Create new Server");
newServer.setBorder(new LineBorder(Color.GRAY));
newServer.setBounds(250, 30, 150, 40);
newServer.setActionCommand("createserver");
newServer.addActionListener(this);
JTextArea outputLog = new JTextArea(" ");
outputLog.setBorder(new LineBorder(Color.GRAY));
outputLog.setBounds(25, 90, 150, 150);
//outputLog.setEditable(false);
JTextArea cashierLog = new JTextArea();
cashierLog.setBorder(new LineBorder(Color.GRAY));
cashierLog.setBounds(185, 90, 150, 150);
//cashierLog.setEditable(false);
JTextArea cookLog = new JTextArea();
cookLog.setBorder(new LineBorder(Color.GRAY));
cookLog.setBounds(345, 90, 150, 150);
//cookLog.setEditable(false);
contentPane.add(paneHeader);
contentPane.add(ipLabel);
contentPane.add(ipArea);
contentPane.add(portLabel);
contentPane.add(portArea);
contentPane.add(outputLog);
contentPane.add(cashierLog);
contentPane.add(cookLog);
contentPane.add(newServer);
frame.setLayout(null);
frame.pack();
frame.setSize(600,400);
frame.setVisible(true);
}
public void test() {
//ipAddress = ipArea.getText() + "\n";
//portNumber = portArea.getText() + "\n";
String text = "lemons";
//System.out.println(text);
outputLog.append(text);
//outputLog.append(portNumber);
}
public void actionPerformed(ActionEvent e) {
if ("createserver".equals(e.getActionCommand())) {
//test();
outputLog.append("lemons");
} else {
//Do Nothing
}
}
}
You are likely shadowing a variable -- declaring it more than once, but initializing a local variable not the class field, and so the class field remains null.
Edit:
Yep, sure enough you do. In your constructor you have
JTextArea outputLog = new JTextArea(" ");
This re-declares the outputLog variable, and so you are initializing only the variable local to the constructor. The solution is not to redeclare the variable but instead initialize the class field. So change the above to
outputLog = new JTextArea(" ");
You will need to do this for every variable that needs to be accessed in the class scope. For those that are OK to declare locally, do so, but in the sake of safety, get rid of their corresponding class declaration so as not to risk causing the same error in the future.
Your error is that the instance variable outputLog is not initialized.
your code not done on EDT, you have to wrap tht into invokeLater()
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
outputLog.setText(outputLog.getText()
+ System.getProperty("line.separator") + text);
}
});