JPanel doesn't update fields.... Please help.

L

Lobang Trader

I have been stumped with this problem for days.
The JPanel does not update the JLabel component into the new JButton.
Even if the JButton is a new JLabel, the panel doesn't update.
Any help a million times appreciated. thanks


import java.awt.BorderLayout;

import javax.swing.JComponent;
import javax.swing.JPanel;

public class Test extends JPanel {

private JComponent display;

public Test() {
setLayout(new BorderLayout());

display = createDisplay();
if(display != null)
add(display, BorderLayout.WEST);
}

public void setDisplay(JComponent display) {
this.display = display;
revalidate();
repaint();
}

protected JComponent createDisplay() {
return new javax.swing.JLabel("JLabel");
}

// Test code.

public static void main(String[] args) {
javax.swing.JFrame frame = new javax.swing.JFrame();

frame.setSize(java.awt.Toolkit.getDefaultToolkit().getScreenSize());
frame.setVisible(true);

Test test = new Test();
frame.add(test, BorderLayout.SOUTH);

test.setDisplay(new javax.swing.JButton("JButton"));
}
}
 
H

hiwa

Lobang Trader said:
I have been stumped with this problem for days.
The JPanel does not update the JLabel component into the new JButton.
Even if the JButton is a new JLabel, the panel doesn't update.
Any help a million times appreciated. thanks


import java.awt.BorderLayout;

import javax.swing.JComponent;
import javax.swing.JPanel;

public class Test extends JPanel {

private JComponent display;

public Test() {
setLayout(new BorderLayout());

display = createDisplay();
if(display != null)
add(display, BorderLayout.WEST);
}

public void setDisplay(JComponent display) {
this.display = display;
revalidate();
repaint();
}

protected JComponent createDisplay() {
return new javax.swing.JLabel("JLabel");
}

// Test code.

public static void main(String[] args) {
javax.swing.JFrame frame = new javax.swing.JFrame();

frame.setSize(java.awt.Toolkit.getDefaultToolkit().getScreenSize());
frame.setVisible(true);

Test test = new Test();
frame.add(test, BorderLayout.SOUTH);

test.setDisplay(new javax.swing.JButton("JButton"));
}
}
(1)
frame.add(test, BorderLayout.SOUTH);
frame.getContentPane().add( ....... );

(2)
public void setDisplay(JComponent display) {
this.display = display;
revalidate();
repaint();
}
public void setDisplay(JComponent display) {
remove(this.display);
this.display = display;
add(display, BorderLayout.WEST);
validate();
}

(3)
Call JFrame#setVisible(true) after all the add()s.
 
L

Lobang Trader

Lobang Trader said:
I have been stumped with this problem for days.
The JPanel does not update the JLabel component into the new JButton.
Even if the JButton is a new JLabel, the panel doesn't update.
Any help a million times appreciated. thanks


import java.awt.BorderLayout;

import javax.swing.JComponent;
import javax.swing.JPanel;

public class Test extends JPanel {

private JComponent display;

public Test() {
setLayout(new BorderLayout());

display = createDisplay();
if(display != null)
add(display, BorderLayout.WEST);
}

public void setDisplay(JComponent display) {
this.display = display;
revalidate();
repaint();
}

protected JComponent createDisplay() {
return new javax.swing.JLabel("JLabel");
}

// Test code.

public static void main(String[] args) {
javax.swing.JFrame frame = new javax.swing.JFrame();

frame.setSize(java.awt.Toolkit.getDefaultToolkit().getScreenSize());
frame.setVisible(true);

Test test = new Test();
frame.add(test, BorderLayout.SOUTH);

test.setDisplay(new javax.swing.JButton("JButton"));
}
}
(1)
frame.add(test, BorderLayout.SOUTH);
frame.getContentPane().add( ....... );

I'm using JDK 1.5 actually. Therefore frame.add() and
frame.getContentPane().add() are identical.

(2)
public void setDisplay(JComponent display) {
remove(this.display);
this.display = display;
add(display, BorderLayout.WEST);
validate();
}

(3)
Call JFrame#setVisible(true) after all the add()s.

First of all, because of the way JFrames work, you need to change the
line:
frame.add(test, BorderLayout.SOUTH);
to:
frame.getContentPane().add(test, BorderLayout.SOUTH);

I'm using JDK 1.5 and therefore using frame.add() is similar to using
frame.getContentPane().

Second, all your setDisplay method does is store the new component in
the display member variable of your Test object. It doesn't actually
add the new component to the window. Try this:

public void setDisplay(JComponent display) {
this.display = display;
add(display, BorderLayout.WEST);
revalidate();
}

Actually, if you re-add the component, revalidate() is redundant.
I am aware of this but I refuse to use it as to me it is ugly coding,
which I could be wrong if this is the only way to solve the problem

Is there any nicer ways of doing it besides re-adding the component?

If I were to change the layout to FlowLayout, for instance, and I
added several components to the frame and calls a method to replace a
component at a specified index such as setDisplay(int index,
JComponent display), does that mean I have to keep use a for loop and
re-add all the other components in order to just change one
compoonent?
 
K

Karl von Laudermann

I'm using JDK 1.5 and therefore using frame.add() is similar to using
frame.getContentPane().

Well, I'm using 1.4.1, so I needed to use getContentPane(). If you're
planning to distribute your program, you might have to keep backwards
compatibility in mind.
Actually, if you re-add the component, revalidate() is redundant.

This must be another 1.5 thing, because I tried removing the
revalidate() call, and the button didn't appear until I resized the
window.
I am aware of this but I refuse to use it as to me it is ugly coding,
which I could be wrong if this is the only way to solve the problem

Is there any nicer ways of doing it besides re-adding the component?

One way is to use a CardLayout, which allows you to switch between
several different controls in the same place in the UI. But that's
more suited to situations where you know in advance what all the
controls are that you'll want to show. If you want to be able to stick
any arbitrary control into a specific place in the UI, you'll have to
manually add the component to the UI each time.
If I were to change the layout to FlowLayout, for instance, and I
added several components to the frame and calls a method to replace a
component at a specified index such as setDisplay(int index,
JComponent display), does that mean I have to keep use a for loop and
re-add all the other components in order to just change one
compoonent?

Well, if you want to be able to replace a component on the fly with
any arbitrary component passed to your method, then you'll obviously
have to use a layout manager that allows you to specify where to put
the control so you can put it in the same place as the one it's
replacing. The FlowLayout doesn't allow this. However, as a
workaround, you could add a nested JPanel to your
FlowLayout-controlled panel, and then add/replace your component to/in
the nested JPanel. That way you're not changing the controls being
managed by the FlowLayout.

In fact, regardless of what layout manager you're using, you may want
to use a nested JPanel that just holds the control that's changing.
This is probably the cleanest approach.

BTW, changing controls in place on the fly isn't something that's
commonly done, so this is one of those things that raises a flag that
would prompt someone to say, "What is it you're *really* trying to do
here? Maybe there's an entirely different approach that's both cleaner
to implement and is a better UI design."
 
R

Roedy Green

Well, if you want to be able to replace a component on the fly with
any arbitrary component passed to your method, then you'll obviously
have to use a layout manager that allows you to specify where to put
the control so you can put it in the same place as the one it's
replacing. The FlowLayout doesn't allow this

GridBagLayout does.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,679
Members
48,796
Latest member
Greg L.

Latest Threads

Top