Java, NetBeans IDE and JTextField - java

it's a shame that my first question on SO is so stupid but i can't manage to get around this thing.
After hours of "distilling" i have reduced the issue to this:
Using Netbeans i've made a JFrame, and put a Jbutton1 and a JTextField(named sinonimo) in it.
The idea is to use the text field to grab user input. so i set the onClick action of the button like this
private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {
System.out.println(sinonimo.getText());
}
Problem is: i can type anything in the text field, the getText() method will return only the string set in the "text" properties in Netbeans, it will never change.
Am i missing something huge about java? can someone point me in the right direction?
EDIT: while copying the complete code i found the problem: in the constructor of the frame, initComponents() was called two times, generating another copy of the textfield inaccessible from the MouseClicked event(i think). Now everything seem to work nicely, thank you guys for the lighting responses!

Using a JTextField, if you call getText() it will return null should the index be out of range or the Document is null. If you could post more code I could help further with this issue. With the following code this works perfectly fine.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Test {
public static void main(final String[] args) {
final JFrame frame = new JFrame();
final JButton button = new JButton("Print");
final JTextField field = new JTextField();
frame.setLayout(new BorderLayout());
frame.add(button, BorderLayout.NORTH);
frame.add(field, BorderLayout.SOUTH);
frame.setVisible(true);
frame.pack();
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(field.getText());
}
});
}
}
From what I can see, until you post more code, is that either the method you print it from is not being used, the document is returning null or that the sinonimo instance was not added correctly and doesn't function how it should.

Related

Cannot refer to the non-final local variable display defined in an enclosing scope

This might be a very basic question. But I am stuck at this. The error that I get for the String variable display states:
Cannot refer to the non-final local variable display defined in an enclosing scope.
If I use a final keyword, I get the message:
The final local variable display cannot be assigned, since it is defined in an enclosing slope.*
The code is:
public class Frame {
public static void main(String[] args) {
String display=" ";
Frame ob=new Frame();
JFrame frame=new JFrame("Test");
frame.setBounds(300,100,800,500);
//Container c=frame.getContentPane();
frame.setLayout(null);
final JTextField name=new JTextField();
name.setBounds(500,212,150,20);
JLabel nameLabel=new JLabel("Name: ");
nameLabel.setForeground(Color.WHITE);
nameLabel.setBounds(450,171,100,100);
JTextField ohr=new JTextField();
ohr.setBounds(500,282,150,20);
JLabel ohrID=new JLabel("OHR ID: ");
ohrID.setForeground(Color.WHITE);
ohrID.setBounds(450,241,100,100);
final JButton button=new JButton("Submit");
button.setBounds(530,350,90,20);
frame.add(name);
frame.add(ohr);
frame.add(ohrID);
frame.add(nameLabel);
frame.add(button);
frame.getContentPane().setBackground(Color.DARK_GRAY);
frame.setVisible(true);
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(e.getSource()==button){
display=name.getText();
JOptionPane.showMessageDialog(null, "Hi "+ display);
System.exit(0);
}
}
});
}
Thanks in advance!
There are multiple issues with your code, and we'll address them right here, right now and solve your problem at the same time.
public class Frame { this particular line has an error, Frame is the name of an AWT class, so it might confuse you or anyone who reads this code later on, give it a more meaningful name and avoid those names that could be confused with other Java packages.
Frame ob=new Frame(); you create an instance of your class and never use it again, why?
frame.setLayout(null); NEVER, please don't use null-layout, Swing has to deal with multiple PLAFs, screen sizes and resolutions, different OS, pixel perfect apps might seem like the easiest way to create complex UIs but later on you'll find that errors like this happen very often.
.setBounds(...) on every component, again, this is due to null-layout but it's better to use Layout managers
final JTextField name=new JTextField(); There's no need to declare any of your components as final, this is due to a poor design of your class, your components should be declared as class members (outside any method including main).
Speaking about main, separate your program into smaller pieces, don't throw everything at main or at the very least create a method that is not static so you can call it after creating an instance of your class (or else later on you'll end up with tons of static variables and that's a poor design of your class once again).
System.exit(0); it will stop the JVM, it's never a good idea to do that, it's better to .dispose() the JFrame and have your JFrame's defaultCloseOperation set to EXIT_ON_CLOSE which will safely dispose your app and then stop the JVM.
display=name.getText();, for this particular case, display could be an inner variable rather than a class member. This will solve your particular question
JOptionPane.showMessageDialog(null, "Hi "+ display); that null should be a reference to your JFrame, this will place your dialog in the middle of that JFrame rather than in the middle of the screen.
You never place your program inside the EDT, see point #2 in this answer.
So, having all the above points in mind, here's an improved version of your code.
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class UsingVariablesInsideActionListenerExample {
//We declare our components here
private JFrame frame;
private JButton button;
private JTextField name;
private JTextField ohr;
private JLabel nameLabel;
private JLabel ohrID;
private JPanel pane;
private JPanel namePane;
private JPanel ohrPane;
public static void main(String[] args) {
SwingUtilities.invokeLater(new UsingVariablesInsideActionListenerExample()::createAndShowGUI); //This is using Java 8 lambdas to place your program in the EDT
}
private void createAndShowGUI() {
frame = new JFrame("Test"); //Create your JFrame
pane = new JPanel();
pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS)); //This will make this JPanel to arrange components vertically
namePane = new JPanel(); //By default, JPanels have FlowLayout which will arrange components horizontally
ohrPane = new JPanel();
name = new JTextField(10); //We create a JTextField with 10 columns
nameLabel = new JLabel("Name: ");
nameLabel.setForeground(Color.WHITE);
ohr = new JTextField(10);
ohrID = new JLabel("OHR ID: ");
ohrID.setForeground(Color.WHITE);
button = new JButton("Submit");
//Add the action listener
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button) {
String display = name.getText(); //The display variable is now an inner variable rather than a class member
JOptionPane.showMessageDialog(frame, "Hi " + display);
frame.dispose(); //We dispose the JFrame and it will be closed after due to EXIT_ON_CLOSE below.
}
}
});
//We add the components to the namePane (horizontally), the order matters
namePane.add(nameLabel);
namePane.add(name);
//Now we add these components to the ohrPane (horizontally again)
ohrPane.add(ohrID);
ohrPane.add(ohr);
//We then add the name and ohr panes to a bigger JPanel (pane, which if you remember will add them vertically) and we add the button at the end
pane.add(namePane);
pane.add(ohrPane);
pane.add(button);
//We make them non opaque (transparent) so that we can see the background color of the JFrame
namePane.setOpaque(false);
ohrPane.setOpaque(false);
pane.setOpaque(false);
frame.add(pane);
frame.getContentPane().setBackground(Color.DARK_GRAY);
frame.pack(); //This will get every component's preferred size and make the JFrame as small as possible where it looks good on every OS, PLAF, screen size and resolution.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true); //We make the frame visible (always at the very end, when we've added everything to it).
}
}
And this is how it looks like now.
The UI may not be perfectly equal to the one you have, but I'm sure you can play with the different layout managers, and nest various JPanels to get a much better looking UI than mine, or at least a more similar one to the one you had.
Variable used in side an inner class should be effectively final . You can use a string[] of length 1 instead of string to resolve this . Please read bellow post for more details
Difference between final and effectively final
Also check this post for more details
Variable used in lambda expression should be final or effectively final

