I have game program where I want the player to choose the file directory to save his game. I am using JFileChooser for this works perfectly fine but it won't close.
here is the code:
public NewGameState(Game game) {
super(game);
open = new JButton();
fc = new JFileChooser();
fc.setCurrentDirectory(new java.io.File("."));
fc.setDialogTitle("Choose file for the new world");
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
}
public void tick() {
input();
selection();
}
public void render(Graphics g) {
drawSelection(g);
drawGUI(g);
}
private void input(){
if(game.getKeyManager().up){
selection --;
}else if(game.getKeyManager().down){
selection ++;
}
if(game.getKeyManager().space){
if(selection == 0){
fileChooser(); //calling fileChooser method when pressing space
}else if(selection == 1){
}else if(selection == 2){
}
}
}
private void selection(){
//blahbahabahaa
}
}
//fileChooser
private void fileChooser(){
fc.showOpenDialog(null);
}
I thought that space is true and it keeps executing the code every tick it turn out it won't stop reading the code which stops the ticking proccess. It keeps reading the method over and over. Other answers are using panel which I'm not using panel in this program I'm using canvas and jframe only
if this is what you are looking for just to be able to close the File Chooser Dialog after selecting the file or saving the file. Just still try to make the code more explanatory i think this should based on my understanding of what u explained
int c = fileWindow.showSaveDialog(this);
if(c==JFileChooser.APPROVE_OPTION)
files.append(fileWindow.getSelectedFile()+"\n");
Related
Synopsis
I am developing a Java Swing project, and I have been debugging successfully within IntelliJ IDEA by running the main method directly. After closing the frame, the debugger exits normally.
However, after adding a JFileChooser dialog to the project, the debugger does not exit normally. I have to click the stop button every time now, which causes the JVM to exit with a non-zero status.
Minimal, Reproducible Example
This is the section of code that is causing the problem; it is an ActionListener that I am adding to two buttons which launch the JFileChooser:
/**
* Generic action listener that is used for both file selection dialog buttons
*/
private final ActionListener fileSelectionButtonActionListener = new ActionListener()
{
#Override
public void actionPerformed(final ActionEvent event)
{
final String target = ((JButton) event.getSource()).getName();
assert (target.equals("file") || target.equals("directory"));
JFileChooser fileChooser = new JFileChooser(new File(".").getAbsoluteFile());
fileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
if(target.equals("directory")) {
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
}
final int result = fileChooser.showOpenDialog(new JFrame());
if(result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
if(target.equals("file")) {
fileTextField.setText(selectedFile.getAbsolutePath());
} else {
directoryTextField.setText(selectedFile.getAbsolutePath());
}
}
}
};
Debugging Steps
I have tried moving the JFrame creation from the parameter of the showOpenDialog method to a variable declaration and added frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); but that did not fix the issue. It's almost like the frame is still hanging around in memory, and that's why the JVM won't close.
Question
How can I make the JVM close appropriately while using JFileChooser?
The problem is, indeed, that the JFrame is still in memory, causing the JVM to hang. However, the solution is a JFrame is not needed.
Instead of setting a new JFrame() as the parent of the dialog, set the parent to the dialog window itself:
/**
* Generic action listener that is used for both file selection dialog buttons
*/
private final ActionListener fileSelectionButtonActionListener = new ActionListener()
{
#Override
public void actionPerformed(final ActionEvent event)
{
final String target = ((JButton) event.getSource()).getName();
assert (target.equals("file") || target.equals("directory"));
JFileChooser fileChooser = new JFileChooser(new File(".").getAbsoluteFile());
fileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
if(target.equals("directory")) {
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
}
--> final int result = fileChooser.showOpenDialog(fileChooser); <--
if(result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
if(target.equals("file")) {
fileTextField.setText(selectedFile.getAbsolutePath());
} else {
directoryTextField.setText(selectedFile.getAbsolutePath());
}
}
}
};
Change the line where you get the result: final int result = fileChooser.showOpenDialog(fileChooser);. Doing that fixes the issue.
I have to write a program that essentially makes a report card, but it cannot do so until until it reads in a file either through command line arguments or by the user picking one from their browser, which means I need to use JFileChooser. I have the GUI set-up for the JFileChooser but that's all I can figure out. The dialog window opens when I click open but after picking a file the window I created (GUI) does not close. Also the program runs through all of my other methods before a file is even loaded causing other problems. I tried using a do-while loop but it just runs through the loop before I can ever open a file.
import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MP1 extends JFrame implements java.awt.event.ActionListener{
static StudentAssignments geen165 = new StudentAssignments();
static boolean fileReady = false;
/**
* #param args the command line arguments
*/
public static void main(String [] args) {
do{
if(args.length == 0 || args[0].isEmpty()){//reads in input from file
//select
MP1 doIt = new MP1();
doIt.setVisible(true);
}
else{
geen165.readGradeFile(args[0]);//reads in input file from command
//argument
}
}while(!fileReady);
//test methods
JOptionPane.showMessageDialog(null, geen165.getGradeReport());
geen165.addAssignments(3, 98, 100);
geen165.saveGradeFile("NewGrades.txt");
JOptionPane.showMessageDialog(null, geen165.getGradeReport());
geen165.removeAssignment(0, 2);
JOptionPane.showMessageDialog(null, geen165.getGradeReport());
}
//JFile Chooser GUI
public MP1(){
prepareGui();
}
private void prepareGui(){
setSize(500,500);
Container window = getContentPane();
window.setLayout(new FlowLayout());
JButton open = new JButton("Open");
JButton cancel = new JButton("Cancel");
JLabel status = new JLabel("You've selected: ");
//sets file when open is pressed
open.addActionListener((ActionEvent e) -> {
JFileChooser chooser = new JFileChooser();
int returnVal = chooser.showOpenDialog(window);
if(returnVal == JFileChooser.APPROVE_OPTION){
File fileName = chooser.getSelectedFile();
status.setText("You've selected: " + fileName.getName());
geen165.readGradeFile(fileName.getName());
fileReady=true;
}
});
//exits program if cancel is pressed
cancel.addActionListener((ActionEvent e) -> {
System.exit(1);
});
window.add(open);
window.add(cancel);
window.add(status);
setDefaultCloseOperation(HIDE_ON_CLOSE);
}
#Override
public void actionPerformed(ActionEvent e) {
throw new UnsupportedOperationException("Not supported yet."); //To change
//body of generated methods, choose Tools | Templates.
}
}
Any suggestions?
You are complicating a simple issue. There is no need for you to build a window and everything only to use JFileChooser. A simple solution that works is
import javax.swing.*;
public class MP1 extends JFrame {
public static void main(String[] args) {
String myFile="";
if (args.length == 0 || args[0].isEmpty()) {//reads in input from file
//select
JFileChooser chooser = new JFileChooser();
int returnVal = chooser.showOpenDialog(null);
if (returnVal!=JOptionPane.CANCEL_OPTION) {
myFile = chooser.getSelectedFile().getPath();
} else {
JOptionPane.showMessageDialog(null, "Thanks for playing!");
System.exit(0);
}
} else {
myFile = args[0];
}
JOptionPane.showMessageDialog(null, "You have selected "+myFile+". Go play!");
}
}
Notice that I check whether there is a parameter. If not, I immediately go and execute the JFileChooser. There is no need for overhead.
I removed all your class activity, because I do not have the files.
BTW, I have not tested it, but I believe that your problem comes from your new frame not being modal. Hence, the boolean variable is changed before you can do anything. But that is just an idea.
I think you need to know how JFileChooser works.
JFileChooser fc = new JFileChooser();
int optionSelected = fc.showOpenDialog(YourClassName.this);
if (optionSelected == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
... // Do what you want with the file
}
JFileChooser
In my code I am asking the user to choose an image. My JFileChooser window worked fine. Then I restarted my computer and now whenever that window comes up it is not clickable in any way. I can't open a file, I can't cancel, I can't chooser folders or files. Here is the necessary code.
JFileChooser jfc = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter("Image Files", "jpg", "png", "jpeg");
jfc.setFileFilter(filter);
jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
jfc.setVisible(true);
int ret = jfc.showOpenDialog(null);
if (ret == JFileChooser.CANCEL_OPTION) {
return;
}
File file_1 = jfc.getSelectedFile();
file_path = file_1.getAbsolutePath();
Breakpoints show that the program never leaves this line:
int ret = jfc.showOpenDialog(null);
As I said the same exact code was working fine moments ago. Not sure what is causing this situation.
In my main program I click "Add image" which calls the previously mentioned code. I try clicking on the window "Open" opened by "showOpenDialog" but it doesn't matter where I click. Nothing changes. The main program resumes once I close the "Open" window from my task manager. Also in my task manager "Open" window doesn't say not responding, it looks fine and closes at an instance and furthermore inside the text field the text cursor is blinking.
EDIT: Same exact code works on a separate project that consists of only this code.
EDIT 2: Some additional codes.
Here is the complete load_file() function.
public class Image {
private static String file_path;
private static ImageFrame frame;
public static boolean isImgLoaded = false;
public static void load_file(){
JFileChooser jfc = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter("Image Files", "jpg", "png", "jpeg");
jfc.setFileFilter(filter);
jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
jfc.setVisible(true);
int ret = jfc.showOpenDialog(null);
if (ret == JFileChooser.CANCEL_OPTION) {
return;
}
File file_1 = jfc.getSelectedFile();
file_path = file_1.getAbsolutePath();
ImageFrame frm = new ImageFrame();
frm.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frm.setVisible(true);
frame = frm;
isImgLoaded = frame.get_component().is_img_loaded();
frame.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
closeFrame();
}
});
}
Here is the button code that calls the function when pressed. shlErgo is my shell that the UI is built on.
Button btnAddImage = new Button(shlErgo, SWT.NONE);
btnAddImage.setBounds(230, 10, 75, 25);
btnAddImage.setText("Add Image");
btnAddImage.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
if (!Image.isImgLoaded){
Image.load_file();
}
else{
Error.translate(2);
}
}
});
I am creating a simple text editor and have run into a small problem. I can open and have open several new windows for creating text documents by clicking on the new button in the menu. My problem is if I click on "File" then "Exit" from the menu it closes all the windows not just the one I wanted closed. How do I go about making it so that it will close just the chosen window and not the entire application.
Here's some code:
public void actionPerformed(ActionEvent event) {
if(event.getSource() == newFile) {
new EditorGUI();
} else if(event.getSource() == openFile) {
JFileChooser open = new JFileChooser();
open.showOpenDialog(null);
File file = open.getSelectedFile();
openingFiles(file);
} else if(event.getSource() == exit) {
System.exit(0);
}
}
It works however when I click on the X at the top right hand corner of the window:
private JFrame createEditorWindow() {
editorWindow = new JFrame("JavaEdit");
editorWindow.setVisible(true);
editorWindow.setExtendedState(Frame.MAXIMIZED_BOTH);
editorWindow.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
// Create Menu Bar
editorWindow.setJMenuBar(createMenuBar());
editorWindow.add(scroll, BorderLayout.CENTER);
editorWindow.pack();
// Centers application on screen
editorWindow.setLocationRelativeTo(null);
return editorWindow;
}
Screenshot:
Don't use multiple frames. An application should only have a single main JFrame.
Then the child window should be a JDialog. A JDialog will only support DISPOSE_ON_CLOSE so you don't have to worry about exiting the application.
This also seems to do the trick:
if(event.getSource() == exit) {
editorWindow.dispose();
}
You could code something like this:
private JFrame createEditorWindow() {
JFrame editorWindow = new JFrame("JavaEdit");
editorWindow.setExtendedState(JFrame.MAXIMIZED_BOTH);
editorWindow.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
editorWindow.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent event) {
exitProcedure();
}
});
// Create Menu Bar
editorWindow.setJMenuBar(createMenuBar());
editorWindow.add(scroll, BorderLayout.CENTER);
editorWindow.pack();
// Centers application on screen
editorWindow.setLocationRelativeTo(null);
editorWindow.setVisible(true);
return editorWindow;
}
public void exitProcedure() {
editorWindow.dispose();
}
You perform the exitProcedure in your JMenuUtem action listener for Exit.
I have a simple game in which I have a JOptionPane popup giving the choice of YES or NO.
So if the user hits NO then the game shuts down ofcourse however if the user hits YES I want the game to restart.
I have got this to work by the following : (Just by calling the main() method again.
main.Main.main(null);
The problem :
It's starting another instance of the game however the previous instead is there as well.
How can I close the previous instance before starting a new instance? or what other ways are there to get around this?
Here is the class code with the JOptionPane
public void popupWinMessage(String message)
{
//default icon, custom title
int n = JOptionPane.showConfirmDialog(
null,
message,
"",
JOptionPane.YES_NO_OPTION);
if(n == JOptionPane.YES_OPTION){
JOptionPane.showMessageDialog(null, "Alright, here we go again");
main.Main.main(null);
}
else {
JOptionPane.showMessageDialog(null, "Thanks for playing the battleships game");
System.exit(0);
}
Here is my updated main method (I'm still pretty confused on what is going on):
package main;
imports
public class Main {
public Controller theController = new Controller(new Game(), new Frame());
/**
* #param args
*/
public static void main(String[] args)
{
newGame();
}
public static void newGame()
{
theController.;
}
}
The directory of my whole game looks like this
http://i.imgur.com/7iKJQwu.png
The method where the JOption pane is located is in the view's Frame class.
public Controller(final Game newGame, final Frame newView)
{
this.game = newGame;
this.view = newView;
this.view.setVisible(true);
//Gets the board arrays into these local variables here for us to use
playerBoard = newGame.DisplayPlayerBoard();
computerBoard = newGame.DisplayCompBoard();
colourGrids();
this.view.addGridActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
Object o = ae.getSource();
if(o instanceof JButton)
{
JButton btn = (JButton) o;
int xValue = (Integer) btn.getClientProperty("row");
int yValue = (Integer) btn.getClientProperty("column");
int tempShipType = computerBoard[xValue][yValue];
newGame.tryHitComputer(xValue, yValue);
btn.setEnabled(false);
if(tempShipType != -1)
{
if(newGame.checkShipStatus(tempShipType) == true)
{
System.out.println(shipDowns[tempShipType]);
newView.popupMessage(shipDowns[tempShipType]);
}
}
//Code here for the computer to try hit your ships
newGame.tryHitPlayer();
colourGrids();
System.out.println(newGame.isGameWon());
if (newGame.isGameWon() == true)
{
System.out.println("Game has been won, do something to stop it at some point");
newView.popupWinMessage("Game has been won\nDo you wish to play again?");
}
if (newGame.isGameLost() == true)
{
System.out.println("Game has been lost, the silly AI has beaten you\nDo you wish to play again?");
newView.popupWinMessage("Game has been lost, the silly AI has beaten you\nDo you wish to play again?");
}
}
else
{
System.out.println("The listener was not attached to a JButton as expected - " + o.getClass());
}
}
});
}
Don't call the main method again. Have a start() method which starts your game and get the dialog to call that when the answer is "yes"
One option is to add a restartGame() method to your Controller class. Since you call popupWinMessage() from the Controller constructor, you can modify it to take a Controller object and pass it the this reference. Then popupWinMessage() method can simply call the restartGame() method on the instance that is passed to it.