I'm getting an AWT-EventQueue-0 Null Pointer Exception in the below code and I can't get to fix it.
I want to have a main frame, from which by pressing a button
I open a second frame, where I have the option to create new players,
which would show up in the main frame.
I passed the references to the constructors, but I still keep getting the error.
I would be very happy for some help, thanks!
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new App();
}
});
}
}
public class App extends JFrame {
private MainPanel mainPanel;
private SecondPanel secondPanel;
public App() {
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 600);
secondPanel = new SecondPanel(mainPanel);
mainPanel = new MainPanel(secondPanel);
add(mainPanel);
}
}
public class MainPanel extends JPanel {
private JTextArea textArea;
private JScrollPane scrollPane;
private JButton options;
public MainPanel(SecondPanel secondPanel) {
textArea = new JTextArea();
textArea.setColumns(20);
textArea.setRows(5);
textArea.setSize(300, 300);
textArea.setVisible(true);
textArea.setEditable(false);
scrollPane = new JScrollPane(textArea);
scrollPane.setSize(new Dimension(400, 400));
options = new JButton("Options");
options.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
secondPanel.setVisible(true);
}
});
add(scrollPane);
add(options);
}
public JTextArea getTextArea() {
return textArea;
}
public void setTextArea(JTextArea textArea) {
this.textArea = textArea;
}
}
public class SecondPanel extends JFrame {
private JButton create, remove;
private JPanel panel;
public SecondPanel(MainPanel mainPanel) {
setVisible(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 400);
panel = new JPanel();
panel.setLayout(new BorderLayout());
create = new JButton("create");
create.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
mainPanel.getTextArea().append("New Player Created");
}
});
remove = new JButton("remove");
remove.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
mp.getTextArea().setText("Player removed");
}
});
add(panel);
panel.add(create, BorderLayout.EAST);
panel.add(remove, BorderLayout.WEST);
}
}
Well, it has to be "null", because you don't initialise your MainPanel before you hand it over to the secondPanel.
Instead, make an own method for setting the MainPanel on the secondPanel and to set the secondPanel on the MainPanel.
I see that you need the secondPanel for instance in your constructor to set an ActionListener. Do that in your "setSecondPanel(SecondPanel sPanel)"-Method which, as I mentioned before, you should create.
Related
i want to add panel from "newWork" class on pressing of "drop" button in "menuPan" class.
i cant add panel.
simply how to add Panel from different class on pressing button.
here are the three different classes .
MainClass :-
public class userFrame extends JFrame{
public void Frame()
{
setTitle("TEST CASE");
setSize(900,670);
add(new MenuPan(),BorderLayout.NORTH);
add(new WorkPan(),BorderLayout.CENTER);
setLocationRelativeTo(this);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String [] args){
userFrame u =new userFrame();
u.Frame();
}
}
MenuPan
public class MenuPan extends JPanel implements ActionListener{
WorkPan work=new WorkPan();
JButton view;
public menuPan() {
setBackground(Color.white);
setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
setLayout(new FlowLayout(1, 15, 10));
view=new JButton(" Registered Courses ");
view.addActionListener(this);
add(view);
}
#Override
public void actionPerformed(ActionEvent e) {
work.TaskPannel();
}
}
WorkPAN class :-
class WorkPan extends JPanel{
JPanel work=new JPanel();
public WorkPan() {
setBackground(Color.LIGHT_GRAY);
setLayout(new BorderLayout(40, 50));
}
void TaskPannel() {
System.out.println("here");
add(new NewWork(),BorderLayout.CENTER);// adds NewWork panel
}
}
NewWork Class
class NewWork extends JPanel{
public NewWork(){
setBackground(Color.red);
}
}
One issue -- you create one workPan (which should be renamed WorkPan), change its state in your ActionListener, but never add it to your GUI. So you appear to be changing the state of a non-displayed GUI component, and so it would make sense that nothing will show in the GUI.
Suggestions:
Be sure to create only one WorkPan reference,
Be sure to display this single reference in the GUI
Be sure that your ActionListener calls the appropriate method on the same reference.
Side recommendation:
Learn and follow Java naming conventions so you others can more easily understand and follow your code.
To swap JPanels within a GUI, I strongly advise you to use a CardLayout rather than adding and removing components manually as you're currently doing. Please check out the CardLayout Tutorial.
And my solution does work, but you also must call revalidate and repaint to get the GUI to layout the new component and repaint it. Note additions and changes as marked by the \\ !! comment
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FooWork {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
userFrame.main(args);
});
}
}
class NewWork extends JPanel {
public NewWork() {
setBackground(Color.red);
}
}
class WorkPan extends JPanel {
JPanel work = new JPanel();
public WorkPan() {
setBackground(Color.LIGHT_GRAY);
setLayout(new BorderLayout(40, 50));
}
void TaskPannel() {
System.out.println("here");
add(new NewWork(), BorderLayout.CENTER);// adds NewWork panel
// !!
revalidate();
repaint();
// !!
}
}
class MenuPan extends JPanel implements ActionListener {
// !! WorkPan work = new WorkPan();
WorkPan work; // !!
JButton view; // !!
// !!
public MenuPan(WorkPan workPan) { // references are key
// !!
this.work = workPan; // set the reference!
// !!
setBackground(Color.white);
setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
setLayout(new FlowLayout(1, 15, 10));
view = new JButton(" Registered Courses ");
view.addActionListener(this);
add(view);
}
#Override
public void actionPerformed(ActionEvent e) {
work.TaskPannel();
}
}
class userFrame extends JFrame {
public void Frame() {
setTitle("TEST CASE");
setSize(900, 670);
// !!
WorkPan workPan = new WorkPan();
MenuPan menuPan = new MenuPan(workPan);
// !!
// !!
// add(new MenuPan(), BorderLayout.NORTH);
// add(new WorkPan(), BorderLayout.CENTER);
add(menuPan, BorderLayout.NORTH);
add(workPan, BorderLayout.CENTER);
// !!
setLocationRelativeTo(this);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
userFrame u = new userFrame();
u.Frame();
}
}
But again, cleaner is to use a CardLayout to help with the swapping:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class SwapStuff {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
SwapMainPanel mainPanel = new SwapMainPanel();
JFrame frame = new JFrame("SwapStuff");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
class SwapMainPanel extends JPanel {
private CardLayout cardLayout = new CardLayout();
private JPanel cardPanel = new JPanel(cardLayout);
private ButtonPanel buttonPanel = new ButtonPanel(this); // pass the reference
private WorkPanel workPanel = new WorkPanel();
private ViewPanel viewPanel = new ViewPanel();
public SwapMainPanel() {
cardPanel.add(workPanel, workPanel.getClass().getName());
cardPanel.add(viewPanel, viewPanel.getClass().getName());
setLayout(new BorderLayout());
add(buttonPanel, BorderLayout.PAGE_START);
add(cardPanel, BorderLayout.CENTER);
}
// one possible way to swap "cards"
public void nextCard() {
cardLayout.next(cardPanel);
}
}
class ButtonPanel extends JPanel {
private SwapMainPanel mainPanel;
public ButtonPanel(SwapMainPanel mainPanel) {
this.mainPanel = mainPanel; // set the reference!
add(new JButton(new SwapAction("Swap Panels", KeyEvent.VK_S)));
}
private class SwapAction extends AbstractAction {
public SwapAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
mainPanel.nextCard();
}
}
}
class WorkPanel extends JPanel {
public WorkPanel() {
setBorder(BorderFactory.createTitledBorder("Work Panel"));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 400);
}
}
class ViewPanel extends JPanel {
public ViewPanel() {
setBorder(BorderFactory.createTitledBorder("View Panel"));
setBackground(Color.RED);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 400);
}
}
I've created 3 buttons. They are each displayed twice in a JFrame. I'm having trouble changing the background of the frame. I've set ActionListeners but upon clicking, nothing is changing. May I ask for some help.
public class MyButtons extends JPanel {
public static JFrame frame;
private JButton Red = new JButton("Red");
private JButton Green = new JButton("Green");
private JButton Blue = new JButton("Blue");
public void InitializeButton()
{
Blue.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
frame.setBackground(Color.BLUE);
}
});
Green.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
frame.setBackground(Color.GREEN);
}
});
Red.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
frame.setBackground(Color.RED);
}
});
}
public MyButtons() {
InitializeButton();
add(Red);
add(Green);
add(Blue);
}
public static void main(String[] args) {
frame = new JFrame();
JPanel row1 = new MyButtons();
JPanel row2 = new MyButtons();
row1.setPreferredSize(new Dimension(250, 100));
row2.setPreferredSize(new Dimension(250, 100));
frame.setLayout(new GridLayout(3,2));
frame.add(row1);
frame.add(row2);
frame.pack();
frame.setVisible(true);
}
}
This code works, but probably not as you expected:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MyButtons extends JPanel {
//public static JFrame frame;
// static is rarely a solution of problems in a GUI. ToDo! Change!
static JPanel ui = new JPanel(new GridLayout(2, 0, 20, 20));
private JButton Red = new JButton("Red");
private JButton Green = new JButton("Green");
private JButton Blue = new JButton("Blue");
public void InitializeButton() {
Blue.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ui.setBackground(Color.BLUE);
}
});
Green.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ui.setBackground(Color.GREEN);
}
});
Red.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ui.setBackground(Color.RED);
}
});
}
public MyButtons() {
InitializeButton();
add(Red);
add(Green);
add(Blue);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(250, 100);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel row1 = new MyButtons();
JPanel row2 = new MyButtons();
//row1.setPreferredSize(new Dimension(250, 100));
//row2.setPreferredSize(new Dimension(250, 100));
//frame.setLayout(new GridLayout(3, 2,10,10));
ui.add(row1);
ui.add(row2);
frame.add(ui);
frame.pack();
frame.setVisible(true);
}
}
N.B. Please learn common Java nomenclature (naming conventions - e.g. EachWordUpperCaseClass, firstWordLowerCaseMethod(), firstWordLowerCaseAttribute unless it is an UPPER_CASE_CONSTANT) and use it consistently.
Hey everyone, I want to combine my classes and get it in
only one frame. Now I have 2 classes and I don't know how to group them.
The JSlider.
public class JSliderExample extends JFrame {
JSlider jsHorizontal;
JTextField jtf1;
public JSliderExample() {
jsHorizontal = new JSlider(JSlider.HORIZONTAL, 0, 100, 50);
jtf1 = new JTextField(15);
jtf1.setEditable(false);
jtf1.setText("Horizontal value is " + jsHorizontal.getValue());
JPanel panel = new JPanel();
panel.setBackground(Color.WHITE);
panel.add(jsHorizontal);
panel.setBackground(Color.WHITE);
panel.add(jtf1);
panel.setBackground(Color.WHITE);
getContentPane().add(panel, BorderLayout.CENTER);
getContentPane().add(panel, BorderLayout.SOUTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(300, 400, 400, 300);
setVisible(true);
setBackground(Color.WHITE);
}
class JSliderHandler implements ChangeListener {
public void stateChanged(ChangeEvent ce) {
jtf1.setText("value is " + jsHorizontal.getValue());
}
}
And there are my buttons
.
public void createGUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
JButton button2 = new JButton("PLAY");
button2.setActionCommand("Button PLAY was pressed!");
panel.add(button2);
textField = new JTextField();
textField.setColumns(23);
panel.add(textField);
ActionListener actionListener = new TestActionListener();
button1.addActionListener(actionListener);
button2.addActionListener(actionListener);
button3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textField.setText(e.getActionCommand());
}
});
getContentPane().add(panel);
setPreferredSize(new Dimension(320, 100));
}
public class TestActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
textField.setText(e.getActionCommand());
}
}
In the end of programm I see 2 frames that consist of 2 classes.
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
TestFrame frame = new TestFrame();
frame.pack();
JSliderExample frame1 = new JSliderExample();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
If you don't want to see 2 JFrames, then don't create 2 JFrames. Why not make JPanels with all your classes above and not JFrames, and then in your main method, add your JPanels to the JFrame created within main. Simple.
So for example, instead of having JSliderExample extend JFrame, change it's name to SliderPanel and have it extend JPanel, and likewise with your JButton program. Then your main method could look something like:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// your JSlider example class **that extends JPanel**
SliderPanel sliderPanel = new SliderPanel();
// your JButton example class **that extends JPanel**
ButtonPanel buttonPanel = new ButtonPanel():
JFrame frame = new JFrame("My GUI");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(sliderPanel, BorderLayout.PAGE_START);
frame.add(buttonPanel, BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null); // center GUI if you want
frame.setVisible(true);
}
});
}
I want to create a button with checkbox in the right side of it.
i tried this but checkbox stays on the center of button on the top of button label text.
Any ideas welkom.
thanks in advance:
public class MainTest extends JPanel {
JButton button;
JPanel panel;
public MainTest() {
createComponents();
layoutComponents();
}
public void createComponents() {
// attempting to add checkbox to button
button = new JButton("Print with Edge");
JCheckBox checkBox = new JCheckBox();
jcb.setHorizontalAlignment(SwingConstants.RIGHT);
button.add(checkBox,new BorderLayout());
panel = new JPanel(new BorderLayout());
}
public void layoutComponents() {
panel.add(button,BorderLayout.SOUTH);
add(panel);
}
public static void main(String[] args) {
MainTest demo = new MainTest();
JFrame frame = new JFrame();
Container cp = frame.getContentPane();
cp.add(demo);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setLocation(500, 500);
frame.setVisible(true);
}
}
You can wrap a JCheckBox inside a JPanel and make the JPanel look like a button. For example:
public class Test {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(new Dimension(100, 100));
JCheckBox button = new JCheckBox();
final JPanel buttonWrapper = new JPanel();
buttonWrapper.add(new JLabel("Button Text"));
buttonWrapper.add(button);
buttonWrapper.setBorder(BorderFactory.createRaisedBevelBorder());
buttonWrapper.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent me) {
buttonWrapper.setBorder(BorderFactory.createEtchedBorder());
}
#Override
public void mouseReleased(MouseEvent me) {
buttonWrapper.setBorder(BorderFactory.createRaisedBevelBorder());
}
#Override
public void mouseClicked(MouseEvent me) {
System.out.println("mouse clicked");
}
});
JPanel mainPanel = new JPanel();
mainPanel.add(buttonWrapper);
frame.getContentPane().add(mainPanel);
frame.setVisible(true);
}
}
I want to create a button with checkbox in the right side of it.
Maybe you just want the checkbox on the right side of the text?
If so you can do:
JCheckBox cb = new JCheckBox("Print with Edge");
cb.setHorizontalTextPosition(SwingConstants.LEADING);
This is the JPanel
public class DisplayBoard {
public static void main (String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//The main panel
JPanel main = new JPanel();
main.setPreferredSize(new Dimension(600,800) );
main.setLayout(new BorderLayout());
//The title panel
JPanel title = new JPanel();
title.setPreferredSize(new Dimension(400, 120));
title.setBackground(Color.YELLOW);
JLabel test1 = new JLabel("Title goes here");
title.add(test1);
//The side bar panel
JPanel sidebar = new JPanel();
sidebar.setPreferredSize(new Dimension(200, 800));
sidebar.add(AddSubtract);
sidebar.setBackground(Color.GREEN);
JLabel test2 = new JLabel("Sidebar goes here");
sidebar.add(test2);
//The panel that displays all the cards
JPanel cardBoard = new JPanel();
cardBoard.setPreferredSize(new Dimension(400,640) );
//adding panels to the main panel
main.add(cardBoard, BorderLayout.CENTER);
main.add(title, BorderLayout.NORTH);
main.add(sidebar, BorderLayout.WEST);
frame.setContentPane(main);
frame.pack();
frame.setVisible(true);
}
}
and I want to add this class into the sidebar panel
public class AddSubtract {
int Number = 0;
private JFrame Frame = new JFrame("Math");
private JPanel ContentPane = new JPanel();
private JButton Button1 = new JButton("Add");
private JButton Button2 = new JButton("Subtract");
private JLabel Num = new JLabel ("Number: " + Integer.toString (Number));
public AddSubtract() {
Frame.setContentPane(ContentPane);
ContentPane.add(Button1);
ContentPane.add(Button2);
ContentPane.add(Num);
Button1.addActionListener(new Adding());
Button2.addActionListener(new Subtracting());
}
public class Adding implements ActionListener {
public void actionPerformed(ActionEvent e) {
Number++;
Num.setText ("Number: " + Integer.toString (Number));
}
}
public class Subtracting implements ActionListener {
public void actionPerformed(ActionEvent e) {
Number--;
Num.setText ("Number: " + Integer.toString (Number));
}
}
public void launchFrame(){
Frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Frame.pack();
Frame.setVisible(true);
}
public static void main(String args[]){
AddSubtract Test = new AddSubtract();
Test.launchFrame();
}
}
Can someone explain to me how I can do this ?
I have a feeling that this is not going to work, but I really want to learn the way to do it.
This definately is not going to work. For starters, you have two main() methods. Second, if you want to add a class to your Frame, it should extend from JComponent. Basically, your code should look like this:
public class MainFrame extends JFrame {
public MainFrame() {
this.add(new MainPanel())
//insert all settings here.
}
}
public class MainPanel extends JPanel {
public MainPanel() {
this.add(new AddSubtract());
this.add(/*more panels*/)
}
}
public class AddSubtract extends JPanel {
public AddSubtract() {
//add buttons and stuff here
}
}
and variables do NOT start with capitals.
Edit: And when you have some JFrame, it's usually best to have a main() method with just one line:
public static void main(String[] args) {
new MainFrame();
}
just set the settings and configuration of the JFrame in the constructor.