How to update components listening a button in java

I am a bit sorry to ask this question, since it seems to be a bit obvious, but I can't find my solution alone.
I am coding a little app in Java, and I encounter some issues "redrawing" my swing components. Basically, I want my JFrame to update when an event occurs. I managed to reproduced the issue in the code below. This code is supposed to display two buttons (which it does), and replace them with a third button when you click on the first button (which it doesn't).
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Example extends JFrame implements ActionListener {
private JButton button = new JButton("Button 1");
private JButton button2 = new JButton("Button 2");
private JButton button3 = new JButton("Button 3");
private JPanel buttons = new JPanel();
public void init() {
this.setVisible(true);
this.setSize(500,500);
buttons.add(button);
buttons.add(button2);
this.add(buttons);
this.button.addActionListener(this);
}
public void update() {
this.removeAll();
buttons.add(button3);
this.revalidate();
}
public static void main(String[] args) {
Example ex = new Example();
ex.init();
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == button) {
update();
}
}
}
I am pretty sure that I am doing something wrong in the update() method. I actually have a lot of trouble to understand how works removeAll(), revalidate(), repaint() etc, and I guess that is the problem. I tried to call the same methods on the buttons panel, it almost worked but I still have a graphic bug, and I would like to do it for all the container. I also tried to call these methods on this.getContentPane(), but it doesn't work.
Can anyone try to help me with it?
You're removing all components from this (which in this case is the JFrame (as you're extending it, which isn't needed, and instead you should create an instance from it rather than inherit from it, as you're not changing the behavior of the JFrame so it's better to just create an instance of it). See: Extends JFrame vs. creating it inside the program
In this case you're adding your components in this way:
JFrame > buttons (JPanel) > JButtons
And you're trying to remove
JFrame > everything
That includes the contentPane, instead you should call.
buttons.removeAll()
Inside the update() method.
And also call this.repaint() so your update() method should become:
public void update() {
buttons.removeAll();
buttons.add(button3);
this.revalidate();
this.repaint();
}
Or the best approach is to use CardLayout as recommended by #AndrewThompson in the comment below. This way you don't have to handle removing / repainting for each component, as CardLayout will do it for you. For example
this works,
public void update() {
buttons.remove(button);
buttons.remove(button2);
buttons.add(button3);
this.revalidate();
this.repaint();
}

