I have this piece of code, which should remove a label, when a button is pressed:
final JLabel label = new JLabel("Label text");
rightPanel.add(label);
final JButton remove = new JButton("Remove label");
leftPanel.add(remove);
add.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
rightPanel.remove(label);
}
});
But when I click on the button, it doesn't remove the label text. Only when I resize the window (for example set it to full screen), the label text dissapears.
From this previous answer located here, put forth by camickr, you need to do the following:
The code would be (assuming the use of a JPanel):
panel.remove(...);
panel.revalidate();
panel.repaint(); // sometimes needed
You need to remove the component and then tell the panel to layout the remaining components.
Perhaps not an answer to your question but what I consider helpful advice: only add/remove components when it is absolutely necessary. If you get creative, you'll find that there are often better solutions than adding/removing components. For example, instead of removing a JButton, consider disabling it instead.
In your situation, you could always just do label.setText(""). This way you don't need to revalidate() and repaint().
I very rarely call revalidate() and repaint() in my code. I think it's better to update the existing components than to remove/add them.
Related
So, I want to draw an image based on the current selection of a scroll list in java Swing. It seems the best way to do this is to add an label to a panel. I tried multiple various ways of doing this and for the life of me I can't figure why it won't display the image. This is a snippet of what I have managed to do so far.
private void jList1MouseClicked(java.awt.event.MouseEvent evt) {
ImageIcon greenDragon = new ImageIcon("C:\\Users\\Ilmari\\Documents\\NetBeansProjects\\GUI harkkatyƶ\\src\\Ile\\Green_dragon.png");
JLabel dragon = new JLabel();
dragon.setIcon(greenDragon);
String selectedMonster = jList1.getSelectedValue();
if(selectedMonster.equals("Green Dragon")){
jPanel1.add(dragon);
}
else if(selectedMonster.equals("Black Demon")){
}
}
The best outcome so far has been overriding the background JLabel image completely and only displaying a white box with the image.
JLabel dragon = new JLabel();
This label should be declared as an attribute of the class, and added to the GUI when it is first made. Then in the jList1MouseClicked method, simply call dragon.setIcon(..).
That way there is no need to revalidate the GUI on each image change.
On the subject of jList1MouseClicked: Use the most optimized listener for a JList. A ListSelectionListener will react to keyboard input as well as mouse input, and provides other advantages besides.
If the image isn't displayed at all. You need to revalidate and repaint your frame.
To achieve that - add this to your code:
frame.getContentPane().validate();
frame.getContentPane().repaint();
Coded this in netbeans so I did not write all the code for the creation of the rest of the GUI myself.
btn_Next is the button that is already on the panel
private void place_Button() {
btn_Next.setLocation((btn_Next.getX()+30), btn_Next.getY());
btn_Next.revalidate();
btn_Next.repaint();
JButton btn_Back = new JButton("Back");
pnl_Buttons.add(btn_Back);
btn_Back.setPreferredSize(btn_Next.getPreferredSize());
btn_Back.setLocation((btn_Next.getX()- 100), btn_Next.getY());
btn_Back.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
switch_Works_Back();
}
});
btn_Back.setVisible(true);
pnl_Buttons.revalidate();
pnl_Buttons.repaint();
}
What layout manager does pnl_Buttons use? If you don't know, you could easily have Java print it out:
System.out.println(pnl_Buttons.getLayout());
Note that some layout managers allow adding components much better than others, and for your question, the layout is key.
A guess here, but it looks like your pnl_Buttons uses a null layout, and if so, your JButton may not be showing because its size is 0 x 0 since you never set its size; this is because null layouts require that the added components specify completely their own size and location. You specify the location and the preferred size of the button but not its size. If so, a quick solution is to set the JButton's size via setSize(...), but much better is to not use null layouts, and instead use one of the more user friendly layout managers.
As an aside, you shouldn't call revalidate() and repaint() on the component being added and don't need to call setVisible(true) on your JBUtton unless you've called setVisible(false) on it previously. Instead you only need to call revalidate() and repaint() on the container that you're adding your component to, here your pnl_Buttons object.
I have a JFrame inside of which is a jpanel that im using as the content pane.
So basically im using the jpanel to load content into on click. New content is returned as a Jpanel also so its ends up being jpanel -> inside jpanel -> inside Jframe. When i need to load in new content i clear the panel, load the new content and validate() the jframe & jpanel and the new content displays.
My problem is that when the new content displays its clear that the validate method is working because i can see the new interface but i can also see the old interface as if its become the background; i can resize the window and it just disappears and looks as it should.
Is this just the way validate works or can i fix it?
Edit: this worked. The problem was i wasn't calling repaint manually.
public BaseWindow setContent(JComponent comp){
contentPane.add(comp);
contentPane.revalidate();
contentPane.repaint();
return this;
}
Generally the code for adding/removing one or two components from a panel is:
panel.remove(..);
panel.add(...);
panel.revalidate();
panel.repaint(); // sometimes needed
However, if you are replacing all the components on the panel, then the better approach is to use a Card Layout.
You have already stated the revaliate() followed by repaint() doesn't work so the only suggestion I have is to post your SSCCE that demonstrates the problem.
Don't use validate. Use revalidate() instead.
Revalidate first calls invalidate() followed by a validate().
In Swing, you would rarely use validate().
Note: I also feel that maybe the old panel is not cleared/removed.Check again!
Validate() is for causing components to re arrange themselves according to the layoutmanager that you have installed. This is not really what you should be using.
I can't see your code, so I'm not sure exactly what you are doing. I could speculate that calling repaint() on your "inner panel" will solve the problem you are having...but really, if you are doing things properly, you shouldn't need to call repaint() or validate().
Make two JPanels, one with content A (e.g. your buttons), and one with content B (e.g. your "static" field). Use the "add()" and "remove()" methods on the parent container (the JFrame's content pane?) to swap these two JPanels with each other whenever you want to switch the content that is displayed in that part of the JFrame.
Then you shouldn't need to do anything else; it should just work.
I don't know if validate() makes any promise about fully repainting the container. You might have to call repaint() yourself to make it behave as you want to.
Here's another possible solution:
Put both JPanels in at the same time, side by side, and then make sure only one of them is ever visible at any one time:
JPanel p = new JPanel(new BorderLayout());
p.add( panelA, BorderLayout.EAST );
p.add( panelB, BroderLayout.WEST );
panelA.setVisible(true);
panelB.setVisible(false);
Then when the user clicks the button to switch panels:
panelA.setVisible(false);
panelB.setVisible(true);
The setVisible() method and BorderLayout should take care of validating, layout, and calls to repaint() for you.
I ended up fixing my issue (display not shown, buttons would stay clicked/weren't unclicking) by changing which panels were added/removed.
Problem:
frame.removeAll();
frame.add(getNewPanelDisplay());
frame.revalidate();
frame.repaint();
Solution:
//initializer()
mainPanel = new JPanel();
frame.add(mainPanel());
// ...
//update()
mainPanel.remove(0);
mainPanel.add(getTablePanel(), 0);
frame.revalidate();
frame.repaint();
I would like to have a JButton (with a folder icon image) inside a JTextField, like over on the far right of the JTextField, so that when clicked, the button opens up a JFileChooser, and when a file is selected, the path to the file appears inside the JTextField.
I have made this code, but nothing shows up.
public class TextFieldChooser extends JTextField {
public ImageIcon folderIcon;
public JButton btnFolder;
public TextFieldChooser(int columns) {
super(columns);
btnFolder = new JButton();
folderIcon = new ImageIcon(getClass().getResource("/resources/folder_find.png"));
btnFolder.setIcon(folderIcon);
this.add(btnFolder);
}
}
You may find the Component Border helpfull. It allows you to display a button in the text field by using the Border API.
Building on what Shakedown suggested, I think you can get the desired effect relatively easily. What you do is have a JPanel that contains both the text area and, beside it, the button. Next, set the text field to not draw any borders and give the JPanel a bevel border. Now it will look like the button is inside the text area. It might take some fine tuning, but it should work.
You can't don't want to put a button in a text field. You need to break out your intent into several components - 3, in fact.
First you're going to need a parent container, or something that will contain both your text field and also the button; a JPanel should suffice.
Then you need your real components, and by real I mean the ones that actually do something. These are your JTextField and JButton - go ahead and add these to the JPanel. In order to add them and have them appear how you want (with the button in the corner), you're going to need to specify a layout for your JPanel. This layout will define where added components go (visually) inside the JPanel.
Now that you've added those things into your JPanel, you can work only with your JPanel instead of thinking in terms of the contained JTextField and JButton.
Because Pyrite has not posted his final solution, here is mine:
my_button = new JButton("x");
JFormattedTextField my_textfield = new JFormattedTextField("Nr.");
my_textfield.setBorder(javax.swing.BorderFactory.createEmptyBorder());
JPanel textfield_with_button = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
Border lowered_bevelborder = BorderFactory.createLoweredBevelBorder();
textfield_with_button.setBorder(lowered_bevelborder);
textfield_with_button.add(my_textfield);
textfield_with_button.add(my_button);
Well I probably think you got your answer, but for others who want to do this easily, cuz I think the other answers are a bit too complicated.
So, what you need to do is, when you create the JTextField you create the JButton as well. Well see the code for yourself:
JButton button = new JButton();
button.setBounds(50, 5, 50, 25);
button.setBackground(Color.black);
JTextField textField = new JTextField();
textField.setBounds(20, 60, 100, 35);
textField.setBackground(Color.white);
textField.add(button);
And its that easy, I used setBounds() on the button cuz I can place it anywhere I want, as for the textField you can use a frame/panel layout aswell, but this was for just demonstrating how it works.
I have GUI created using netbeans GUI builder. I want to add there an object (let's try with button) after pressing a JButton
The very simple code which I wrote in ActionListener and works:
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
panel2.add(new JButton("X"));
panel2.validate();
}
});
Howewer in Gui created by netbeans this doesnt work:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
jPanel1.add(new JButton("X"));
jPanel1.validate();
System.out.print("aa");
}
But it prints "aa" so action listener works.
It looks like a similar problem to one showed here:
http://bytes.com/topic/java/answers/857720-adding-icon-jpanel
but I can't see even that rectangle about which JosAH wrote.
I'll appreciate any suggestion.
Create a placeholder panel in your editor, and then add the panel to that. I think the problem is to do with layouts and such, since some layouts require some layout data to be present on adding the component (i.e., the second field in add(c, ...) is set). So, create a placeholder JPanel using the GUI creator tool, name it so you have a reference to it, and then add the component to that panel. Give it a layout such as FlowLayout which requires no layout data. You may also want to remove all the insets on the panel so you don't get massive spacing, which you can probably do in the UI editor.