Java GUI, why isn't mine showing up? - java

//leaving out import statements
public class MVCView extends JFrame{
private JButton add = new JButton("Click me");
private JTextArea center = new JTextArea(200,300);
private JTextField bottom = new JTextField(200);
public MVCView() {
setLayout(new BorderLayout());
add(add, BorderLayout.NORTH);
add(center, BorderLayout.CENTER);
add(bottom, BorderLayout.SOUTH);
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
}
public class MVCTester {
public static void main(String[] args) {
MVCView view = new MVCView();
}
}
I'm just trying to get this to show up on my screen. I create a class with main to create the object which is in a different class. When I click run nothing pops up. I've been following a few tutorials and my code doesn't look much different. Already tried putting everything in a JPanel first which didn't work... I don't know what I'm leaving out or doing wrong.

I just modified code you posted and thing works.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MVCView extends JFrame{
private JButton add = new JButton("Click me");
private JTextArea center = new JTextArea(200,300);
private JTextField bottom = new JTextField(200);
public MVCView() {
setLayout(new BorderLayout());
add(add, BorderLayout.NORTH);
add(center, BorderLayout.CENTER);
add(bottom, BorderLayout.SOUTH);
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
MVCView view = new MVCView();
}
}

Related

How to detect if a action listener has been triggered from another class?

I have a method which asks the user a question and in my GUI I have a JTextArea where they type in the answer. Since the method which asks the question is in a different class, how would I get the users answer to return to the method?
GUI (JFrame class):
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GUI extends JFrame{
public GUI(String name) {
super(name);
//setSize(700,700);
setLayout(new BorderLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
JPanel myPanel1 = new GUIPanel("Center");
add(myPanel1, BorderLayout.CENTER);
pack();
setVisible(true);
setResizable(true);
}
public static void main(String[] args) {
GUI frame = new GUI("Game");
}
}
GUIPanel (JPanel class):
package javaapplication2;
import java.awt.*;
import javax.swing.*;
public class GUIPanel extends JPanel {
JLabel label1;
JTextField textField1;
JLabel label2;
JTextArea textArea1;
public GUIPanel(String position) {
if (position.equals("Center")) {
createCenterPanel();
}
}
public void createCenterPanel() {
setLayout(new GridLayout(2,2,10,10));
label1 = new JLabel("Type Here: ");
textField1 = new JTextField();
textField1.setPreferredSize(new Dimension(110, 25));
label2 = new JLabel("Game Output: ");
textArea1 = new JTextArea();
add(label1);
add(textField1);
add(label2);
add(textArea1);
}
}
I have not yet added the method call or ActionListener class yet but basically it will call a method which will ask a question and then the user has to answer. This is what I am stuck on. I do not know how I can get the method to "detect" that the user has entered something and then retrieve the data.
I thought about making the textfield static and making a static boolean which gets changed to true when the action performed (user presses enter) gets triggered but that would mean the method would have to have a while loop to check so there must be a better way out there.
I'm not sure if this is what are you looking for because I don't know if i understood right what do you need but I tried
The only code i added was the method getTextField1Text() and called it inside createCenterPanel(), if you have anything to add please let me know, I hope this helps you a bit
public void createCenterPanel() {
setLayout(new GridLayout(2, 2, 10, 10));
label1 = new JLabel("Type Here: ");
textField1 = new JTextField();
textField1.setPreferredSize(new Dimension(110, 25));
label2 = new JLabel("Game Output: ");
textArea1 = new JTextArea();
getTextField1Text();
add(label1);
add(textField1);
add(label2);
add(textArea1);
}
public void getTextField1Text() {
textField1.addActionListener(e -> {
textArea1.setText(e.getActionCommand());
textField1.setText("");
});
}
-------------------------------------------------------------
After discussing in comment section i tried to come up with something
new(which i hope i did) to help you I added 2 methods to get the answer
(NOTE: I used System.out.println(); only for testing)
These methods are added on GUIPanel class
public void getAnswer() {
textArea1.addActionListener(e -> {
textArea1.setText(e.getActionCommand());
testAnswer(textArea1.getText());
});
}
public String testAnswer(String s) {
String saveParam = s;
System.out.println(saveParam);
return saveParam;
}
On GUI class i did some small changes so i can test if the methods is printing the answer,
GUIPanel myPanel1 = new GUIPanel("Center");
public GUI(String name) {
super(name);
//setSize(700,700);
setLayout(new BorderLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
add(myPanel1, BorderLayout.CENTER);
pack();
setVisible(true);
setResizable(true);
}
public GUIPanel getMyPanel1() {
return myPanel1;
}
public static void main(String[] args) {
GUI frame = new GUI("Game");
frame.getMyPanel1().getAnswer();
}

How to swap JPanel's from an action in a JPanel

I am new(ish) to Java Swing but I have not been able to find an elegant solution to my issue so I thought I'd raise a question here.
I am trying to make my current JPanel change to another JPanel based on a button click event from within the current JPanel. In essence just hiding one panel and displaying the other. I feel this can be done within my MainFrame class however I'm not sure how to communicate this back to it. Nothing I am trying simply seems to do as desired, I'd appreciate any support. Thanks
App.java
public static void main(final String[] args) {
MainFrame mf = new MainFrame();
}
MainFrame.java
public class MainFrame extends JFrame {
public MainFrame(){
setTitle("Swing Application");
setSize(1200, 800);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setVisible(true);
// First Page Frame switch
getContentPane().add(new FirstPage());
}
}
FirstPage.java
public class FirstPage extends JPanel {
public FirstPage() {
setVisible(true);
JButton clickBtn = new JButton("Click");
clickBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
// Change to SecondPage JPanel here.
}
});
add(clickBtn);
}
}
SecondPage.java
public class SecondPage extends JPanel {
public SecondPage() {
setVisible(true);
add(new JLabel("Welcome to the Second Page"));
}
}
Any more information needed, please ask thanks :)
I think the best way is to use CardLayout. It is created for such cases. Check my example:
public class MainFrame extends JFrame {
private CardLayout cardLayout;
public MainFrame() {
super("frame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cardLayout = new CardLayout();
getContentPane().setLayout(cardLayout);
getContentPane().add(new FirstPage(this::showPage), Pages.FIRST_PAGE);
getContentPane().add(new SecondPage(this::showPage), Pages.SECOND_PAGE);
setLocationByPlatform(true);
pack();
}
public void showPage(String pageName) {
cardLayout.show(getContentPane(), pageName);
}
public static interface PageContainer {
void showPage(String pageName);
}
public static interface Pages {
String FIRST_PAGE = "first_page";
String SECOND_PAGE = "second_page";
}
public static class FirstPage extends JPanel {
public FirstPage(PageContainer pageContainer) {
super(new FlowLayout());
JButton button = new JButton("next Page");
button.addActionListener(e -> pageContainer.showPage(Pages.SECOND_PAGE));
add(button);
}
}
public static class SecondPage extends JPanel {
public SecondPage(PageContainer pageContainer) {
super(new FlowLayout());
add(new JLabel("This is second page."));
JButton button = new JButton("Go to first page");
button.addActionListener(e -> pageContainer.showPage(Pages.FIRST_PAGE));
add(button);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new MainFrame().setVisible(true));
}
}
CardLayout is the right tool for the job.
You can simply create the ActionListener used to swap pages in JFrame class, and pass a reference of it to FirstPage:
import java.awt.CardLayout;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MainFrame extends JFrame {
public MainFrame(){
setTitle("Swing Application");
setSize(1200, 800);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLocationByPlatform(true);
//Create card layout and set it to the content pane
CardLayout cLayout = new CardLayout();
setLayout(cLayout);
//create and add second page to the content pane
JPanel secondPage = new SecondPage();
add("SECOND",secondPage);
//create an action listener to swap pages
ActionListener listener = actionEvent ->{
cLayout.show(getContentPane(), "SECOND");
};
//use the action listener in FirstPage
JPanel firstPage = new FirstPage(listener);
add("FIRST", firstPage);
cLayout.show(getContentPane(), "FIRST");
setVisible(true);
}
public static void main(String[] args) {
new MainFrame();
}
}
class FirstPage extends JPanel {
public FirstPage(ActionListener listener) {
JButton clickBtn = new JButton("Click");
clickBtn.addActionListener(listener);
add(clickBtn);
}
}
class SecondPage extends JPanel {
public SecondPage() {
add(new JLabel("Welcome to the Second Page"));
}
}

incompatible type GridLayout cannot be converted to layout manager

Here is the my demo code, please check out why this code given me problem.
package gridlayout;
import java.awt.*;
import javax.swing.*;
public class GridLayout {
public static void main(String[] args) {
EventQueue.invokeLater(()->{
MyFrame frame = new MyFrame();
//frame.setDefaultCloseOperation(0);
//frame.setTitle("Grid Layout");
// frame.setDefault
});
}
}
class MyFrame extends JFrame{
public MyFrame(){
setTitle("My Programm");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(new MyPanel());
pack();
setVisible(true);
}
}
class MyPanel extends JPanel{
private JButton display;
private double result;
private String lastCommand;
private boolean start;
private JPanel panel;
// private static final int n = 4;
public MyPanel(){
setLayout(new BorderLayout());
//setLayout(new GridLayout(4,4));
result = 0;
lastCommand = "=";
start = false;
display = new JButton("0");
setEnabled(false);
add(display, BorderLayout.NORTH);
// panel = new JPanel();
// panel.setLayout(new GridLayout());
GridLayout expLayout = new GridLayout(0,4);
}
public void addButtons(String Name){
JButton button = new JButton(Name);
}
}
The issue seems to be in that you have this code:
public class GridLayout {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
EventQueue.invokeLater(()->{
MyFrame frame = new MyFrame();
//frame.setDefaultCloseOperation(0);
//frame.setTitle("Grid Layout");
// frame.setDefault
});
}
}
Since you have defined your custom class in the package where other classes reside and that class is called GridLayout, those two names conflict when you do panel.setLayout(new GridLayout())
To avoid it either rename your custom GridLayout so that it has some different name or try panel.setLayout(new java.awt.GridLayout()) instead of panel.setLayout(new GridLayout())
P.S. - As #XtremeBaumer correctly noticed you should avoid using the well-known class names either from JDK distribution package or from other well-known libraries (at least you should understand the risks if you still required your classes to have such the names)

