When I put in the code below I get the error: "local variable classWindow is accessed from within inner class; needs to be declared final."
classWindow.dispose();
I did put:
private final void classWindow
and I still get the error.
private final void classWindow() {
// Create the frame
JFrame classWindow = new JFrame("Pick A Class");
// Set the size of the frame
classWindow.setSize(230, 150);
// Specify an action for the close button.
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Add a layout manager to the content pane.
setLayout(new GridLayout());
JButton warriorButton = new JButton("Warrior");
warriorButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
userClass = "Warrior";
classWindow.dispose();
}});
classWindow.add(warriorButton, BorderLayout.WEST);
classWindow.setLocationRelativeTo(null);
classWindow.setVisible(true);
}
Yes, I did look it up and that's why I tried the 'final' thing and it doesn't seem to work on my code for some weird reason. I'm sure it is a very simple fix.
The ultimate reason is confusing way to name variables and methods. The error is referring to the variable, which need to be final:
final JFrame classWindow = new JFrame("Pick A Class");
I would seriously recommend also picking a different name for it.
Related
"This method creates an object but does not assign this object to any variable or field. This implies that the class operates through side effects in the constructor, which is a bad pattern to use, as it adds unnecessary coupling. Consider pulling the side effect out of the constructor, into a separate method, or into the calling method."
This short test program runs as I expected, but I don't know how to address this checkstyle error. Most of the examples of using javax.swing seem to have this structure.
There is also a error causes by EXIT_ON_CLOSE, but without it the process lingers after I close the window and must be force quit.
public class GUI implements ActionListener {
private int clicks = 0;
private JLabel label = new JLabel("Clicks= " + clicks);
private JFrame frame = new JFrame();
public GUI() {
// make a Jbutton named button
JButton button = new JButton("Click Me");
button.addActionListener(this);
// arrange the button and label
JPanel panel = new JPanel();
panel.add(button);
panel.add(label);
// put the panel in a frame
frame.add(panel, BorderLayout.CENTER);
// EXIT_ON_CLOSE has a style error too.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Graphical User Interface");
frame.pack();
frame.setVisible(true);
}
// update label and number of clicks when button is clicked
public void actionPerformed(ActionEvent e) {
clicks++;
label.setText("Clicks= " + clicks);
}
// This is the code that InteliJ says has bad form.
public static void main(String[] args) {
new GUI();
} }
One bad pattern here is that you are not creating your GUI on Event Dispatch Thread. Not sure if this is related to your problem.. but you should always use EDT to create the GUI in Swing.
EDIT: take a look here. In the main method you just have "new GUI()" without a reference variable. Writing your app like this example you are not going to use the constructor to create all :)
I have a frame with a combo box that displays different shapes and a button, for the button I added an action listener which will get the selected item from the combo box and store it as a string which i declared as a public class variable, in my main method i want to access this string to make a finch robot draw that shape but I can't seem to access it no matter what I try
public class DrawShape
{
private JFrame frame;
private String[] choices = {"circle", "square", "triangle", "rectangle", "quit"};
public String choice = "";
//class constructor
public DrawShape()
{
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
JPanel p = new JPanel();
final JComboBox cb = new JComboBox(choices);
JButton button = new JButton("Done");
p.add(cb);
p.add(button);
frame.add(p);
//create an action listener that, when button is clicked, gets the selected choice and stores it to
//the string variable 'choice'
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
choice = (String)cb.getSelectedItem();
}
}) ;
frame.pack();
}
public static void main(String[] args)
{
new DrawShape();
System.out.println(choice);
}
}
I wouldn't recommend the use of non-private variables. However, you need to keep a reference to the object you created and then access the fields through that reference as if you were calling methods on an object.
DrawShape draw = new DrawShape();
System.out.println(draw.choice);
However, you should see null as this is called immediately after you construct the object rather than from the listener.
You probably want the code executed from the listener. So either put the print code in the listener, or have the listener call another method with that in.
GUI programming tends to be event driven. Don't expect to be able to sequence the user interaction - the user drives.
you should use getters/setters in this case. Your action listener would call the getter method which would in turn get what is in the combobox.
Here is an example of how that works: https://www.codejava.net/coding/java-getter-and-setter-tutorial-from-basics-to-best-practices
Hope this helps.
I'm working through a book, and the following code throws a NPE at runtime when the JButton is clicked, at the line button.actionPerformed. I've done my best to be sure my code is exactly what is in the book, can someone point out my problem? (the book was written for java 5, I'm using the latest java 7, this shouldn't make a difference in the following code as far as I know though)
import javax.swing.*;
import java.awt.event.*;
public class SimpleGui implements ActionListener {
JButton button;
public static void main(String[] args) {
SimpleGui gui = new SimpleGui();
gui.go();
}
public void go() {
JFrame frame = new JFrame();
JButton button = new JButton("click here");
button.addActionListener(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(button);
frame.setSize(300,300);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
button.setText("I've been clicked, argh!");
}
}
The reason is this Line:
JButton button = new JButton("click here");
Here you are creating new local JButton object which is shadowing the member variable button . Hence button is still null. You should instead use:
button = new JButton("click here");
In a method, you have this:
JButton button = new JButton("click here");
This create the variable, but the scope of this new variable is inside the method. You've already declared button in your class though. It should just be:
button = new JButton("click here");
You're shadowing your variables.
You declare button as a class variable, but the re-declare within your go method, meaning that the class variable (which you reference within your actionPerformed method) is null
Change JButton button = new JButton("click here"); to button = new JButton("click here");
Well, your JButton button; is still null.you are not assigned it anywhere in your programm
This problem is known as "Variable Hiding" or "Hidden Variables" or "Shadowing Variables". Which means, a local variable hides another variable which has the same name. You have re defined your variable button inside the go method. Just removed the re definition from the go method, so it will work fine. Have a look at the following code
import javax.swing.*;
import java.awt.event.*;
public class SimpleGui implements ActionListener {
JButton button;
public static void main(String[] args) {
SimpleGui gui = new SimpleGui();
gui.go();
}
public void go() {
JFrame frame = new JFrame();
button = new JButton("click here"); //Variable Re definition removed
button.addActionListener(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(button);
frame.setSize(300,300);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
button.setText("I've been clicked, argh!");
}
}
Since you seems to be new to the Java GUI, take the following few advises.
It is always a best practice to define your class variables inside the constructor
Use access specifiers. private is a good specifier for your button variable
Even though the constructor can be automatically get created (default constructor) it is a best practice to code it by your self, at least a blank one.
I am asking this question due to mKorbel's second comment on this question. I have been using this keyword to call local variables, local components of that class (example Buttons) and methods e.t.c. I am not sure what is wrong with using the keyword the way I have been doing it.
don't to use this.whatever in Swing, Java, (in MCV make me some sence), use local variables insted of.
Question: What is wrong with using this.XXX in Swing?
Sample Code
public class SwingTest extends JFrame {
// variables
private String st = "You clicked me";
SwingTest() {
this.initUI();
}
private void initUI() {
this.setTitle("Swing Test");
this.setSize(200, 200);
this.setLayout(new BorderLayout());
this.setVisible(true);
this.clickMe = new JButton("Click"); // What is wrong with using this
// ref here?
this.add(clickMe);
this.clickMe.addActionListener((ActionEvent) -> {
JOptionPane.showMessageDialog(this, this.st);// What is wrong with
// using this ref
// here?
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
SwingTest swingTest = new SwingTest();
}
});
}
// components
JButton clickMe;
}
The button clickMe does not need to be a field. It can be a local variable JButton clickMe inside the dialog defining method/constructor. As normally many GUI components are created and added to the window, it cleans up the class, keeps declarations close to usage, and leaves the life-time as short as possible (on changing window contents).
(The talk about this is merely to point out the fieldness of clickMe.)
I have class main extends jframe, it has a button that calls /shows another class that extends jdialog.
If the button from jdialog is triggered, it will dispose that dialog and will remove all component of jframe, then add it to a new jpanel.
What should I do?
Here's my new broken code:
public class mainz extends JFrame{
mainz(){
setVisible(true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
JToolBar r = new JToolBar();
r.add(Box.createHorizontalGlue());
add(r, BorderLayout.NORTH);
JButton n = new JButton();
r.add(n, BorderLayout.EAST);
n.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae){
show();
}
});
}
public void show(){
dialogz d = new dialogz(this);
d.setVisible(true);
}
public void lastHope(){
getContentPane().removeAll();
getContentPane().validate();
getContentPane().repaint();
}
public static void main (String[]args){
new mainz().setExtendedState(MAXIMIZED_BOTH);
}
}
public class dialogz extends JDialog{
public dialogz(final mainz owner) {
setSize(300, 300);
JButton n = new JButton("execute");
add(n);
final JFrame ew = (JFrame)super.getOwner();// <<
n.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae){
dispose();
//owner.lastHope;
ew.removeAll();// <<
ew.validate();// <<
ew.repaint();// <<
}
});
}
void yes(){
getOwner().removeAll();
getOwner().validate();
getOwner().repaint();
}
}
I know I can prevent my main class from extending jframe, and call it from main instead, but I want to do it like that...
Please help me ... T-T
Sorry for my English, I from a far away country ~,~"
update:
the error is
java.lang.ClassCastException: javax.swing.SwingUtilities$SharedOwnerFrame cannot be cast to javax.swing.JFrame
it will be done with delete the line that contain
// <<
then call lastHope();
but i think there's a another way to get that existing jframe to removeall
(by casting it first or something ~,~" )
You are calling getParent() but you never set the parent (or owner). That should happen in the constructor as already pointed out. Also, be mindful that getParent() returns a Container object and getOwner() returns a Window object. Both of these refer to the JFrame which is the parent and owner. If you want to use it as a JFrame, you'll have to cast the output as (JFrame). But removeAll() is in Container class so if that's all you want, there'll be no need for casting.
Update:
JFrame frame = new JFrame();
JDialog dialog = new JDialog(frame);//frame is owner
JFrame parentOfDialog = (JFrame)(dialog.getParent());
//OR
//JFrame parentOfDialog = (JFrame)(dialog.getOwner());
parentOfDialog.removeAll();
If you are using your custom class, pass JFrame in the constructor and call super.
Please read the javadoc on JDialog before you try to use it. Also, read more about inheritance.
I'm not clear on what your goal is, but if you want to change the components that are displayed in a container, such as a JFrame or JDialog's contentPane, then I recommend that you use a CardLayout to do this since it allows you to easily swap "views".
There could be two ways to do this:
Your JDialog class could use a reference to the JFrame that is passed in via its constructor (and you should then pass it immediately into the dialog's super constructor so that your modality will work correctly). You could then call any public methods in the JFrame's class.
Or since the JDialog is modal, the JFrame's code will halt while the dialog is visible. You could swap "views" immediately after the dialog has been disposed of and is no longer visible. this would keep the JFrame manipulating code in the JFrame class.
Edit: note that if you don't use CardLayout, then you're responsible for calling revalidate() and repaint() on any container who gets its components changed.
As an aside: since English is not your first tongue and nor is it the native language of many folks on this forum, please avoid using non-standard abbreviations. The clearer your communication with us, the easier it will be for us to understand you and help you.