package sample;
import java.awt.DisplayMode;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class NewClass {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
final JFrame frame = new JFrame();
final JDesktopPane d = new JDesktopPane();
frame.setTitle("Frame");
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
device.setFullScreenWindow(frame);
device.setDisplayMode(new DisplayMode(800, 600, 32, 60));
frame.setVisible(true);
JButton btn = new JButton();
btn.setText("Button");
final JPanel panel = new JPanel();
panel.add(btn);
frame.add(panel);
final JFileChooser chooser = new JFileChooser();
chooser.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals(JFileChooser.APPROVE_SELECTION)) {
System.out.println("File selected: " + chooser.getSelectedFile());
chooser.getFocusCycleRootAncestor().setVisible(false);
} else {
chooser.getFocusCycleRootAncestor().setVisible(false);
}
}
});
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showInternalOptionDialog(frame.getContentPane(), chooser, "Browse", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, new Object[]{}, null);
}
});
}
}
This code looks weird for you, but thats the only way to preserve my full screen using GraphicsDevice. My problem is that, when I click the cancel or open button of the JFileChooser, my screen freezes using this code chooser.getFocusCycleRootAncestor().setVisible(false);. How can I close the JOPtionPane using internal dialog without freezing my screen or closing the whole screen.
you problem is not in
chooser.getFocusCycleRootAncestor().setVisible(false);
if you make these changes, your code will work flawlessly
just remove this part
JOptionPane.showInternalOptionDialog(frame.getContentPane(),chooser, "Browse",JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, new Object[]{}, null);
and add this code instead
chooser.showOpenDialog(frame);
let me know if you have further concerns
The problem is, the program still thinks that there is a modal dialog open, which is restricting focus to the modal dialog...
Try changing your chooser's actionListener to something like this...
chooser.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Container parent = chooser.getParent();
while (!(parent instanceof JOptionPane)) {
parent = parent.getParent();
}
JOptionPane op = (JOptionPane) parent;
op.setValue("done");
if (e.getActionCommand().equals(JFileChooser.APPROVE_SELECTION)) {
System.out.println("File selected: " + chooser.getSelectedFile());
} else {
}
}
});
This basically "tricks" the JOptionPane into thinking that the user has selected a value (which you've actually not provided anything for) and closes the dialog, returning control back to your application
Related
I want JOptionPane to appear above modeless dialogs. For example, in the following app please press the JDialog button to show a modeless dialog, and then press the JOptionPane button to show a JOptionPane confirmation dialog. Unfortunately, the JOptionPane appears under the modeless dialog.
In my real app, I have several modeless JDialogs, and I use JOptionPane from several different places.
How can I easily make the JOptionPane appear above all the modeless JDialog instances?
By "easily" I mean by adding 1 or 2 lines to each modeless JDialog construction or to each JOptionPane invocation.
One way I tried was to make a new temporary unowned JFrame with always-on-top option as the owner of the JOptionPane. This makes the JOptionPane on top, but the JOptionPane is in center of the screen instead of the center of original JFrame, and I worry that the user may not notice it.
Another way I tried was to make all modeless dialogs invisible before showing the JOptionPane and then making them visible again afterward. But this way is not easy to put round all calls to JOptionPane, because (I believe) it requires a try-finally block to do reliably.
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
public class App {
public static void main(String[] args) {
JFrame f = new JFrame("App Frame");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnDialog = new JButton("JDialog");
JButton btnOptionPane = new JButton("JOptionPane");
btnDialog.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JDialog dlg = new JDialog(f, "Modeless Dialog", false);
dlg.setSize(256, 256);
dlg.setLocationRelativeTo(f);
dlg.setVisible(true);
}
});
btnOptionPane.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showConfirmDialog(f, "Confirm JOptionPane");
}
});
f.add(btnDialog, BorderLayout.WEST);
f.add(btnOptionPane, BorderLayout.EAST);
f.setSize(512, 512);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
You need to set the correct parent for your option pane. To determine it you can use the list of all opened windows. In my example I use the last opened window.
import java.awt.BorderLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class App {
public static void main(String[] args) {
JFrame f = new JFrame("App Frame");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnDialog = new JButton("JDialog");
JButton btnOptionPane = new JButton("JOptionPane");
btnDialog.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JDialog dlg = new JDialog(f, "Modeless Dialog", false);
dlg.setSize(256, 256);
dlg.setLocationRelativeTo(f);
dlg.setVisible(true);
}
});
btnOptionPane.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showConfirmDialog(findLatestWindow(), "Confirm JOptionPane");
}
});
f.add(btnDialog, BorderLayout.WEST);
f.add(btnOptionPane, BorderLayout.EAST);
f.setSize(512, 512);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static Window findLatestWindow() {
Window result = null;
for (Window w : Window.getWindows()) {
if (w.isVisible()) {
result = w;
}
}
return result;
}
}
If you have more than one dialog opened at the same time, and user can switch between these dialogs, so you need some more lines of code. Because in your case after button click the frame is always the focus owner.
After trying and experimenting with #Sergiy's idea of using static Window methods I came up with this:
import java.awt.BorderLayout;
import java.awt.Window;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;
public class App {
static JFrame hideOwnedWindows(JFrame f) {
ArrayList<Window> arHidden = new ArrayList();
WindowAdapter wa = new WindowAdapter() {
#Override
public void windowActivated(WindowEvent e) {
for (Window w : arHidden)
w.setVisible(true);
f.removeWindowListener(this);
}
};
for (Window w : f.getOwnedWindows()) {
if (w.isVisible()) {
w.setVisible(false);
arHidden.add(w);
}
}
f.addWindowListener(wa);
return f;
}
public static void main(String[] args) {
JFrame f = new JFrame("App Frame");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnDialog = new JButton("JDialog");
JButton btnOptionPane = new JButton("JOptionPane");
btnDialog.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JDialog dlg = new JDialog(f, "Modeless Dialog", false);
dlg.setSize(256, 256);
dlg.setLocationRelativeTo(f);
dlg.setVisible(true);
}
});
btnOptionPane.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showConfirmDialog(hideOwnedWindows(f), "Confirm JOptionPane");
}
});
f.add(btnDialog, BorderLayout.WEST);
f.add(btnOptionPane, BorderLayout.EAST);
f.setSize(512, 512);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
The "hideOwnedWindows" method hides all owned windows including the dialogs, and then restores them next time the main JFrame is activated. As all owned Windows are invisible during the JOptionPane, I think (hope) the main JFrame is always activated when the JOptionPane closes.
I'm trying to use a few JDialogs inside my form JPanel to notify the user of incorrect data and form submission.
I'm just a bit confused with the JDialog constructor. I'd want to link the dialog to the panel (only because that's where it's created), but obviously the only owner parameters that are allowed are top level Frames (which I don't think I can access from the JPanel), or a Dialog (which I can't see helping me).
I could pass a reference for the Frame down to the JPanel, but isn't that a bit strange design wise? Or am I misunderstanding the class, or just more generally where the JDialog should be instantiated?
Hope I've made myself clear, I can make a sscce if it helps. Thanks.
the only owner parameters that are allowed are top level Frames (which I don't think I can access from the JPanel
You can access the parent frame of the panel by using:
Window window = SwingUtilities.windowForComponent( yourPanelHere );
Then just use the window as the owner of the dialog.
JComponent.getTopLevelAncestor gives you the owner of the JPanel:
Returns the top-level ancestor of this component (either the
containing Window or Applet), or null if this component has not been
added to any container.
You can try it:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class DialogTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
EventQueue.invokeLater(new Runnable() {
public void run() {
DialogFrame frame = new DialogFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
/**
* Frame contains menu. When we choose menu "File-> About" JDialog will be shown
*/
class DialogFrame extends JFrame {
public DialogFrame() {
setTitle("DialogTest");
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
// Menu
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu fileMenu = new JMenu("File");
menuBar.add(fileMenu);
// Add About & Exit.
// Choose About - > About
JMenuItem aboutItem = new JMenuItem("About");
aboutItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (dialog == null) //if not
{
dialog = new AboutDialog(DialogFrame.this);
}
dialog.setVisible(true); // to show dialog
}
});
fileMenu.add(aboutItem);
// When Exit
JMenuItem exitItem = new JMenuItem("Exit");
exitItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
fileMenu.add(exitItem);
}
public static final int DEFAULT_WIDTH = 300;
public static final int DEFAULT_HEIGHT = 200;
private AboutDialog dialog;
}
/*
* Modal dialog waits on click
*/
class AboutDialog extends JDialog {
public AboutDialog(JFrame owner) {
super(owner, "About DialogTest", true);
// Mark with HTML centration
add(new JLabel(
"<html><h1><i>Все о Java</i></h1><hr>"
+ "Something about java and JDialog</html>"),
BorderLayout.CENTER);
// When push "ok" dialog window will be closed
JButton ok = new JButton("ok");
ok.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
setVisible(false);
}
});
// Button ОК down of panel
JPanel panel = new JPanel();
panel.add(ok);
add(panel, BorderLayout.SOUTH);
setSize(260, 160);
}
}
Here is my code:
else if (roomNumber == 3) {
txtAreaDisplay.append("Oh no, it looks like you have run into a monster!\n"
+ "The monster runs straight at you, looking for a fight.\n"
+ "Are you going to fight, or run?\n");
//fight
if (btnFight.getModel().isPressed()) {
txtAreaDisplay.append("You have chosen to fight the monster!\n");
}
//run
else if (btnRun.getModel().isPressed()) {
txtAreaDisplay.append("You have chosen to attempt to run away from the monster!\n");
}
}
My question is, how do I go about registering the button click in the if statement (if that makes sense)? I have the line: (btnFight.getModel().isPressed()) but that does not seem to work because when I press the button, the next line is not outputted.
Any help is greatly appreciated!
I believe the problem you have here is more fundimental. The button press is an event, as such it is asychronous to your prompt. By the time the player has read your prompting message and started to respond the if then else has already been processed and neither event has happened...so you get no message.
the place you want to put the txtAreaDisplay appends is in the button press event code. That way the prompt happens and the player makes their choice. the action happens when the player moves... Now the user should only have a short time to respond before the monster makes the choice for them.
You can do it the following way.
Example with Anonymous ActionListener.
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class ButtonE extends JFrame {
JButton btnFight = new JButton("Figth");
JButton btnRun = new JButton("Run");
JTextArea txtAreaDisplay = new JTextArea();
JPanel pnl = new JPanel(new FlowLayout());
public ButtonE() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(400, 400);
this.setLayout(new BorderLayout());
this.setVisible(true);
pnl.add(btnFight);
pnl.add(btnRun);
Container cntnr = this.getContentPane();
cntnr.add(txtAreaDisplay, BorderLayout.CENTER);
cntnr.add(pnl, BorderLayout.SOUTH);
btnFight.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
txtAreaDisplay.append("Oh no, it looks like you have run into a monster!\n"
+ "The monster runs straight at you, looking for a fight.\n"
+ "Are you going to fight, or run?\n");
txtAreaDisplay.append("You have chosen to fight the monster!\n");
}
});
btnRun.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
txtAreaDisplay.append("Oh no, it looks like you have run into a monster!\n"
+ "The monster runs straight at you, looking for a fight.\n"
+ "Are you going to fight, or run?\n");
txtAreaDisplay.append("You have chosen to attempt to run away from the monster!\n");
}
});
}
public static void main(String[] args) {
new ButtonE();
}
}
Or You can do it the Following way by using an Interface.
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class ButtonE extends JFrame implements ActionListener{
JButton btnFight = new JButton("Figth");
JButton btnRun = new JButton("Run");
JTextArea txtAreaDisplay = new JTextArea();
JPanel pnl = new JPanel(new FlowLayout());
public ButtonE() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(400, 400);
this.setLayout(new BorderLayout());
this.setVisible(true);
pnl.add(btnFight);
pnl.add(btnRun);
Container cntnr = this.getContentPane();
cntnr.add(txtAreaDisplay, BorderLayout.CENTER);
cntnr.add(pnl, BorderLayout.SOUTH);
btnFight.addActionListener(this);
btnRun.addActionListener(this);
}
public static void main(String[] args) {
new ButtonE();
}
#Override
public void actionPerformed(ActionEvent ae) {
txtAreaDisplay.append("Oh no, it looks like you have run into a monster!\n"
+ "The monster runs straight at you, looking for a fight.\n"
+ "Are you going to fight, or run?\n");
//fight
if (ae.getSource() == btnFight) {
txtAreaDisplay.append("You have chosen to fight the monster!\n");
} //run
else if (ae.getSource() == btnRun) {
txtAreaDisplay.append("You have chosen to attempt to run away from the monster!\n");
}
}
}
You should use a JToggleButton and then use an ActionListener to help perform the action you want to run. This should help and will perform whatever has been clicked it is being used as a different version of an if-statement.
tglFight.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
tglFight.setBackground(Color.GREEN);
txtAreaDisplay.append("You have chosen to fight the monster!\n");
}
});
tglRun.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
tglRun.setBackground(Color.RED);
txtAreaDisplay.append("You have chosen to attempt to run away from the monster!\n");;
}
});
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm creating a "Snake" game as homework and I've passed hours searching around all the possible methods to close a JFrame, without conclusion. I started the program creating a JFrame with a background image and a menu, nothing more. When I click on the "Start game" button (JMenuItem) it opens a new JFrame with a thread to play the game. My problem is that the first JFrame doesn't close anyway I try to. I tried using these solutions and these and these but that JFrame's still there. It looks like the only command he listens to is the "EXIT_ON_CLOSE" as DefaultCloseOperation, not even the "DISPOSE_ON_CLOSE" is working. This is my SnakeFrame class:
package snake;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
/**
*
* #author Giacomo
*/
public class SnakeFrame extends Snake{
protected JMenuItem start = new JMenuItem("Start game");
public void pullThePlug(final SnakeFrame frame) {
/*// this will make sure WindowListener.windowClosing() et al. will be called.
WindowEvent wev = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
// this will hide and dispose the frame, so that the application quits by
// itself if there is nothing else around.
frame.setVisible(false);
frame.dispose();*/
frame.addComponentListener(new ComponentAdapter() {
#Override
public void componentHidden(ComponentEvent e) {
((JFrame)(e.getComponent())).dispose();
}
});
}
public int game(final SnakeFrame frame,final JFrame gameFrame){
short game_ok=0;
try{
start.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
GameThread gamethread = new GameThread(frame,gameFrame);
gamethread.start();
pullThePlug(frame);
}
});
}
catch(Exception e){
game_ok=1;
}
return game_ok;
}
//-----------Frame initialization with relative Listeners and Events.---------\\
public SnakeFrame(){
JFrame frame= new JFrame("Le Snake");
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double larghezza = screenSize.getWidth();
double altezza = screenSize.getHeight();
frame.setBounds(((int)larghezza/4),((int)altezza/4),800, 600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
ImageIcon icon = new ImageIcon("C:\\Users\\Giacomo\\Documents"
+ "\\NetBeansProjects\\Snake\\src\\res\\Snake-icon.png");
frame.setIconImage(icon.getImage());
frame.setResizable(false);
frame.setLayout(new GridLayout());
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Menu");
menuBar.add(menu);
menuBar.setBounds(1, 1, frame.getWidth(),frame.getHeight()/25);
JMenuItem close = new JMenuItem("Exit");
close.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
menu.add(start);
menu.add(close);
frame.setJMenuBar(menuBar);
try {
frame.setContentPane(new JLabel(new ImageIcon(ImageIO.read
(new File("C:\\Users\\Giacomo\\Documents\\NetBeansProjects\\"
+ "Snake\\src\\res\\default.png")))));
} catch (IOException e) {
System.out.println("Exception with the background image.");
}
frame.pack();
}
//-------------------------Frame initialization ended.-----------------------\\
}
Here's the game thread's code instead (for now):
package snake;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
/**
*
* #author Giacomo
*/
public class GameThread extends Thread implements Runnable{
private final SnakeFrame frame;
private final JFrame gameFrame;
public GameThread(final SnakeFrame f,final JFrame gF){
this.frame = f;
this.gameFrame = gF;
}
#Override
public void run(){
System.out.println("Game Thread started.");
final Label[][] griglia = new Label[50][50];
final Container container = new Container();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double larghezza = screenSize.getWidth();
double altezza = screenSize.getHeight();
gameFrame.setVisible(true);
gameFrame.setBounds(((int)larghezza/4),((int)altezza/4),
800, 600);
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImageIcon icon = new ImageIcon("C:\\Users\\Giacomo\\Documents"
+ "\\NetBeansProjects\\Snake\\src\\res\\Snake-icon.png");
gameFrame.setIconImage(icon.getImage());
gameFrame.setResizable(false);
gameFrame.addWindowListener(new WindowAdapter(){
#Override
public void windowClosing(WindowEvent e){
//Just to be sure he dies.
gameFrame.dispose();
frame.dispose();
System.exit(0);
}
});
gameFrame.setLayout(new GridLayout(50,50));
for(int i=0;i<50;i++){
for(int j=0;j<50;j++){
griglia[i][j] = new Label();
griglia[i][j].setBackground(Color.BLACK);
container.add(griglia[i][j]);
}
}
gameFrame.add(container);
}
}
Did I forget something? Does anyone have an idea? Sorry if my code's bad but I'm at school to learn :P I'm using NetBeans 8.0.2. Thanks everyone.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
EDIT:
I have now solved most of the problems I had, and here is the main:
public static void main(String[] args) {
final SnakeFrame frame = new SnakeFrame();
short isGameOk;
isGameOk =(short)frame.game(frame);
if(isGameOk==1)
System.err.println("Game Error!");
}
while here's the SnakeFrame class ("fixed"):
public class SnakeFrame extends Snake{
private final JMenuItem start = new JMenuItem("Start game");
private final BackgroundPanel defaultpanel;
public int game(final SnakeFrame frame){
short game_ok=0;
try{
start.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
defaultpanel.setVisible(false);
JPanel panel = new JPanel();
JLabel[][] griglia = new JLabel[50][50];
panel.setLayout(new GridLayout(50,50));
for(int i=0;i<50;i++){
for(int j=0;j<50;j++){
griglia[i][j] = new JLabel();
griglia[i][j].setBackground(Color.BLACK);
panel.add(griglia[i][j]);
}
}
frame.add(panel);
griglia[45][30].setIcon(new ImageIcon
("src\\res\\sneikhead.png"));
panel.setVisible(true);
}
});
}
catch(Exception e){
game_ok=1;
}
return game_ok;
}
//-----------Frame initialization with relative Listeners and Events.---------\\
public SnakeFrame(){
JFrame frame= new JFrame("Le Snake");
ImageIcon imm = new ImageIcon(getClass().getResource
("/res/default.png"));
Image background = imm.getImage();
defaultpanel = new BackgroundPanel(background, BackgroundPanel.ACTUAL,
1.0f, 0.5f);
frame.add(defaultpanel);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double larghezza = screenSize.getWidth();
double altezza = screenSize.getHeight();
frame.setBounds(((int)larghezza/4),((int)altezza/4),800, 600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImageIcon imageIcon = new ImageIcon(getClass().getResource("/res/Snake-icon.png"));
Image icon = imageIcon.getImage();
frame.setIconImage(icon);
frame.setResizable(false);
frame.setLayout(new GridLayout());
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Menu");
menuBar.add(menu);
menuBar.setBounds(1, 1, frame.getWidth(),frame.getHeight()/25);
JMenuItem close = new JMenuItem("Exit");
close.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
menu.add(start);
menu.add(close);
frame.setJMenuBar(menuBar);
frame.pack();
}
//-------------------------Frame initialization ended.-----------------------\\
}
I am now able to change the SnakeFrame's background with a defaultpanel.setVisible(false); but the panel full of black colored labels that should show isn't visible even if I set it true. How can I get it visible? Thank you.
Some general comments:
Why are you creating a second frame? Usually a game is played in its own frame? You have a menu that allows you to change options of the game and this is done by display a modal JDialog. Then you have a "Start" button that starts the game by adding a panel to the existing frame.
Don't use a ComponentListener on the frame. There is no need to handle componentHidden.
Why do you have the game() method? I don't even see in your code where you invoke the method. Just add the actionListener to the Start menu item in the constructor of your class. Keep the creation of the menu item and the assignment of the actionListener in the same block of code so we don't need to look all over the class to find all the related properties for the component.
When I click on the "Start game" button (JMenuItem) it opens a new JFrame with a thread to play the game.
This is wrong. You should NOT be starting a separate Thread. All Swing components should be created on the Event Dispatch Thread (EDT). So basically the code should just be invoked from within your ActionListener since all event code does execute on the EDT.
It looks like the only command he listens to is the "EXIT_ON_CLOSE" as DefaultCloseOperation, not even the "DISPOSE_ON_CLOSE" is working.
Those are properties that you set for the frame. Then when the user clicks on the "X" button at the top/right of the frame the frame will close depending on the property. These properties have no effect when you invoke frame.dispose() or System.exit() directly.
GameThread gamethread = new GameThread(frame,gameFrame);
Why are you passing the frame to your other class? If you goal is to close the original frame. Then close the frame here after creating the other frame. In fact why do you even have a reference to the "gameFrame" here. If you have another class that creates the components of the frame, it should create the frame as well.
pullThePlug(frame);
This code does nothing. You are invoking this method AFTER you attempt to close the frame.
In general, I can't follow your logic since the code is not complete. However as a general rule an application should only contain a single JFrame. Hiding/showing multiple frames is not an experience uses want to see. When a new game starts you should just refresh the content pane of the existing frame.
I am very new to Java AWT. My question header must seem ridiculous to you, sorry about that. In my application I have three buttons which display different threads when clicked on. Now I want to add maybe a button or checkboxes or choicelist, etc when clicked on a particular button. For eg, if I click on yes button, it should display a choice list, something like that. How do I achieve something like that? Here is my code so far:
import java.awt.Button;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class AppWindow extends Frame implements ActionListener{
String keymsg = "Test message";
String mousemsg = "Nothing";
int mouseX=30, mouseY=30;
String msg;
public AppWindow(){
//addKeyListener(new MyKeyAdapter(this));
//addMouseListener(new MyMouseAdapter(this));
addWindowListener(new MyWindowAdapter());
}
public void paint(Graphics g){
g.drawString(msg, 150, 100);
}
//Here the window is created:
public static void main(String args[]){
AppWindow appwin = new AppWindow();
appwin.setSize(new Dimension(300,200));
appwin.setTitle("My first AWT Application");
appwin.setLayout(new FlowLayout(FlowLayout.LEFT));
appwin.setVisible(true);
Button yes,no,maybe;
yes = new Button("yes");
no = new Button("no");
maybe = new Button("maybe");
appwin.add(yes);
appwin.add(no);
appwin.add(maybe);
yes.addActionListener(appwin);
no.addActionListener(appwin);
maybe.addActionListener(appwin);
}
#Override
public void actionPerformed(ActionEvent ae) {
// TODO Auto-generated method stub
String str = ae.getActionCommand();
if(str.equals("yes")){
msg = "You pressed Yes";
}
if(str.equals("no")){
msg = "You pressed No";
}
if(str.equals("maybe")){
msg = "You pressed Maybe";
}
repaint();
}
}
class MyWindowAdapter extends WindowAdapter {
public void windowClosing(WindowEvent we){
System.exit(0);
}
}
Points describing what you should be doing :
As already mentioned by others, better to use Swing over AWT, since Swing is more advanced.
As much as possible, always try to Paint on top of a JPanel or a
JComponent, instead of Painting right on top of your JFrame, by
overriding the paintComponent(Graphics g) method of the said
JComponent/JPanel
Never call setVisible(true) on the JFrame until and unless it's
size has been established. So in general terms, this has to be the
last call, once you are done adding components to the JFrame and
the size of the JFrame has been realized by the LayoutManager.
Inside your actionPerformed(...), instead of writing all if
statement blocks, you should adhere to the if-else if statement
blocks. The benefit of this, over the former is that, at any given
time, only one event will be fired, hence once the said condition is
satisfied, you don't want your code to keep checking other
conditions, which in general is really not a good programming
practice, IMHO.
MOST IMPORTANT THING : Never make calls like pack()/setVisible(...) from within the main method, such calls belong
to the Event Dispatch Thread, and must be done on the same. Please
read Concurrency in Swing for more detail.
Have a look at the example program, for better understanding.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ComponentExample
{
private CustomPanel drawingBoard;
private JPanel contentPane;
private JButton yesButton;
private JButton noButton;
private JButton maybeButton;
private JComboBox cbox;
private ActionListener buttonAction = new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
JButton button = (JButton) ae.getSource();
if (cbox.isShowing())
contentPane.remove(cbox);
if (button == yesButton)
{
drawingBoard.setText("You Pressed YES.");
contentPane.add(cbox, BorderLayout.PAGE_END);
}
else if (button == noButton)
drawingBoard.setText("You Pressed NO.");
else if (button == maybeButton)
drawingBoard.setText("You Pressed MAYBE.");
/*
* revalidate()/repaint() is needed
* when the JComponent is added or
* removed from the already
* visible Container.
*/
contentPane.revalidate();
contentPane.repaint();
}
};
public ComponentExample()
{
cbox = new JComboBox(
new String[]{"I GOT IT"
, "I STILL HAD DOUBT"});
}
private void displayGUI()
{
JFrame frame = new JFrame("Component Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = new JPanel();
contentPane.setOpaque(true);
contentPane.setBackground(Color.DARK_GRAY);
contentPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(5, 5));
JPanel buttonPanel = new JPanel();
buttonPanel.setOpaque(true);
buttonPanel.setBackground(Color.WHITE);
yesButton = new JButton("YES");
yesButton.addActionListener(buttonAction);
noButton = new JButton("NO");
noButton.addActionListener(buttonAction);
maybeButton = new JButton("MAY BE");
maybeButton.addActionListener(buttonAction);
buttonPanel.add(yesButton);
buttonPanel.add(noButton);
buttonPanel.add(maybeButton);
contentPane.add(buttonPanel, BorderLayout.PAGE_START);
drawingBoard = new CustomPanel();
contentPane.add(drawingBoard, BorderLayout.CENTER);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new ComponentExample().displayGUI();
}
});
}
}
class CustomPanel extends JPanel
{
private String msg;
public CustomPanel()
{
msg = "";
setOpaque(true);
setBackground(Color.WHITE);
}
public void setText(String msg)
{
this.msg = msg;
repaint();
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(300, 300));
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawString(msg, getWidth() / 3, getHeight() / 3);
}
}
I don't know if I have understood the question well but... couldn't you create those elements and call their setVisible(boolean) methods to make them not visible at first, and them make them visible when user pushes buttons?