AS3 - Button Click + Number

What I'm trying to do is create a very basic button click game much like "AdVenture Capitalist" and several other casual games like it. Nothing quite as fancy. I'm using FlashDevelop (AS3) and I'm trying to figure out how to create a button then every time that button is pressed it adds +1 to my main value represented on screen.
I'd also like to figure out how to make a button that would automate the clicking process.
If anyone could show me how, or direct me to a specific page that would help me out I would be very thankful.
I'm also not sure if Actionscript is the best language to write this in. If you have a recommendation that I can use FlashDevelop with I would appreciate the tip!
Thank you!
I have idea about the how this operation will be performed in java. For example creating buttons and labels. As long as you need to combine java and flash this link is useful for starters. If you need only java the following snippet will be useful. Also learn java swing from JavaDocs for GUI purpose
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ButtonClick
{
int counter = 0;
public ButtonClick()
{
JFrame frame = new JFrame("Title");
JButton btn = new JButton("Click me");
JLabel clicks = new JLabel("");
frame.setSize(400,400);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
counter++;
clicks.setText("Number of clicks till now :"+Integer.toString(counter));
frame.repaint();
}
});
frame.add(btn);
frame.add(clicks);
frame.setVisible(true);
}
public static void main(String []args)
{
ButtonClick c = new ButtonClick();
}
}

Why does using ActionListener break my Swing Applet?

I have an application working in Java Swing, but can't seem to convert to an Applet. Basically there are four buttons displayed on the Applet, and I want one of them to clear the screen and then draw a new interface (I'm going to add stuff for the other buttons, of course, but I got stuck here).
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.JApplet; //import swing applet interface
import java.util.Hashtable;
public class TopMenu extends JApplet{
private JPanel panel = new JPanel();
public void init(){
mainMenu();
}
public void mainMenu() {
// create buttons
panel.setLayout(new GridLayout(2, 2));
JButton collectButton = new JButton("Collect data");
JButton uploadButton = new JButton("Upload");
JButton downloadButton = new JButton("Download");
JButton exploreButton = new JButton("Explore data");
panel.add(collectButton);
panel.add(uploadButton);
panel.add(downloadButton);
panel.add(exploreButton);
collectButton.addActionListener(new ActionListener( ) {
public void actionPerformed(ActionEvent e) {
int numberGFish = 400;
//panel.removeAll();
//panel.add(new JLabel("Just to test"), BorderLayout.CENTER);
//panel.revalidate();
//panel.repaint();
}
});
setContentPane(panel);
}
}
All the code works totally fine until I add the ActionListener, and then the whole thing just goes blank. It compiles okay, but when I test it on my server not even the first menu comes up, it's just a blank panel. I've tried putting loads of really banal things in the ActionListener bit to make sure it's not a problem with them, but as you can see even just declaring a number in there doesn't work.
Originally I actually had the Listener bit call on another method which then did everything else, and that didn't work either, I scrapped that because I thought perhaps that was the problem.
I'm sure this is so simple but I've sunk many hours into it now and I've really just run out of ideas of things to test. And advice gratefully appreciated.
Don't know if it would be a problem or not but all GUI components should be created on the Event Dispatch Thread.
Here is the recommended code structure from the Swing tutorial on How to Make Applets:
public void init() {
//Execute a job on the event-dispatching thread:
//creating this applet's GUI.
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
createGUI();
}
});
} catch (Exception e) {
System.err.println("createGUI didn't successfully complete");
}
}
private void createGUI() {
JLabel label = new JLabel(
"You are successfully running a Swing applet!");
label.setHorizontalAlignment(JLabel.CENTER);
label.setBorder(BorderFactory.createMatteBorder(1,1,1,1,Color.black));
add(label, BorderLayout.CENTER);
}
I knew it was a dumb question, but I just couldn't figure it out. I've sorted it now.
I was being totally daft and not copying across the TopMenu$1.class file to the server. For some reason it works without this file but not with the ActionListener bit added. So I never thought that could be the problem.
Doh! Thanks all.

I have a JLabel that doesn't want to update

