Whenever I run my code it ends in a few seconds. Why?
This is the Main file:
public class Main {
public static void main(String[] args) {
System.out.println("This is running");
GameWin Win = new GameWin();
}
}
This is the GameWin file:
import java.awt.event.*;
import javax.swing.*;
public class GameWin implements ActionListener{
JFrame frame = new JFrame();
JButton myButton = new JButton("New Window");
public void GameWin(){
myButton.setBounds(100,160,200,40);
myButton.setFocusable(false);
myButton.addActionListener(this);
frame.add(myButton);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(420,420);
frame.setLayout(null);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==myButton) {
frame.dispose();
}
}
}
When I try to run this code it shows running and then the code ends with exit code 1 which is good, but it just ends without showing the window. Is there something wrong with my JRE or JDK?
Constructors do not have return type. public void GameWin() is not a constructor, thus the default constructor is called that does nothing interesting here. It should be declared public GameWin().
You must call any Swing-related function in the Swing-main-thread for consistency. Thus call the construction of the GameWin object through SwingUtilities class. Even if it seems to work without such, it may not in different kind of environnements.
Hence:
import java.awt.event.*;
import javax.swing.*;
public class GameWin implements ActionListener{
public static void main(String[] args) {
System.out.println("This is running");
SwingUtilities.invokeLater(() -> new GameWin());
}
JFrame frame = new JFrame();
JButton myButton = new JButton("New Window");
public GameWin(){
myButton.setBounds(100,160,200,40);
myButton.setFocusable(false);
myButton.addActionListener(this);
frame.getContentPane().add(myButton);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(420,420);
frame.setLayout(null);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==myButton) {
frame.dispose();
}
}
}
Related
I am trying to get the buttons to at least execute something when they are pressed and BlueJ doesn't show any errors, but when I execute the Program and I try to press the buttons, nothing happens. I am really unsure why that is the case. I would appreciate any help!
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
class MainMenu
{
JFrame frame= new JFrame();
JButton button = new JButton("Singleplayer");
JButton button2 = new JButton("Multiplayer");
MainMenu(){
prepareGUI();
}
public void prepareGUI(){
frame.setTitle("Game");
frame.getContentPane().setLayout(null);
frame.add(button);
frame.add(button2);
button.setBounds(100,200,100,40);
button2.setBounds(200,200,100,40);
frame.setVisible(true);
frame.setBounds(200,200,400,400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void setUpButtonListeners(){
ActionListener buttonlistener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
frame.getContentPane().setBackground(Color.green);
System.out.println("Singleplayer Selected");
}
};
ActionListener buttonlistener2 = new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
frame.getContentPane().setBackground(Color.red);
System.out.println("Multiplayer Selected");
}
};
button.addActionListener(buttonlistener);
button2.addActionListener(buttonlistener2);
}
public class MainClass {
public void main(String args[] )
{
new MainMenu();
}
}
}
setUpButtonListeners() are not executed in the program. So action listeners are not available. you can include setUpButtonListeners() in prepareGUI method.
I have two JFrames (frameA and FrameB). frameB can only be opened from frameA and when I open frameB, frameA must be left open. frameB has got a button (Close_frameA). I would like when the button is clicked to close frameA.
How can i do it?
First of all, is each JFrame made by a different class( I would assume so because I don't know any other way to make two frames).
Possible solution to try:
in frame A, create a "static variable":
//lets call the class that create frameA ClassA
public class ClassA extends JFrame {
static JFrame frameA;
instead of doing
JFrame frameA=new JFrame("Name of the frame");
in the public static void main(String[] args).Then, in the public static void main(String[] args) program, do
//the static JFrame assigned before
frameA= new JFrmae("Nameof the frame");
this lets the program in frameB to read "frameA" with the following code in ClassB(lets call the class that make frameB ClassB):
JFrame frameA= ClassA.frameA;
then, still in ClassB, we can do
frameA.dispose();
I hope you understand(please comment for what you don't understand if you don't), and i hope it works.
Code:
import javax.swing.JFrame;
public class ClassA {
static JFrame frameA;
public ClassA(){
//a useless constructor because I am not adding any Listeners(don't worry about it)
}
public static void main(String[] args){
frameA=new JFrame("Name");
//your ordinary things(some peiople put these in the constructor)
frameA.setSize(300,300);
frameA.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frameA.setVisible(true);
//runs ClassB
new ClassB();
}
}
and
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class ClassB extends JFrame implements ActionListener{
static JButton close=new JButton("close");
public ClassB(){
//your ordinary thigns
add(close);
setSize(300,300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
close.addActionListener(this);
System.out.println("what?");
}
public static void main(String[] args){
JFrame frameB=new JFrame("Clae Frame A");
}
#Override
public void actionPerformed(ActionEvent arg0) {
if(arg0.equals("close")){
JFrame frameA=ClassA.frameA;
frameA.dispose();
}
}
}
You can use below two class: TJFrame and OpenFrame to close a JFrame class with a button in another JFrame
public class TJFrame {
public static OpenFrame openWindow;
public static void main(String[] args) {
JFrame frame = new JFrame("Swing Frame");
JButton button = new JButton("Open");
frame.add(button);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
openWindow = new OpenFrame();
openWindow.setVisible(true);
}
});
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setSize(350, 200);
frame.setVisible(true);
}}
public class OpenFrame extends JFrame{
JPanel back_panel;
public JButton button = new JButton("Cross");
public OpenFrame() {
back_panel = new JPanel();
setContentPane(back_panel);
this.setSize(350, 200);
button.setBounds(380, 10, 20, 20);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
dispose();
}
});
back_panel.add(button);
}}
To be short, I create a class Something witch have a function with a JFrame where I have a label and a button on it. On the button I have an addActionListener(new changeLabel()).
I did class changeLabel in the src package for the listener but when I start the application and I click the button throw an NullPointerException on the changeLabel at
nameLabel.setText("Name changed");
line. I want to mention that if I create this listener class in Something class, work perfectly.
I don't know why throw null exception because the label is initialized firstly and after that, the button just want to change the text.
I tryed to make a getFunction, to call that label, I tryed with object Something, with object changeLabel etc... but doesn't work.
Here is some code
package trying;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.event.*;
public class Something {
JFrame frame;
JLabel changeName;
JButton button;
public void gui(){
frame = new JFrame();
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//is just an example
changeName = new JLabel("Stefan");
//is just an example
button = new JButton("Change");
button.addActionListener(new changeLabel());
frame.getContentPane().add(changeName, BorderLayout.NORTH);
frame.getContentPane().add(button, BorderLayout.SOUTH);
frame.setVisible(true);
}
public static void main(String args[]){
new Something().gui();
}
}
The listener class
package trying;
import java.awt.event.*;
public class changeLabel extends Something implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
changeName.setText("Andrei");
}
}
How can I solve this problem?
The problem is that because the changeLabel class extends Something, it will contain it's own changeName variable which is not initialized == null.
You can:
make the changeLabel implementation private class of Something (good practice) or
pass the JLabel to its constructor.
In both ways changeLabel should not extend Something.
Code Sample #1:
public class Something {
JFrame frame;
JLabel changeName;
JButton button;
public void gui(){
frame = new JFrame();
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//is just an example
changeName = new JLabel("Stefan");
//is just an example
frame.getContentPane().add(changeName, BorderLayout.NORTH);
button = new JButton("Change");
button.addActionListener(new changeLabel());
frame.getContentPane().add(button, BorderLayout.SOUTH);
frame.setVisible(true);
}
public static void main(String args[]){
new Something().gui();
}
class changeLabel implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
changeName.setText("Andrei");
}
}
}
Code Sample #2:
public class Something {
...
public void gui() {
...
button.addActionListener(new changeLabel(changeName));
}
}
public class changeLabel implements ActionListener {
private final JLabel label;
public changeLabel(JLabel label) {
this.label = label;
}
#Override
public void actionPerformed(ActionEvent e) {
label.setText("Andrei");
}
}
I have a parent window which will start another window.When the child window is started, I want it to display like a modal dialog.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class ModalDialogTest {
public void createUI(){
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
JPanel mainPanel = new JPanel();
mainPanel.setBorder(BorderFactory.createEmptyBorder(200, 200, 200, 200));
JButton openButton = new JButton("Open a frame");
openButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
AnotherWindow anotherWindow = new AnotherWindow();
anotherWindow.createUI();
}
});
mainPanel.add(openButton,BorderLayout.CENTER);
frame.add(mainPanel,BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
ModalDialogTest modelDialogTest = new ModalDialogTest();
modelDialogTest.createUI();
}
class AnotherWindow{
public void createUI(){
JFrame frame = new JFrame("Dialog");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
JPanel mainPanel = new JPanel();
mainPanel.setBorder(BorderFactory.createEmptyBorder(100, 100, 100, 100));
JLabel label = new JLabel("I want to be a modal dialog");
mainPanel.add(label,BorderLayout.CENTER);
frame.add(mainPanel,BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
}
The demo above describes the process of my app and the architecture is just the same.So what is the solution?
You cannot set the modality of a JFrame; the second window must be a JDialog. Therefore, change the second JFrame to a JDialog and use the method setModalityType() on it.
JFrame can't be a modal, use JDialog instead
don't to create a bunch of JFrames, use JDialog instead
create only one JDialog, as local variable, re_use this container for another action by JDialog.getContentPane.removeAll() before JDialog.setVisible(false) is called
note Top-Level Containers never will be GC'ed, all a new instances increasing used JVM memory, more details about here
It's possible to make a Frame modal, but you should JDialog as standard choice.
Here is an example which I've found to make a Frame modal (code is for Java 1.4 but should also work for the actual java version).
static class EventPump implements InvocationHandler {
Frame frame;
public EventPump(Frame frame) {
this.frame = frame;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return frame.isShowing() ? Boolean.TRUE : Boolean.FALSE;
}
// when the reflection calls in this method has to be
// replaced once Sun provides a public API to pump events.
public void start() throws Exception {
final Class clazz = Class.forName("java.awt.Conditional");
final Object conditional = Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] {clazz}, this);
final Method pumpMethod = Class.forName("java.awt.EventDispatchThread").getDeclaredMethod("pumpEvents", new Class[] {clazz});
pumpMethod.setAccessible(true);
pumpMethod.invoke(Thread.currentThread(), new Object[] {conditional});
}
}
// show the given frame as modal to the specified owner.
// NOTE: this method returns only after the modal frame is closed.
public static void showAsModal(final Frame frame, final Frame owner) {
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowOpened(WindowEvent e) {
owner.setEnabled(false);
}
#Override
public void windowClosed(WindowEvent e) {
owner.setEnabled(true);
frame.removeWindowListener(this);
}
});
owner.addWindowListener(new WindowAdapter() {
#Override
public void windowActivated(WindowEvent e) {
if (frame.isShowing()) {
frame.setExtendedState(JFrame.NORMAL);
frame.toFront();
} else {
owner.removeWindowListener(this);
}
}
});
frame.setVisible(true);
try {
new EventPump(frame).start();
} catch (final Throwable throwable) {
throw new RuntimeException(throwable); // NOPMD
}
}
I'm working on a Java HW and faced this problem. Even though everything seems to be coded correctly, I'm getting blank frame in the end. I'm guessing it has something to do with this part in the driver program:
frame.getContentPane().add(new RandomPanel());
Here is my main program:
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;
public class RandomPanel extends JPanel
{
private JButton randButton;
private JLabel label;
public void NamePanel()
{
JPanel primary = new JPanel();
randButton = new JButton("Whats my name?");
ButtonListener listener = new ButtonListener();
randButton.addActionListener(listener);
label = new JLabel("Displaying random number");
setBackground(Color.pink);
add(label);
add(randButton);
}
class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
label.setText( new Integer(new Random().nextInt(100) + 1).toString() );
}
}
}
And driver program:
import javax.swing.JFrame;
public class RandomPick
{
public static void main (String[] args)
{
JFrame frame = new JFrame("RandomPick");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new RandomPanel());
frame.pack();
frame.setVisible(true);
}
}
You need to invoke namePanel to add the components to the frame.
RandomPanel randomPanel = new RandomPanel();
randomPanel.namePanel();
frame.add(randomPanel);
but you may have intended to use the method as a constructor
public RandomPanel() {
which would mean that the method call would not be necessary