I have a question regarding the possibility to dinamically update the visual side of a swing application.
I have created a small program, that works without any compile/logic errors and it does it's thing but it has a flaw. It does not automatically update when user clicks on something.
Let me explain the issue with the underneath picture
I tried adding a repaint and revalidate to anything. but it doesn't seem to work. they get ignored. Really, I added a repaint/revalidate method to EVERYTHING. Still nothing :)
I suggest adding the action event to the checkbox (I called it fullAutomaticCheckBox and the field txtField):
private void fullAutomaticCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {
txtField.setEnabled(fullAutomaticCheckBox.isSelected());
}
To add the event listener:
fullAutomaticCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
fullAutomaticCheckBoxActionPerformed(evt);
}
});
I want the text field to enable itself.
Then you add an ActionListener to the check box to enable/disable the text field depending on the state of the checkbox.
once user inputs a number it will repaint dynamically
If you want the screen to repaint, then you need to invoke the "update calculations" code dynamically. So you can add a DocumentListener to the text field. This will generate an event any time the user adds or removes text in the text field.
Read the section from the Swing tutorial on How to Write a DocumentListener for a basic example to get you started.
Related
I'm very new at coding Java and Netbeans. So basically, I have a "save" button and three text fields, I want to enable the Button when these three text fields are edited and disable the button when one of them is empty. Also I'm wondering where I should put my codes. Since it's Netbeans I'm only familiar with ActionPerformed methods, there you can set an action when a button is pressed.
If you can keep it simple it would be appreciated!
public project() {
initComponents();
//Here I want the window to appear in the middle of the screen
setLocationRelativeTo(null);
if(txfField1.getText().equals("")){
btnSave.setEnabled(false);
}
else {
btnSave.setEnabled(true);
}
}
I tried with this code on only one of the three text fields and It does not work, the button is always enabled. The button is initially disabled. Additionally I have also tried to put my code below this method:
public class project extends javax.swing.JFrame {
You can use event handlers to change the state of the button. For example, if you have one text field and you want to change the state of the button depending on the data inside the text field, you could use something like
if (!jTextField1.getText().equals("")) {
jButton1.setEnabled(true);
} else {
jButton1.setEnabled(false);
}
and the event handler you can use
private void jTextField1KeyTyped(java.awt.event.KeyEvent evt) {
You can generate this automatically in Netbeans by going to the event tab when you have clicked on a component in the design view.
It seems in your example you have the right idea, however you need to update the button using events such as key pressing, key releasing etc
You can add it in onblur() method of those text boxes.
If it can, you can add a validation with an error message on click of save button, which might be more meaningful.
So I'm using a JPasswordField to get the user input, and then give instantaneous feedback regarding the strength of the entered password. My problem is that if the user clicks on the 'hide' checkbox, the string in the textfield isn't immediately masked by '●', but works only when the textfield regains focus. I've tried to use component.getFocus within the mouseListener, but it doesn't seem to work.
Here's what this particular listener looks like:
inputT.addMouseListener(new MouseAdapter(){
#Override
public void mouseClicked(MouseEvent hideClicked){
if (hideC.isSelected()){
inputT.setEchoChar('•');
inputT.requestFocus();
}
if (!hideC.isSelected()){
inputT.setEchoChar('\u0000');
inputT.requestFocus();
}
}
});
Show the feedback to the user in a different field than the password field that they are typing into. Ideally a separate read only component that is to the right of the password in your GUI. Your password strength feedback would then be updated by a listener on the password field, but the JPasswordField could then just work like normal.
From the JavaDoc: http://docs.oracle.com/javase/7/docs/api/javax/swing/JComponent.html#requestFocus%28%29
public void requestFocus()
Requests that this Component gets the input focus. Refer to Component.requestFocus() for a complete description of this method.
Note that the use of this method is discouraged because its behavior is platform dependent. Instead we recommend the use of requestFocusInWindow(). If you would like more information on focus, see How to Use the Focus Subsystem, a section in The Java Tutorial.
Also, as MadProgrammer pointed out - your listener is on the JPasswordField instead of the JCheckBox.
Don't use mouse listener. For doing on selection, use ItemListener:
checkBox.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent evt) {
if(evt.getStateChange()==ItemEvent.SELECTED)
jPasswordField1.setEchoChar((char)0);
else jPasswordField1.setEchoChar('*');
}
});
Well, the above code works perfectly for me.
Start by attaching a ActionListener to the the checkbox, this means that user can click or press the space bar to activate the check box
In the actionPerformed method, check the state of the checkbox and the required changes.
Use JPasswordField#selectAll or JPassword#requestFocusInWindow (usually I do it the other way round ;)). If these do not work, you might even consider using JPassword#repaint to force the field to repaint
I have written a calculator in NetBeans and it functions perfectly. However, I have to actually click the buttons to insert numbers and am trying to remedy that with a KeyListener. I have all my numbers and function buttons set inside a JPanel named buttons. I have my display label in a JPanel named display.
I set my class to implement KeyListener and it inserted the KeyPressed, -Typed, and -Released methods; however I stuck from there. I'm not sure how to make my buttons actually listen for the KeyPressed event, and when it hears the event - activate the button. Also, my buttons are named by their number (e.g. the Zero Button is named zero, One button is one, etc.).
I've read that you actually have to implement a KeyListener somewhere by using: something.addKeyListener(something);
but I cannot seem to figure this out.
Can I get some help here? I'm new to Java and this is my first solo project. And let me know if I didn't provide enough information.
EDIT: Most of my code is NetBeans Generated and I cannot edit the initialization of the components which seems to be my problem I think?
My class declaration:
public class Calculator extends javax.swing.JFrame implements KeyListener {
//Creates new form Calculator
public Calculator() {
initComponents();
}
One of my buttonPressed actions (all identical with changes for actual number):
private void zeroActionPerformed(java.awt.event.ActionEvent evt) {
if (display.getText().length() >= 16)
{
JOptionPane.showMessageDialog(null, "Cannot Handle > 16 digits");
return;
}
else if (display.getText().equals("0"))
{
return;
}
display.setText(display.getText().concat("0"));
Main method supplied by NetBeans:
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Calculator().setVisible(true);
}
});
}
The initComponents() netbeans generated is absolutely massive (about 500 lines of code) and I cannot edit any of it. Let me know if I can supply any more helpful information.
Could there be an issue of Focus, and if so how can I resolve the issue?
Yes there is probably an issue with focus. That is why you should NOT be using a KeyListener.
Swing was designed to be used with Key Bindings. That is you create an Action that does what you want. Then this Action can be added to your JButton. It can also be bound to a KeyStroke. So you have nice reusable code.
Read the Swing tutorial on How to Use Key Bindings for more information. Key Bindings don't have the focus issue that you currently have.
I'm not sure I completely understand your question, and some code would help, but I'll take a crack, since it sounds like a problem I used to have a lot.
It sounds like the reason that your key presses aren't being recognized is that the focus is on one of the buttons. If you add keylisteners to the buttons, then you shouldn't have any problem.
In netbeans you can add keylisteners through the design screen really easily.
Here's a picture showing you how to add a keyPressed listener to a button in a jPanel.
private void jButton1KeyPressed(java.awt.event.KeyEvent evt) {
//Check which key is pressed
//do whatever you need to do with the keypressed information
}
It is nice to be able to write out the listeners yourself, but if you are just learning, then it is also nice to get as much help as possible.
This might not be the best solution, since you would have to add the listener for each of your buttons.
I'm doing an app with lots of buttons and menus and I want enable and disable the buttons and menu items when the actions attached to them can or can not be performed. ie the save button and the save menu item only will be active when there are unsaved changes.
Question: How can I do this efficiently/Which is the correct way to do this?
One solution can be have a private variable for each button and menu entry and enable/disable it as needed.
Other solution can be get all the components of the JToolBar and the JMenu in an array and iterate over all them and enable/disable as needed.
But I think there are better solutions. Any help or guideline will be apreciated.
edit: The question is not how to enable/disable a single button or menu item, I will know how can I manage the state of all the buttons and menu items of the app. Which is the best way to achive this?. I have explained some solutions in which I have been thinkin, but none of them convince me.
The Action class already supports this. See the Action#isEnabled and Action#setEnabled methods. Calling the setter will fire an event, on which the UI on which this Action is set will enable/disable itself.
The Action can be seen as the model for your UI buttons/menu items/... . All state is stored and updated in the model, and the view needs to reflect this (MVC pattern).
1) to disable from clicking use:
JButton#setEnabled(boolean)
and
JMenuItem#setEnabled(boolean)
2) to disable ActionListener for some time use a private boolean variable inside
public void actionPerformed (ActionEvent ae) {
if (!enabled) return;
// rest of code
}
This may be a stupid question, but I have to ask!
I have the following code snippets that are supposed to run their corresponding methods when the user interacts with objects.
For some reason, "foo" is never printed, but "bar" is.
myJSpinner1.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseEntered(java.awt.event.MouseEvent evt) {
System.out.println("foo"); //"foo" is not printed
}
});
myJSpinner2.addChangeListener(new java.awt.event.ChangeListener() {
public void stateChanged(java.awt.event.ChangeEvent evt) {
System.out.println("bar"); //"bar" is printed
}
});
I get no exceptions or stack trace. What am I missing in the MouseListener one?
Thanks in advance.
EDIT: MouseEntered works perfectly on a JCheckBox implemented in exactly the same way!
JSpinner is a composite component consisting of a text field and 2 buttons. It's possible to add mouse listeners to all of those by iterating over the results of getComponents() and adding a listener to each.
However, in my experience, when something takes that much work, you're probably going about it the wrong way.
Why do you need the mouse-entered information for a JSpinner?
What do you want to do with this event?
Update:
If you're looking to supply information about all of the controls in your panel, you may want to look at using a glasspane to detect the component under the mouse.
A Well-behaved Glasspane by Alexander Potochkin is a good place to start.
This is a guess but I suspect you need to add a MouseListener to the JSpinner's editor (via a call to getEditor()). I imagine that the editor Component occupies all available space within the JSpinner and is therefore intercepting all MouseEvents.
This worked for me.
JSpinner spinner = new JSpinner();
((JSpinner.DefaultEditor)spinner.getEditor()).getTextField().addMouseListener(
new java.awt.event.MouseAdapter() {
public void mouseClicked(final MouseEvent e) {
// add code here
}
});
I needed this in order to evoke a popup key dialog for added usability due to our software requirements.
Aditional to #Rapier answer...
If you change the Spinner using something like
yourOldSpinner = new JSpinner(new SpinnerModel(...))
you will lost your previosly MouseListener...
If you need to change something of SpinnerModel, Don't create a new, change its parameters instead! (if you do it, you will need to reassign the MouseListener again, because it will be lost when you assign a new SpinnerModel).
an example (I'm talking...):
((SpinnerNumberModel)yourOldSpinner.getModel()).setValue(size/3);
((SpinnerNumberModel)yourOldSpinner.getModel()).setMinimum(0);
((SpinnerNumberModel)yourOldSpinner.getModel()).setMaximum(isize/2);
((SpinnerNumberModel)yourOldSpinner.getModel()).setStepSize(1);