Adding a certain image to a JPanel in Java - java

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();

Related

Creating Dynamic JLabels for sort of a messenger app using Java

So I am trying to make a messenger sort of app with Java Drag and Drop in Netbeans.
I am fairly new at it. I initially want to take a string from the text area and display it in a JLabel in another panel. I tried to do it in the following process but it did not work.Can someone please help?
private void sendButtonActionPerformed(java.awt.event.ActionEvent evt) {
int i=0;
message = messageType.getText();
JLabel messageLabel = new JLabel();
messageLabel.setText(message);
messageLabel.setSize(100, 100);
messageLabel.setAlignmentX(0);
messageLabel.setAlignmentY(0);
JOptionPane.showMessageDialog(null, message);
clientPanel.add(messageLabel);
messageLabel.setVisible(true);
}
We have no idea what layout manager clientPanel is using and so do not know how well it will accept a JLabel being dropped into it, so as asked your direct question is unanswerable, other than to say you should always call revalidate() on a container (clientPanel) and then repaint() after adding or removing components so that the container re-lays out its components and then redraws them.
I advise against creating new JLabels for this. Much easier to set up the GUI including all necessary JLabels from the very beginning, give them text, empty spaces if need be, and then during the program set the text of an existing JLabel.
If on the other hand you wish to show multiple messages on the cientPanel, then consider using a JList<String> or a non-focusable JTextArea.

Removing a label in Java

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.

JPanel removeAll doesn't get rid of previous components

I have a swing application in which I display images in a JPanel. If the app is unable to produce the image I want to remove the previous one from the JPanel and replace it with a JTextField and message. I can add the text field , but it's drawn on top of the previous contents, which is itself a subclass of JPanel. Here's what I have:
private void displayMessage(String message) {
JTextField tf = new JTextField(message);
cdPanel.removeAll();
cdPanel.add(tf, BorderLayout.NORTH);//tried lots of variations, inc. no layout
cdPanel.validate();
}
How can I get cdPanel to completely redraw itself?
You can simply try calling :
cdPanel.revalidate();
cdPanel.repaint(); // This is required in some cases
instead of
cdPanel.validate();
As you are dealing with unpredictable latency, use a SwingWorker to do the loading in the background, as shown here. The example uses pack() to resize the label to that of the image, but you may want to use a fixed-size grid and scale the images, as shown here.

How to put a JButton inside a JTextField (Java)?

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.

Refresh JPanel

I need to display different drawings on a JPanel.
I have put the drawing files into an array, but when I changed it using a button, the JPanel only displays first drawing and doesn't change to the next drawing...
I have called panel.revalidate(), but it doesnt work.
This is the segment of the code that I used but not working.
The JPanel display was static.
String[] a = {"image1.txt","image2.txt","image3.txt"};
List<String> files = Arrays.asList(a);
public void actionPerformed(ActionEvent e) {
if (e.getSource() == answer1){
fileNumber++;
//call other class for painting (files=array files, fileNumber=index of the array)
draw = new drawingPanel(files,fileNumber);
panel.add(draw);
}
panel.revalidate();
panel.repaint();
}
You might try keeping a reference to your drawingPanel and calling remove() on the existing drawingPanel before re-adding it. According to the JPanel JavaDoc, the layout is FlowLayout by default - which will not replace the image like you are intending, but will instead place the next drawingPanel to the right of the previous one. (what happens when you resize the window?)
By the way, how do you handle the case where you get past the last image in the array?
Are you only displaying one drawing at a time? If so, you may want to try using a CardLayout, so you can switch between drawings easily. See http://java.sun.com/docs/books/tutorial/uiswing/layout/card.html for an example.
I had a similar issue the other day attempting to dynamically display different buttons on my UI depending which tab of a JTabbedPane the user picked. CardLayout was just the thing to make things easy.

Categories