I've looked at other JLabel threads and though similar, a few just don't seem to apply to what I'm experiencing. First, I want to say I am a novice when it comes to Java. Next, I am trying to follow tutorials and demos at the docs.oracle.com site. Now, I can update the label when I type something into a JTextField and there is an ActionListener on that...
But I also have a Menu, and when I select a Menu Item, that Action does not want to update the label.
Questions -
How do I have action listeners on both JTextFields and JMenuItems? Are there two ActionEvent methods or do I use one method and somehow identify each type of action?
If I use the same basic code in the JTextField ActionEvent and JMenuItem ActionEvent, the JLabel updates correctly with the JTextField event but not JMenuItem event. They both use the messageField.setText property. Could the JMenuItem action be doing something to block the setText?
I can easily copy code in here, but it's pretty spaghetti-like at the moment, so if you want to see anything, let me know specifically and I'll post it.
I would appreciate any assistance that anyone would be able to provide.
---edit---
Wow!! Thanks for all of the comments and suggestions.
1 - I know it has to be my code. As I mentioned, I am really just cobbling stuff together from demos and tutorials, and trying to learn Java along the way. I've just never gotten the hang of object oriented....
2 - I do know the individual Listeners are working. I'm using System.out.println to validate, as well as inspecting those labels in debug mode to see they have indeed changed.
3 - I will look at the various links and code posted here and see if I can figure out what's wrong with my code.
Really, thanks again!
---edit---
Here is what I originally had in my createAndShowGUI method....
private static void createAndShowGUI()
{
JFrame frame = new JFrame("Create XML for Photo Gallery");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CreateGalleryXML window = new CreateGalleryXML();
frame.setJMenuBar(window.createMenuBar());
frame.add(new CreateGalleryXML());
frame.pack();
frame.setVisible(true);
}
Seems like you yourself are doing something wrong, in your code. Without a proper SSCCE it's hard to say what thing you doing wrong, since it works perfectly, using same ActionListener for both JMenuItem and JTextField.
Here is a sample program to match with yours :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class UpdateLabel
{
private JLabel label;
private String labelText;
private ActionListener action = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
setLabelText((String) ae.getActionCommand());
label.setText(getLabelText());
}
};
private void setLabelText(String text)
{
labelText = text;
}
private String getLabelText()
{
return labelText;
}
private void createAndDisplayGUI()
{
final JFrame frame = new JFrame("Update Label");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationByPlatform(true);
JMenuBar menuBar = new JMenuBar();
JMenu programMenu = new JMenu("Program");
JMenuItem exitMenuItem = new JMenuItem("Exit");
exitMenuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
frame.dispose();
}
});
JMenu labelMenu = new JMenu("Label");
JMenuItem updateMenuItem = new JMenuItem("Update Label");
updateMenuItem.setActionCommand("Updated by JMenuItem");
updateMenuItem.addActionListener(action);
programMenu.add(exitMenuItem);
labelMenu.add(updateMenuItem);
menuBar.add(programMenu);
menuBar.add(labelMenu);
frame.setJMenuBar(menuBar);
JPanel contentPane = new JPanel();
label = new JLabel("I am the LABEL which will be updated!!");
contentPane.add(label);
JTextField tfield = new JTextField(10);
tfield.setActionCommand("Updated by JTextField");
tfield.addActionListener(action);
frame.add(contentPane, BorderLayout.CENTER);
frame.add(tfield, BorderLayout.PAGE_END);
frame.pack();
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new UpdateLabel().createAndDisplayGUI();
}
});
}
}
And here is the output in both the cases :
and
Do check out the main method, might be you had failed to put your code inside EDT - Event Dispatcher Thread, that can lead to such issues too. All updates on the Swing GUI, must be done on the Event Dispatcher Thread.
LATEST EDIT
It seems to me that CreateGalleryXML extends JPanel by the look of it. See at Line 3 of this below code taken from your update, here you are initializing a new Object of CreateGalleryXML inside, when you already had one Object window created at Line 1:
CreateGalleryXML window = new CreateGalleryXML();
frame.setJMenuBar(window.createMenuBar());
frame.add(new CreateGalleryXML());
So try to change the above thingy to this
CreateGalleryXML window = new CreateGalleryXML();
frame.setJMenuBar(window.createMenuBar());
frame.add(window);
and see what happens and Please do revert back again :-)
Use Action to encapsulate common functionality that must be shared by menus and related components. See this example that extends AbstractAction.
Pretty much everything you could need to know is in the Java tutorials. Down the bottom they have demo's on how to do both menu's and text fields. They include source code to look at as well.
There's not much more I can say that they don't say better, but in answer to your questions:
Both, you can have separate listener's on each component, or one that figures out what component is responsible for causing the action event. I would suggest you use separate ones for each thing.
Can't really say with out seeing the code, are you sure that the action on the JMenu is even firing? Does it print something to the console etc if you use System.out.println somewhere?

Categories