How do I make java game options?

I m trying to make a main menu with START button, CONTROLS button and HELP button.
I made a backboard for it but I need help with making options.
I tried to make it, but the error says that local variable gameFrame is accessed from within inner class; needs to be declared final
import java.util.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import static java.lang.System.*;
public class GameFrame {
public static void main(String[] args) {
JFrame gameFrame = new JFrame("PoopMan");
gameFrame.setSize(900, 800);
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gameFrame.setResizable(false);
gameFrame.setVisible(true);
gameFrame.getContentPane().setBackground(Color.yellow);
JPanel panel = new JPanel();
JButton button1 = new JButton();
gameFrame.add(panel);
panel.add(button1);
gameFrame.setVisible(true);
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JOptionPane.showMessageDialog(gameFrame.getComponent(0), "START");
}
});
}
}
I believe you would like to initialize your Game in a non-static context. Do the following.
public class Main {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new GameFrame();
}
});
}
}
And
import java.util.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import static java.lang.System.*;
public class GameFrame extends JFrame {
private void init() {
this.setSize(900, 800);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setResizable(false);
this.setVisible(true);
this.getContentPane().setBackground(Color.yellow);
JPanel panel = new JPanel();
JButton button1 = new JButton("START");
this.add(panel);
panel.add(button1);
this.setLayout(new FlowLayout());
this.setMinimumSize(new Dimension(300, 300));
this.pack();
this.setVisible(true);
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JOptionPane.showMessageDialog(getComponent(0), "START");
}
});
}
public GameFrame() {
super("PoopMan");
init();
}
}
This way, you start the GameFrame on another thread, and you can continue your work within the GameFrame class.
That is quite simple. Please note that this is a place to inquire about issues regarding your code, and not a place to look for answers.
What you should be researching is known as JMenuBar (refer to This Tutorial for Assitance)
Seeing as you are new, I will assist you this once. Below is the code that will accomplish what you ask. (Tried and Tested)
import java.util.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import static java.lang.System.*;
public class GameFrame
{
static private JMenuBar menuBar;
static private JMenu startMenu, controlsMenu, helpMenu;
static private JMenuItem startBtn;
static private JMenuItem controls;
static private JMenuItem hlpBtn;
public static void main(String[] args)
{
JFrame gameFrame = new JFrame("PoopMan");
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gameFrame.getContentPane().setBackground(Color.yellow);
menuBar = new JMenuBar();
startMenu = new JMenu("File");
controlsMenu = new JMenu("Controls");
helpMenu = new JMenu("Help");
startBtn = new JMenuItem("Start");
controls = new JMenuItem("Controls");
hlpBtn = new JMenuItem("Help");
gameFrame.add(menuBar, BorderLayout.PAGE_START);
menuBar.add(startMenu);
menuBar.add(controlsMenu);
menuBar.add(helpMenu);
startMenu.add(startBtn);
controlsMenu.add(controls);
helpMenu.add(hlpBtn);
gameFrame.pack();
gameFrame.setResizable(false);
gameFrame.setVisible(true);
gameFrame.setSize(900,800);
}
}
I am not certain as to why you are receiving a Final error. It works fine.
From later edits to the question:
JButton button1 = new JButton("Button");
JPanel panel = new JPanel();
panel.setBackground(Color.yellow);
gameFrame.add(panel);
panel.add(button1);
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JOptionPane.showMessageDialog(gameFrame.getComponent(0), "START");
}
});

