I wrote a simple application in Swing that writes text to a file. Here is my main class:
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class WritingTextToFileApp {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new MainFrame("Application");
frame.setSize(500, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
Here is the other class:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
public class MainFrame extends JFrame {
public MainFrame(String title) {
super(title);
//Set Layout Manager
setLayout(new BorderLayout());
//Create Swing Components
JTextArea textArea = new JTextArea();
JButton button = new JButton("Add");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
File file = new File("C:\\Users\\Vincent Wen\\Desktop\\Test.txt");
try (BufferedWriter br = new BufferedWriter(new FileWriter(file))) {
br.write(input);
br.newLine();
} catch (IOException ex) {
System.out.println("Unable to write to file:" + file.toString());
}
}
});
//Add Swing components to conent pane
Container c = getContentPane();
c.add(textArea, BorderLayout.CENTER);
c.add(button, BorderLayout.SOUTH);
}
}
Whenever I press the button, the program freezes and nothing happens. Is there something wrong with the code? I am new to Swing so any help would be appreciated.
Swing runs the actions synchronously in the same thread that's handling the GUI input and rendering. That means that when you click the button, it waits for the action listener to complete running before it goes back to handling input and drawing the GUI. In this case, it's effectively stopping the GUI from running until you type something into the console.
You can use SwingWorker to run it asynchronously so that it continues running the GUI while it runs the action.
The problem is that when you press the button, java expects to read data from System.ini (console).
Try to start your application by using the java command on a console. Then enter some text in the console after pressing the button and press enter. Your program you work.
I fixed my problem by using textArea.getText() instead of using scanner.
Related
I wrote a simple application in Swing that writes text to a file. Here is my main class:
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class WritingTextToFileApp {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new MainFrame("Application");
frame.setSize(500, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
Here is the other class:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
public class MainFrame extends JFrame {
public MainFrame(String title) {
super(title);
//Set Layout Manager
setLayout(new BorderLayout());
//Create Swing Components
JTextArea textArea = new JTextArea();
JButton button = new JButton("Add");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
File file = new File("C:\\Users\\Vincent Wen\\Desktop\\Test.txt");
try (BufferedWriter br = new BufferedWriter(new FileWriter(file))) {
br.write(input);
br.newLine();
} catch (IOException ex) {
System.out.println("Unable to write to file:" + file.toString());
}
}
});
//Add Swing components to conent pane
Container c = getContentPane();
c.add(textArea, BorderLayout.CENTER);
c.add(button, BorderLayout.SOUTH);
}
}
Whenever I press the button, the program freezes and nothing happens. Is there something wrong with the code? I am new to Swing so any help would be appreciated.
Swing runs the actions synchronously in the same thread that's handling the GUI input and rendering. That means that when you click the button, it waits for the action listener to complete running before it goes back to handling input and drawing the GUI. In this case, it's effectively stopping the GUI from running until you type something into the console.
You can use SwingWorker to run it asynchronously so that it continues running the GUI while it runs the action.
The problem is that when you press the button, java expects to read data from System.ini (console).
Try to start your application by using the java command on a console. Then enter some text in the console after pressing the button and press enter. Your program you work.
I fixed my problem by using textArea.getText() instead of using scanner.
As part of learning SwingWorker on Java swing I created a simple program where a different thread(Other than EDT) is doing some background task and once thats done that thread is updating GUI component (JTextArea).
As I understand if we try to update GUI components from an outside thread ,other than EDT , then UI might get freezed. But this is not happening. I really would like to create that situation(Freeze UI) so as to understand it better. Below is my code that I tried. Can some one help me saying what I need to do on my code so that UI is getting freezed.
App.java
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class App {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MainFrame();
}
});
}
}
MainFrame.java
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class MainFrame extends JFrame implements ActionListener {
private JButton btn,btn2;
private JTextArea txtArea;
public MainFrame() {
super("Hello World");
setLayout(new BorderLayout());
btn = new JButton("Click Me!");
btn2 = new JButton("Click Me New!");
txtArea = new JTextArea();
btn.addActionListener(this);
add(txtArea,BorderLayout.CENTER);
add(btn,BorderLayout.SOUTH);
add(btn2,BorderLayout.NORTH);
setSize(600,800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
MyTestThread extThr = new MyTestThread();
extThr.setBtnRef(txtArea);
extThr.start();
}
}
MyTestThread.java
import javax.swing.JTextArea;
public class MyTestThread extends Thread {
private int i = 0;
private JTextArea txtAreaRef;
public void setBtnRef(JTextArea ta) {
this.txtAreaRef = ta;
}
public void run() {
while (i < 500000) {
try {
txtAreaRef.append("test"+i+"\n");
i=i+1;
sleep(2000);
} catch (InterruptedException e) {System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
}
I have no idea where you got that information from, but calling GUI updates outside of the EDT do not cause UI freezing.
If you want to produce a freeze, try making an infinite loop inside the EDT, like this.
This will cause the UI to permanently freeze.
public void actionPerformed(ActionEvent e) {
//MyTestThread extThr = new MyTestThread();
//extThr.setBtnRef(txtArea);
//extThr.start();
while(true) {}
}
I've been trying to make it so my button will close out of the frame on click but it never does anything. I've looked through several stackoverflow threads but none of them seems to work on my this.. here is what I have so far
JButton start = new JButton("Start");
start.setBounds(251, 216, 119, 23);
start.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent evt) {
try {
int hpToEat = Integer.parseInt(GUI.textField.getText());
Frost.hp = hpToEat;
} catch(NumberFormatException nfe) {
GUI.textField.setText("");
}
setVisible(false);
}
});
contentPane.add(start);
I have tried making a closeFrame method which uses super.dispose(); and I've also tried system.exit(0);
Does anyone have any idea as to why My button won't do What i want it to do?
Someone requested the rest of my code so here it is:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JCheckBox;
import javax.swing.JTextField;
import javax.swing.JButton;
public class GUI extends JFrame{
private JPanel contentPane;
public static JTextField textField;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GUI frame = new GUI();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public GUI() {
//LABELS ===================================================================================================
The problem is that GUI.textfield is not what you think it is. You're shadowing the field here:
JTextField textField = new JTextField();
That creates a local variable by the name textField, it does not set the static field you're using in the action listener. A quick fix would be writing just:
textField = new JTextField();
However, I recommend getting out of the habit of using static fields. That approach does not scale. Furthermore, don't use absolute positioning. It leads to no end of trouble (just browse a few questions in the swing tag for examples). Learn to use layout managers right from the start.
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
I have a game that uses a JFrame that displays the game info. The window updates whenever a player sends a move object to the server. It works perfectly fine for any number of move objects. However once the 3nd turn starts it hits a wall and here is what happens:
The Jframe completely stops responding to left and right mouse clicks (it makes a windows ding sound when you try to click)
The JFrame still responds to mouse scrolls and keyboard inputs
The JFrame vanishes from the alt-tab program list.
NO error message or stack trace.
Using souts it appears that the code reaches all points of necessary code properly
I can't even click the "X" Window button or right-click close on the task bar
The 3rd turn object is structurally identical to previous turn objects
what on earth can cause a program to do this??
The event dispatch thread has thrown an exception. It is automatically restarted, but your program remains in the state you describe. See also How can I catch Event Dispatch Thread (EDT) exceptions and this answer.
Addendum: How uncaught exceptions are handled and Uncaught exceptions in GUI applications may be helpful. Also check for empty exception handlers.
Addendum: Here's an example.
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
/** #see https://stackoverflow.com/a/9935287/230513 */
public class Fail extends JPanel {
private static final JLabel label = new JLabel(
"12345678901234567890", JLabel.CENTER);
public Fail() {
this.setLayout(new GridLayout(0, 1));
this.add(label);
this.add(new JButton(new AbstractAction("Kill me, now!") {
#Override
public void actionPerformed(ActionEvent e) {
JButton b = (JButton) e.getSource();
b.setText(String.valueOf(1 / 0));
}
}));
new Timer(100, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
label.setText(String.valueOf(System.nanoTime()));
}
}).start();
}
private void display() {
JFrame f = new JFrame("Example");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Fail().display();
}
});
}
}
Check if your frame class do not overrides isEnabled() method.
I spent couple of hours searching for exception but the responce was pretty trivial: I have implemented interface with such method.