I have a JPanel which contains a JToolbar (including few buttons without text) and a JTable and I need to enable/disable (make internal widgets not clickable). I tried this:
JPanel panel = ....;
for (Component c : panel.getComponents()) c.setEnabled(enabled);
but it doesn't work. Is there a better and more generic solution to enable/disable all internal components in a JPanel?
I have partially solved my problem using JLayer starting from the example here http://docs.oracle.com/javase/tutorial/uiswing/misc/jlayer.html:
layer = new JLayer<JComponent>(myPanel, new BlurLayerUI(false));
.....
((BlurLayerUI)layer.getUI()).blur(...); // switch blur on/off
class BlurLayerUI extends LayerUI<JComponent> {
private BufferedImage mOffscreenImage;
private BufferedImageOp mOperation;
private boolean blur;
public BlurLayerUI(boolean blur) {
this.blur = blur;
float ninth = 1.0f / 9.0f;
float[] blurKernel = {
ninth, ninth, ninth,
ninth, ninth, ninth,
ninth, ninth, ninth
};
mOperation = new ConvolveOp(
new Kernel(3, 3, blurKernel),
ConvolveOp.EDGE_NO_OP, null);
}
public void blur(boolean blur) {
this.blur=blur;
firePropertyChange("blur", 0, 1);
}
@Override
public void paint (Graphics g, JComponent c) {
if (!blur) {
super.paint (g, c);
return;
}
int w = c.getWidth();
int h = c.getHeight();
if (w == 0 || h == 0) {
return;
}
// Only create the offscreen image if the one we have
// is the wrong size.
if (mOffscreenImage == null ||
mOffscreenImage.getWidth() != w ||
mOffscreenImage.getHeight() != h) {
mOffscreenImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
}
Graphics2D ig2 = mOffscreenImage.createGraphics();
ig2.setClip(g.getClip());
super.paint(ig2, c);
ig2.dispose();
Graphics2D g2 = (Graphics2D)g;
g2.drawImage(mOffscreenImage, mOperation, 0, 0);
}
@Override
public void applyPropertyChange(PropertyChangeEvent pce, JLayer l) {
if ("blur".equals(pce.getPropertyName())) {
l.repaint();
}
}
}
I still have 2 problems:
In the link above events are relative to mouse only. How can I manage the keyboard events?
How can I create a "gray out" effect in place of blur?
It requires a recursive call.
import java.awt.*;
import javax.swing.*;
public class DisableAllInContainer {
public void enableComponents(Container container, boolean enable) {
Component[] components = container.getComponents();
for (Component component : components) {
component.setEnabled(enable);
if (component instanceof Container) {
enableComponents((Container)component, enable);
}
}
}
DisableAllInContainer() {
JPanel gui = new JPanel(new BorderLayout());
final JPanel container = new JPanel(new BorderLayout());
gui.add(container, BorderLayout.CENTER);
JToolBar tb = new JToolBar();
container.add(tb, BorderLayout.NORTH);
for (int ii=0; ii<3; ii++) {
tb.add(new JButton("Button"));
}
JTree tree = new JTree();
tree.setVisibleRowCount(6);
container.add(new JScrollPane(tree), BorderLayout.WEST);
container.add(new JTextArea(5,20), BorderLayout.CENTER);
final JCheckBox enable = new JCheckBox("Enable", true);
enable.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent ae) {
enableComponents(container, enable.isSelected());
}
});
gui.add(enable, BorderLayout.SOUTH);
JOptionPane.showMessageDialog(null, gui);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
new DisableAllInContainer();
}
});
}}
I used the following function:
void setPanelEnabled(JPanel panel, Boolean isEnabled) {
panel.setEnabled(isEnabled);
Component[] components = panel.getComponents();
for(int i = 0; i < components.length; i++) {
if(components[i].getClass().getName() == "javax.swing.JPanel") {
setPanelEnabled((JPanel) components[i], isEnabled);
}
components[i].setEnabled(isEnabled);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With