Why does the order of setting JFrame properties matter?

During a JFrame test program, I realized that I can't put this:
setSize(450, 300);
setResizable(false);
setVisible(true);
On the top of the constructor, otherwise it doesn't work as it should. However it works if I put it in the bottom like so:
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JFrame;
#SuppressWarnings("serial")
public class GameWindow extends JFrame {
private GameGraphics gameGraphics;
public GameWindow() {
super("Fellice");
gameGraphics = new GameGraphics();
gameGraphics.setBackground(Color.BLACK);
add(gameGraphics, BorderLayout.CENTER);
setSize(450, 300);
setResizable(false);
setVisible(true);
}
}
It doesn't work if I put it after calling the superclass, but why? I have attempted to put these:
setSize(450, 300);
setResizable(false);
setVisible(true);
One by one on the top to see which was causing the problem, and it seems to to be a this combination:
setSize(450, 300);
setVisible(true);
That doesn't work at the top. However, in one of my other programs it works perfectly fine:
#SuppressWarnings("serial")
public class Client extends JFrame {
private JTextField messageField;
private JTextArea chatWindow;
public Client(String host) {
super("Messenger");
setSize(300, 400);
setVisible(true);
chatWindow = new JTextArea();
chatWindow.setEditable(false);
messageField = new JTextField();
// .. actions etc.
add(new JScrollPane(chatWindow), BorderLayout.CENTER);
add(messageField, BorderLayout.SOUTH);
}
*edit
Working code:
#SuppressWarnings("serial")
public class GameWindow extends JFrame {
private GameGraphics gameGraphics;
public GameWindow() {
super("Fellice");
gameGraphics = new GameGraphics();
gameGraphics.setBackground(Color.BLACK);
add(gameGraphics, BorderLayout.CENTER);
setSize(450, 300);
setResizable(false);
setVisible(true);
}
}
Glitched code (Screen appears blank):
#SuppressWarnings("serial")
public class GameWindow extends JFrame {
private GameGraphics gameGraphics;
public GameWindow() {
super("Fellice");
setSize(450, 300);
setResizable(false);
setVisible(true);
gameGraphics = new GameGraphics();
gameGraphics.setBackground(Color.BLACK);
add(gameGraphics, BorderLayout.CENTER);
}
}

Categories