Currently the code only hides the JLabel. I'm not sure why it's not making it visible when I click the button again. Hopefully this is an easy fix
contentPane.add(btnSwap);
btnHide.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
lblHello.setVisible(false);
}
});
contentPane.add(btnHide);
btnHide.setBounds(185, 199, 89, 23);
lblHello.setVisible(true);
}
I'm not sure why it's not making it visible when I click the button again.
Why should it, since all the ActionListener does (the code that's called on button press) is to continually set the label invisible?
A solution is to simply toggle its visibility:
lblHello.setVisible(!lblHello.isVisible());
Note that to be safe, it's best to revalidate and repaint the container after making such changes, so:
btnHide.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
lblHello.setVisible(!lblHello.isVisible());
revalidate();
repaint();
}
});
as this will rid the GUI of "dirty" pixels that can occur from adding and especially from removing visible components.
A word on this:
btnHide.setBounds(185, 199, 89, 23);
This suggests that you're using null layouts with setBounds(...). While this often seems to newbie Swing coders the best way to create complex GUI's, it will come back to haunt them later, since this will mean that the GUI will look OK on one platform and one platform only, and that if later you want to enhance or improve the GUI, it can only be done with much difficulty and risk of bugs. Much better is to learn and use the layout managers.
Another recommendation:
If your desire is to change the appearance of the GUI on button press, then also have a look at the CardLayout (please check the CardLayout Tutorial) as this can be a way to cleanly and easily swap views
And a better recommendation:
Since a JLabel only shows its text or its icon or both, the best way to make it "invisible" is to remove its text and its icon, as noted by Andrew Thompson below:
// get rid of its text
lblHello.setText("");
// and if needed
lblHello.setIcon(null);
This won't work for text components such as JTextFields and JTextAreas or other components that have more "heft" than a JLabel including pretty much all other user-interaction components.
Try :
btnChangeLabelVisibilityButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
lblHello.setVisible(!lblHello.isVisible());
}
});
Related
So I'm writing a program in which I would eventually like a JButton to change color when pressed. So far, here is my dilemma:
-I cannot get the JButton I currently have set up to show the background color, despite toggling the true/false of setOpaque() and setContentAreaFilled(). I would like to be able to do this before even attempting to add an ActionListener.
-I would like to use something similar to JToggleButton() to change the color, however I would like to do this with just a background instead of an icon.
I am using a mac, and I'm wondering if it has something to do with the default button settings, but I don't know how to change/override these.
I would post a screenshot, but unfortunately my reputation isn't high enough yet.
Here is an example of what I am getting:
import java.awt.*;
import javax.swing.*;
public class Example extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame main = new JFrame("Example");
JPanel content = new JPanel();
JButton button = new JButton("Press");
button.setBackground(Color.orange);
button.setContentAreaFilled(false);
button.setOpaque(true);
content.add(button);
main.setContentPane(content);
main.setVisible(true);
main.setSize(40,60);
main.setLocation(500, 200);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
For those (maybe on a windows or linux platform) who can't see what I'm talking about, the button appears and the layout behind the button (not the border or the JPanel, just a small rectangle around the button) is colored to what was specified.
Thank you in advance for your time.
Also, I know that inside the ActionListener the getSource() method will return the text associated with the button. Is there any way to use something similar to change the color of the button from inside the ActionListener or is this idea just a redundancy for something that can be done in a much simpler fashion.
Much appreciated.
i think you want play something around with the look and feel.
try
button.setUI(new MetalButtonUI());
or try some other background color supported UI for the button.
I would eventually like a JButton to change color when pressed
here are two different ways (note JButton has an arrays of colors in UIManager)
override events from ButtonModel (ChangeListener or the same methods are implemented e.g. isPressed, isArmed in JButtons API), accelators are valid for mouse and KeyEvens (selection or focusInWindow)
override BasicsButtonUI (for real project)
I am using a mac, and I'm wondering if it has something to do with the
default button settings, but I don't know how to change/override
these.
depends of Look and Feel that your Java uses (Quaqua - default on OSX or standards by Oracle Metal, Nimbus ...)
I think that button.setOpaque(true); is unnecessary.
Remove it, or change it to: button.setOpaque(false); and see what happened
I'm trying to set a variable to be a new JPanel and then add it once a button is pressed, but it is not working and I don't know why.
code:
private void nextButtonActionPerformed(java.awt.event.ActionEvent evt) {
remove(scriptPanel);
scriptPanel = new GemPanel();
add(scriptPanel);
validate();
repaint();
pack();
}
GemPanel is just a JPanel class I made. When I press the next button, it re-sizes the frame to be as small as possible and nothing actually happens. If I re-size it to normal, the original scriptPanel is still there.
What gives?
Instead of trying to remove and add entire panels, a better, less problem prone approach would be to use a CardLayout that will allow to swap views. You can see more at How to use Cardlayout
Also, by the looks of your method signature, it seems you're using the Netbeans builder too. You may also want to take a look at How to Use CardLayout with Netbeans Gui Builder
I'm making a calculator using Swing. So far I have created a GUI that consists of a JFrame with BorderLayout, and in its center I put a JPanel that has a JLabel (representing the screen of the calculator) and some JButtons (representing the keys).
I want the calculator to be able to receive input directly from the keyboard, so I included the method addKeyListener in a class that extends JFrame and I put as an argument a reference to an object of a class that implements KeyListener.
When I run the application it accepts keyboard input until I click on one of the JButtons. After that using the keyboard doesn't work anymore.
I suspect the problem is about focus, but it is not a problem that I could fix by clicking anywhere on the application. I added the following code:
setFocusable(true);
to the JFrame but it did not help. I have read that using Key Bindings maybe a better option than using a KeyListener, but I am not really sure about this approach.
Swing components are lightweight and use KeyBindings, where KeyListeners are for AWT components which are heavyweight. and known to have focus issues when mixed with Swing components. Thus I suggest changing to KeyBindings (but I see you have heard of them). You would use them something like:
final JButton b=..;
//method to add keybindings to a JComponent ie JButton,JPanel,JTextField etc
private void addKeyBindings(JComponent jc) {
//not the getInputMap(..) call it could also be JComponent.WHEN_FOCUSED etc
jc.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("D"), "D pressed");
jc.getActionMap().put("D pressed", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
//do something when d is pressed
b.doClick();
}
});
}
For general knowledge a very hacky solution would be calling requestFocusInWindow() on the component to which the listeners are attached whenever focus is lost (like after button click etc)
It's another hacky approach, but you could alter the properties of the JButton when you create it so that it can't take the focus in the first place i.e:
myJbutton.setFocusable(false);
This worked for me.
Recently I found out that I can use my images as buttons with mouse listener.
What is the main difference between using buttons and images as buttons. What is the main drawback of this option?
Button:
JButton btnNewButton_1 = new JButton("Button");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//Do something
}
});
Image:
getJlabel().addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
//Do something
}
});
Although both of them provide similar functionalities, I think that most users are not accustomed to such a thing.
To the average user (in my opinion at least), buttons should be clicked and images should be looked at. It is like the image provides a means to the user to understand and the button provides a means for the user to act.
You could throw in Images in JButtons (as explained here), but that being said, I think that from a User Experience point of view you should not use images as buttons unless you really have to, and when you do, I think that you should include specific instructions.
The JButton provides animation (during clicking and releasing), different looks for different states (like when it's not enabled) and other things one expects from an actual "push button".
You can add the these (or some of these) functionalities to an image according to your requirements using a mouse listener.
It all depends on what you want and how much code are you willing to write by hand.
FYI, the images can be added to JButtons (mainly for the purpose of icons).
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);