import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MyCalculatorGUI extends JFrame implements ActionListener {
JButton tripled, doubled;
JTextField input, output;
JPanel p1, p2;
MyCalculatorGUI() {
Container c = getContentPane();
tripled = new JButton("Triple");
tripled.addActionListener(this);
doubled = new JButton("Doubled");
doubled.addActionListener(this);
input = new JTextField("Input a number here.");
output = new JTextField("Result..");
p1.add(doubled);
p1.add(tripled);
p2.add(input);
p2.add(output);
c.add(p1);
c.add(p2);
setVisible(true);
setSize(400,400);
}
public void actionListener(ActionEvent e) {
}
public static void main(String[] args) {
MyCalculatorGUI output = new MyCalculatorGUI();
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
Eclipse is having a problem with my code where it is MyCalculatorGUI, it says the local variable is not used. Can somebody help me fix this?? I have recently just moved to Eclipse and everything I have tried to fix this isn't working for me.
I think you have created an object and not using it anywhere in main method
MyCalculatorGUI output = new MyCalculatorGUI();
This is just a warning by Eclipse. It cannot see that your actual logic happens inside the constructor - so it thinks you create a new object of your class MyCalculatorGUI inside the main method, but never use it. This could be a sign for unnecessary memory usage/consumption which might be a problem in large projects...
IF you change the line to just new MyCalculatorGUI(); the warning will disappear.
This is not an error, it's just a warning.
It simply means that you have created a variable which is never accessed later in the code. If you don't need it, then don't create it. If you do then just make use of it ;)
MyCalculatorGUI output = new MyCalculatorGUI(); //either delete this line
output.someMethod(); //or use the instance in some way
The warning should dissapear afterwards.
You don't use the variable you created in the main method, so either don't create it, use it or add the following above the main method: #SuppressWarnings("unused")
It's not a problem, it's just an Eclipse information to inform you that your local variable is not used. You can compile with 0 problem!
To resolve the warning you have two solutions:
First:
Implement the variable:
MyCalculatorGUI myCalculator = new MyCalculatorGUI();
Second:
Use the SupressWarnings on the top of your function like that:
#SuppressWarnings("unused")
MyCalculatorGUI() {
Container c = getContentPane();
tripled = new JButton("Triple");
tripled.addActionListener(this);
doubled = new JButton("Doubled");
doubled.addActionListener(this);
input = new JTextField("Input a number here.");
output = new JTextField("Result..");
p1.add(doubled);
p1.add(tripled);
p2.add(input);
p2.add(output);
c.add(p1);
c.add(p2);
setVisible(true);
setSize(400,400);
}
Related
I am learning Java Swing. I am trying to develop as simple app for learning purpose. There is are multiple issues in following code. I try to read a csv file and populate JComboBox on button click.
public class MyForm {
private JButton btnRead;
private JButton btnRead2;
private JComboBox cbCodes;
private JPanel mainPanel;
private DefaultComboBoxModel comboBoxModel;
public MyForm(){
// issue 1: I always get null pointer exception in this line
comboBoxModel = new DefaultComboBoxModel();
cbCodes = new JComboBox(comboBoxModel);
btnRead.addActionListener( e -> {
List<String[]> data = readData();
comboBoxModel.removeAllElements();
data.forEach(item -> comboBoxModel.addElement(item));
});
// issue 2: Since DefaultComboBoxModel was not working. I tried without it. As this I get correct data in the array. But when I make JComboBox with array. Nothing is filled. It is empty.
btnRead2.addActionListener( e -> {
List<String[]> data = readData();
String[] array = new String[data.size()];
data.toArray(array);
cbCodes = new JComboBox(array);
});
}
// issue 3: I can't complie the code without this empty method. Why do I need it?
// error: Form contains components with Custom Create option but no createUIComponents() method
void createUIComponents(){
}
public List<String[]> readData() {
String file = "data.csv";
List<String[]> content = new ArrayList<>();
try(BufferedReader br = new BufferedReader(new FileReader(file))) {
String line = "";
while ((line = br.readLine()) != null) {
if(line.contains("\"")){
content.add(line.split(" "));
}
content.add(line.split(","));
}
} catch (FileNotFoundException e) {
//Some error logging
} catch (IOException e) {
e.printStackTrace();
}
return content;
}
public static void main(String[] args) {
JFrame frame = new JFrame("MyForm");
frame.setContentPane(new MyForm().mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
I make my question in the source code with the comment to show exactly here those issues are involved.
You don't get the NullPointerException in the lines you indicated, but in the line btnRead.addActionListener( e -> { because btnRead has not been initialized yet!
When you create a new JComboBox, you have to add it to the panel, too. Just creating it with new will not display it. But the real problem behind it is: you're using the model wrong. Write
comboBoxModel.removeAllElements();
for (final String string : array) {
comboBoxModel.addElement(string);
}
to solve that.
The problem you have here does not lie within the code you provided, but from another component. At some point, someone used a UI designer. Those designers usually create initialization methods, just like createUIComponents. See where that method gets called.
Synopsis:
All in all, your code is really chaotic. Restructure from new, this will clean up a lot of problems.
And initialize UI components as soon as possible, best do it in the declaration line: private final JButton btnRead = new JButton("Read!");
I strongly recommend using an IDE like Eclipse or IntelliJ that will help you write clean code and see and correct problems easier.
Can anyone guide me on why 'frame.dispose();' doesn't dispose the frame? The other method is called but 'frame.dispose();' is just ignored. This java class is used to check whether a stored answer that is made from another java class (RecoveryQuestion.check()) is the same as the user's input. Public variables such as StoredQuestion and StoredPassword are in the RecoveryQuestion class as well. Furthermore, I'm using Intelli J IDEA GUI form and I don't know how to extract the code, however, the form runs smoothly as intended except with the frame.dispose();
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.io.IOException;
public class ForgotPassword {
private JPanel panel1;
private JTextField answer;
private JLabel Question;
private JButton Submit;
private JFrame frame = new JFrame("Password Reset");
public ForgotPassword() {
Submit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(RecoveryQuestion.StoredPassword.equals(answer.getText())) {
//frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
frame.dispose();
FirstRun.main(null);
}
else JOptionPane.showMessageDialog(null,"Incorrect Answer");
}
});
}
public void setUI() {
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setContentPane(new ForgotPassword().panel1);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(400,250));
frame.pack();
frame.setResizable(false);
}
public static void main(String[] args) {
try{
RecoveryQuestion.Check();
} catch(IOException e1) {}
new ForgotPassword().setUI();
}
private void createUIComponents() {
// TODO: place custom component creation code here
Question = new JLabel();
Question.setText(RecoveryQuestion.StoredQuestion);
}
}
Every call to new ForgotPassword() does just that -- it creates a completely new and unique ForgotPassword instance. Look at your code above, and count how many times that you call this -- I see two times, suggesting that your problem is that you're displaying a JFrame from one of these instances, and trying to dispose of it in another -- two different JFrames that are unrelated to each other.
Suggestions:
Your code is very convoluted with instances creating instances of them self within their self. Simplify.
Create only one ForgotPassword in your GUI and pass it where needed
Side issue: shouldn't this sort of window be a dialog window (i.e., a JDialog) and not an application window (i.e., a JFrame)?
If your code did work as intended, then calling .dispose() on this JFrame should cause the JVM to exit (the entire program to end) since you're setting its default close operation to EXIT_ON_CLOSE.
Side issue 2: your posted code is not a valid MCVE meaning we cannot easily copy the code, paste it into our IDE and compile and run it without modification, making it more difficult for us to fully understand your code and forcing me to guess at your problem. In the future (and now), please consider posting one of these. Note that we do not want to see your entire program, nor should you post a link to a code repository. Instead keep it small, keep it simple, and make it functioning.
I've programmed a DLL in C. The first function sends a pointer of the callback function that is called when new data is available.
So I use JNA to wrap this function.
In order to avoid the end of the app, I use an InputStreamReader that wait data from the standard input. And when new data are available the callback is called and data are printed in the console.
But, if I use a JFrame to avoid the end of the program before closing the window, it doesn’t work properly. In fact, if I don’t resize the JFrame window, the callback is called about 30 times and after that nothing (even if new data are available). If I resize the window, the callback if never called (even if new data are available).
Please could you help me?
Thanks
Edit : This is my main method.
package jsigmausblib;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import javax.swing.JFrame;
public class JSigmaUSBLib {
public static void main(String[] args) {
NativeSigmaUSBLibInterface nsuli = (NativeSigmaUSBLibInterface) Native.loadLibrary("SigmaUSBLib1.0", NativeSigmaUSBLibInterface.class);
ReadCallback rc = new ReadCallback() {
#Override
public void callbackFunction(Pointer readData, byte len) {
System.out.println("ok"+readData.getByte(0));
}
};
SigmaUSBLibConfigStruct.ByValue config = new SigmaUSBLibConfigStruct.ByValue();
nsuli.SigmaUSBLibInit(rc , config);
JFrame frame = new JFrame("Debug");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(80, 60);
frame.setVisible(true);
}
}
statsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
//Return the string "stats" to gameLoop() as cmd
}
});
public void gameLoop(){
Scanner lineScanner = new Scanner(System.in);
cmd = "";
System.out.print(getBoard().printBoard(false));
while (!cmd.equals("quit")) {
System.out.print(">");
Scanner wordScanner = new Scanner(lineScanner.nextLine());
if (wordScanner.hasNext()) {
cmd = wordScanner.next();
if (cmd.equals("board")) {
System.out.print(getBoard().printBoard(false));
} else if (cmd.equals("ships")) {
System.out.print(getBoard().printBoard(true));
} else if (cmd.equals("help")) {
printHelp();
} else if (cmd.equals("stats")) {
printStats();
} else if (cmd.equals("fire")) {
if(fire(wordScanner)) {
printStats();
cmd = "quit";
}
} else if (cmd.equals("quit")) {
} else if (!cmd.equals("")) {
System.out.println(ILLEGAL_COMMAND);
}
}
}
}
What I'm trying to do is that when the user clicks the statsButton, the String cmd in the gameLoop would be changed to "stats". The statsButton and the gameLoop() are located in two different classes. Anyone can give me an idea how to do it? (I've attempted pipedreader/pipedwriter) and I just can't seem to get it right.
*I'm basically trying to make my console application into a GUI application without changing the original console application.
Edit: What I've tried
Class textBased
PipedInputStream in = new PipedInputStream()
public void gameLoop(){
try{
in.connect(GUIclass.out);
Scanner lineScanner = new Scanner(in);`
Class GUIclass
PipedOutputStream out = new PipedOutputStream();
PrintWriter writer;
public GUIclass(){
final PrintWriter writer = new PrintWriter(out);
statsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
writer.println("stats");
}
});
that's what I tried writing but it doesn't seem to work.
Regarding
I'm basically trying to make my console application into a GUI application without changing the original console application..."
My advice is simple: "don't do it".
The two applications have completely different structure, one being linear, the other being event-driven, and are not directly translatable to each other. Better to make a new GUI program from the ground up. Now if your non-GUI application contains some well-structured and behaved object-oriented classes, then by all means use those classes in your GUI's "model" or logic section, but don't try to directly translate the program flow of one type of application to the other.
Edit
Based on your posted requirements:
"You should be able to play your Battleship game through your GUI interface. In addition, the text-based front-end you wrote for project 1 should still "work" and be playable."
Correct me if I'm wrong, but I'm betting that you have several classes involved here, and only one of them is the "text-based front-end". If so, then use the non front-end classes as the model of your GUI as I suggested above, but do not use the text-based front-end for anything GUI related, and do not try to emulate it in your GUI.
Have the console application instantiate the button ActionListener and pass it to the UI. When the action event is fired, the listener will tell the console app that it happened. The method in the ActionListener will tell it what to do.
I agree with Hovercrafts comment (changed to a reply).
But in general for problems like this I would change the method signature of your gameLoop(). I would use:
public void gameLoop(Reader reader)
Then you can pass different types of readers to the loop depending on the requirement.
For a console you might do something like:
gameloop( new InputStreamReader( System.in ) );
For a GUI you could do something like:
gameLoop ( new StringReader("some text") );
Edit:
Without changing the method signature you can redirect System.in to come from the String retrieved by the ActionListener:
public class Test
{
public static void main(String args[]) throws Exception
{
String text = "some text";
System.setIn( new ByteArrayInputStream( text.getBytes() ) );
// gameloop();
Scanner lineScanner = new Scanner(System.in);
System.out.println( lineScanner.nextLine() );
}
}
If you have something like this :
class B {
public void gameLoop(){
..
}
}
and
class A{
statsButton.addActionListener(new ActionListener() {
...
});
}
You can declare reference to B in A with final . In that case it's will be visible in inner class ActionListener.
class A{
final B b = ...; //final variable is visible in inner class
statsButton.addActionListener(new ActionListener() {
b.gameLoop();
...
});
}
i write a method to create a form(3 buttons and a textBox), then i call it in main.
but when i run program, before i enter information in the form (method form6 ),
Other commands that are executed! "s4 and ontname chenged in the form".
this is a part of my code:::::::::::
//////////////////////////////////////////////////////////////////////////
public static void main(String[] args) {
System.out.println("*begin main*"); // call form method
String s4= form6(); // s4 is returned by method.
System.out.println("s3333*"+s4);
System.out.println("ont:"+ontname);//it's global }
//////////////////////////////////////////////////////////////////////////
i have 2 questions:::
1--- While the form is running, other commands are executed!
What is their order execution?
2. --- i want to define a button to when i click it,it closes the form.
thanks all.
If I get your code correctly, ontname is either (1) a class member (declared outside a method) or (2) a local variable, which is declared in the method that contains this code snippet.
In both cases there is no need to "return" ontname just because it is not declared inside the anonymous ActionListener instance.
The following example illustrates a typical pattern for this problem:
public void someMethod() {
// ...
button2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String filename = File.separator+"c:";
JFileChooser fc = new JFileChooser(new File(filename));
fc.showOpenDialog(null);
File selFile = fc.getSelectedFile();
setOntName(selFile.getPath()); // <-- here we call another method
}
});
// ...
}
void setOntName(String ontName) {
// do something with ontName
}
Alternativly: declare ontName as a static class member (only):
private static String ontName = ""; // <-- accessible from main method
public static void main(String[] args) {
// ...
}
// more methods.
You can't return a value in this Method because the ActionListenerInterface does not allow this. But you can call another method from within the actionPerformed() method and pass the ontname to it.
You can also close the third button in the new method. Or define the third button as final and use it in the actionPerformed() method.
E.g.
button2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String filename = File.separator+"c:";
JFileChooser fc = new JFileChooser(new File(filename));
fc.showOpenDialog(null);
File selFile = fc.getSelectedFile();
ontname=selFile.getPath();
System.out.println("filepath: "+ontname); //it works correctly.
anotherMethod(ontname);
}
});
private void anotherMethod(String path) {
//doSomething with the path
//close third button here
}
You could probably define your variable ontname as global, outside of your function:
var ontname = null;
button2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
// ...
ontname=selFile.getPath();
}
});
// ...
System.out.println("filepath: "+ontname);
If you want to remember the values, then they should be class level variables.
But, generally, you would want to pass these to some other method to do some processing on them (or, say, persist them in a file). You can pass these as parameters to the other method.
(The second one is better in most cases, I don't know much about your app, so I am unable to give one answer)
There are other problems with your code:
You need to check whether the use has clicked the "Ok" or "Cancel" button in the open dialog to decide whether to get the file or not.
String filename = File.separator+"c:"; does not really make sense. Perhaps you meant String filename = "c:"+File.separator; But even this is not very useful. File.separator is for getting the platform specific file separator char (\ in Windows, / on linux) but since you are hard coding c:, you are anyway constrainting your app to Windows. You might want to have a better platform independent way (start at the "default" path, new JFileChooser() without arguments, and then remember the path the user last used, and proceed from there)
If the argument to the showOpenDialog method is your parent frame, then the dialog would be centered on the parent frame, and would, in most cases, look nicer.
You might also want to relook your variable names.
button2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String filename = File.separator+"c:";
JFileChooser fc = new JFileChooser(new File(filename));
int option = fc.showOpenDialog(null);
if(option = JFileChooser.APROVE_OPTION)
{
File selFile = fc.getSelectedFile();
String ontname=selFile.getPath();
System.out.println("filepath: "+ontname); //it works correctly.
doSomeOperation(ontname); //Or, declare ontname as a class level variable.
}
}
});