Refresh JPanel - java

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.

Related

Adding a certain image to a JPanel in 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();

JPanel deforms my Layout

Im using NetBeans to do a work for school. There i have an huge JPanel that contains a huge JFrame. That JFrame as 5 small JFrames, 1 is the menu with buttons, the other ones are boxes with text that will swap when i choose in the buttons.
When one box is showing the other ones are invisible im using the following code (dont know if it is the best):
public ConversorUI() {
initComponents();
PanelVazio.setVisible(true);
PanelTemp.setVisible(false);
PanelComp.setVisible(false);
PanelMoedas.setVisible(false);
this.pack();
}
My problem is, when i run my program i have a big space with nothing and only below it the components appear. I want them to appear in the top of my window. What can I do ?
ANSWER
After some time searching i just realized i could Set Layout from JPanel to Card Layout and create JPanels over each other activating them with the code:
private void DinheiroButtonActionPerformed(java.awt.event.ActionEvent evt) {
//Remove Panels
CAIXA.removeAll();
CAIXA.repaint();
CAIXA.revalidate();
//Add Panels
CAIXA.add(DinheiroBox);
CAIXA.repaint();
CAIXA.revalidate();
}
Looks like you are using Java Swing , right ?
Any way you do something wrong if you have JPanel that contains JFrames. To build correct UI you have to add JPanels inside JFrame.
Also, to reach correct component order and placing you need configure corresponded layout, here is description.
You can load one jframe at e time
Because every jframe you added have own place and visibility doesnt do anything to remove
Try to save every jframe and for changing
Delete old one and add new one
Why are you using multiple JFrames to do this? From what I can see it would be a better idea to use JPanels that can take care of the individual tasks, such as the menu and buttons etc.
I'm relatively new to using javax.swing myself, but from my knowledge you can only have 1 frame at a time per window (like the other person said).
From what i've been able to discern from your project, you possibly don't even need multiple panels. You just need one panel for the menu with buttons, and multiple Labels or JLabels that display text according to the button. You can use the setText method in writing your addActionListener, something like this:
buttonName.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
labelName.setText("blah blah blah");
//and whatever else you may need to do
}
});

Copying JPanel contents to another JPanel without removing contents of original JPanel

I am new to Java swing coding. I am trying to copy JPanel contents to a new JPanel which uses contents of original JPanel to show. Also, the original JPanel contents are changing as records are changing. I tried the following code but it's totally useless.
public void addPanel(JPanel jp)
{
JPanel jp1=new JPanel();
int count=jp.getComponentCount()-1;
for(;i>=0;i--)
{
jp1.addComponent(jp.getComponent(i);
}
//after this I am setting bounds of jp1.
this.add(jp1);
}
This doesn't work if I want to make multiple JPanels as original JPanel changes. It overwrites the contents of new 'jp' over 'jp1' if used multiple times, say if used in a for loop.
I do not want to remove components of original JPanel. How can I do that?
Moving instances of Component is possible but coping them requires you to do it manually.
You can do this as a program by creating new instances of the origin class and then calling the setters with the values of the getters... But frankly, thats an error prone way and you'll need reflection for it which you shouldn't use unless really necessary.
What you can do is to override the standard Java Classes you use (e.G. JLabel) and in your overridden class you implement Cloneable where you set the parameters you need (text, bounds, whatever) then call your function like this:
public void addPanel(JPanel jp)
{
JPanel jp1=new JPanel();
int i=jp.getComponentCount()-1;
for(;i>=0;i--)
{
jp1.addComponent(
((Component) // this casts the clone back to component. This is maybe superfluous.
((Cloneable)jp.getComponent(i) // You have to ensure that all components that are returned are in fact instances of Cloneable.
).clone()
));
}
//after this I am setting bounds of jp1.
this.add(jp1);
}
If you go down that road, be sure to read the Documentation of Cloneable.
Here is method for solving the following problem without coding just using design views of JPanels/JFrames.
You can go to Navigator in design view select all JPanel components and copy them by typing ctrl+a and ctrl+c.
Then create another one JPanel and in design view, just paste them with ctrl+v.
Result: You get all components same size, dimensions and positions with same properties and values. After you do this, you can easily change whatever you want by using properties of GUI forms.

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.

Java Swing dynamic loading of classes into panels

My program looks like this!
I want to have the bottom part dynamically load a frame into the bottom frame depending on the item selected in the ComboBox. For example, if the first item is selected I want a panel from the PresentValue.java file displayed. The idea is that I have one java file for each selection that displays what I design in its respective java file.
These two java files should be put into the "bottom" box from my first screenshot, depending on the selection from the combobox.
I'm more used to Android programming and there I would simple call the replace method from fragments to swap out the fragment loaded... looking for the analogy here.
final JComboBox selectorBox = new JComboBox(selection);
selectorBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
int selectionID = selectorBox.getSelectedIndex();
}
});
but cant find a way to do what I want to do. Please explain.
For each Java file that you have, the output of that Java file should be a JPanel. Not a JFrame.
Before you display anything, execute all of the Java files you have. Create all of the possible JPanels.
Create your JFrame in your GUI, then use the remove and add methods of JFrame to remove or add the desired JPanel.
Here's an example from one of my GUI's.
public void updatePartControl() {
Thread thread = new CountdownThread(model, this, displayPanel);
thread.start();
frame.remove(alarmPanel.getPanel());
frame.add(displayPanel.getPanel());
frame.validate();
frame.pack();
frame.setBounds(getBounds());
}
The setBounds method resets the bounds if the display JPanel is bigger or smaller than the alarm JPanel.
Your application should have one JFrame. You use multiple JPanels to create your GUI.
Changing the bottom component will depend on the layout manager that are using. CardLayout is purpose designed for swapping panels.
public void actionPerformed(ActionEvent arg0) {
int selectionID = selectorBox.getSelectedIndex();
if (selectionID == 0) {
cardLayout.show(basePanel, SELECTED_1);
}
// handle other selections
}

Categories