Skip to main content

JXPanel vs JXLayer?

6 replies [Last post]
robross
Offline
Joined: 2003-06-13

Cross-posted on SwingLabs forum: http://forums.java.net/jive/thread.jspa?threadID=45004&tstart=0

Hi there. I'm a little confused. I thought for some reason that the JXLayer 3.0 was a replacement for JXPanel, but I'm beginning to suspect I am wrong about that. But if they are different projects, what is the difference between them? I am looking for some container that I can make semi-transparent (give it an alpha value) by calling a single method on the container, and having it apply to all child components. I see that JXPanel lets me do that. But I also need the container to be able to disable all its children,maybe with some cool drawing effects, also with a single call, like JXLayer can do. (Note I can do all of this myself in regular Swing, but I'm tired of manually doing it every time, and instead of writing my own yet-another-framework I'd like to start using existing code.)

So are these different projects? And if so, does anyone know if they work well together? Do I wrap a JXLayer in a JXPanel, or vice-versa, to get what I am looking for?

P.S. It's really great that there are all these tools and libraries for desktop Java, but it's also really hard to keep track of them all.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
justthemath
Offline
Joined: 2010-07-27

HI,

I am new to this forum and might be called an advanced beginner. I started to post on CodeRanch (http://forums.java.net/jive/forum.jspa?forumID=59) but I did not get much interest and this new post belongs here.

First, after using JXPanel with alpha < 1.0, the repaint when I resize the JFrame is horrendous when using Windows 7. There are some repaint issues on XP or XP Professional, but they might be listed as "acceptable, but not ideal".

Thus, I have created the following component using JXLayer. It behaves as a JXPanel when the alpha value is changed. The one difference is that when adding this component to the container, you add the jxLayer to the component by calling the method -- getJXLayer() instead of adding the component directly. The test program is also included. I would like any comments, specifically as to whether this component can be improved. Thanks in advance.

[code]
import java.awt.*;
import javax.swing.*;

import org.jdesktop.jxlayer.JXLayer;
import org.jdesktop.jxlayer.plaf.AbstractLayerUI;

public class FadingJPanel extends JPanel {
float alpha = 1.0f;
JXLayer jxLayer;

public FadingJPanel() {
super();
setOpaque(false);
jxLayer = new JXLayer(this);
AbstractLayerUI fadableLayerUI = new AbstractLayerUI() {
@Override
protected void paintLayer(Graphics2D g2,
JXLayer l) {
Graphics2D g2d = (Graphics2D) g2;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, alpha));
super.paintLayer(g2d, l);
}
};
jxLayer.setUI(fadableLayerUI);
}
public float getAlpha() {
return this.alpha;
}

public void setAlpha(float alpha) {
this.alpha = alpha;
this.repaint();
}

public JXLayer getJXLayer() {
return jxLayer;
}
}

[/code]

The test program is

[code]
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class FadingJPanelTestTwo extends JComponent {
private int iScreen = 66;
private int iLocation = 10;
JFrame frame = new JFrame();
Container contentPane = frame.getContentPane();
Font defaultFont = new Font("Bookman Old Style", 3, 20);
FadingJPanel fjp = new FadingJPanel();
JLayeredPane layerPane = new FilledJLayeredPane();

public FadingJPanelTestTwo() {
fjp.setLayout(new GridLayout(3, 1));
fjp.add(getJLabelWithBorder("I'm in a JXLayer!", Color.BLACK,
Color.YELLOW));
fjp.add(getJLabelWithBorder("I'm in a JXLayer!", Color.BLUE,
Color.WHITE));
fjp.add(getJLabelWithBorder("I'm in a JXLayer!", Color.BLACK,
Color.GREEN));
fjp.setAlpha(0.2f);

JPanel southButtonPanel = new JPanel();
southButtonPanel.setLayout(new GridLayout());
southButtonPanel.add(getSouthButton(" Alpha = 0.0 ", 0.0f));
southButtonPanel.add(getSouthButton(" Alpha = 0.2 ", 0.2f));
southButtonPanel.add(getSouthButton(" Alpha = 0.4 ", 0.4f));
southButtonPanel.add(getSouthButton(" Alpha = 0.6 ", 0.6f));
southButtonPanel.add(getSouthButton(" Alpha = 0.8 ", 0.8f));
southButtonPanel.add(getSouthButton(" Alpha = 1.0 ", 1.0f));

layerPane.add(getJLabelWithBorder("I'm just a plain jlabel (:",
Color.MAGENTA, Color.PINK));
layerPane.add(fjp.getJXLayer(), JLayeredPane.PALETTE_LAYER);

contentPane.add(layerPane, BorderLayout.CENTER);
contentPane.add(southButtonPanel, BorderLayout.SOUTH);

/*
* Below is the code to intialize and show the JFrame.
*/
boolean packFrame = false;
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = frame.getSize();
frameSize.height = (int) (iScreen * screenSize.height / 100);
frameSize.width = (int) (iScreen * screenSize.width / 100);
frame.setSize(frameSize);
frame.setLocation((screenSize.width - frameSize.width) / iLocation,
(screenSize.height - frameSize.height) / iLocation);
// frame.setLocationRelativeTo(null);
if (packFrame) {
frame.pack();
packFrame = true;
} else {
frame.validate();
}
frame.setVisible(true);
}

private JButton getSouthButton(String bLbl, final float alpha) {
JButton sbtn = new JButton(bLbl);
sbtn.setFont(defaultFont);
sbtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
fjp.setAlpha(alpha);
}
});
return sbtn;
}

public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new FadingJPanelTestTwo();
}
});
}

private JLabel getJLabelWithBorder(String text, Color c, Color bc) {
JLabel jlabel = new JLabel(text);
jlabel.setFont(new Font("Bookman Old Style", 3, 60));
jlabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
jlabel.setBorder(javax.swing.BorderFactory.createLineBorder(c, 40));
jlabel.setBackground(bc);
jlabel.setOpaque(true);
return jlabel;
}

private class FilledJLayeredPane extends JLayeredPane {
private static final long serialVersionUID = 1L;
/**
* Layout each of the components in this JLayeredPane so that they all
* fill the entire extents of the layered pane -- from (0,0) to
* (getWidth(), getHeight())
*/
@Override
public void doLayout() {
super.doLayout();
// Synchronizing on getTreeLock, because I see other layouts doing
// that.
// see BorderLayout::layoutContainer(Container)
synchronized (getTreeLock()) {
int w = getWidth();
int h = getHeight();
for (Component c : getComponents()) {
if (getLayer(c) == JLayeredPane.DEFAULT_LAYER) {
c.setBounds(0, 0, w, h);
c.doLayout();
}
if (getLayer(c) == JLayeredPane.PALETTE_LAYER) {
c.setBounds(0, 0, w + 2, h + 2);
c.doLayout();
}
}
}
}
}
}

[/code]

Message was edited by: justthemath

alexfromsun
Offline
Joined: 2005-09-05

Hello Rob

They are the different components, indeed,

JXPanel is a part of SwingX library, when JXLayer is a separate project.

JXPanel uses a custom RepaintManager which makes it possible to support translucency effects,

JXLayer's BufferedLayerUI also has the setAlpha() method, but it doesn't work out-of-the-box,

I don't use the same trick in JXLayer because it would be incompatible with JXPanel

so, if you need to set alpha for you components use JXPanel,

but when it comes to locking container with some cool effects JXLayer is the best choice

I haven't use these two components together, but I expect no problems

Thanks

alexp

robross
Offline
Joined: 2003-06-13

Would you recommend adding a JXPanel as a child of a JXLayer, or instead make the JXLayer a child of a JXPanel?

alexfromsun
Offline
Joined: 2005-09-05

Hello Rob

I'd recommend just using JXLayer without JXPanel
:-)

but if you really need to setAplha() for the container,
I would try adding JXLayer to JXPanel

Thanks
alexp

robross
Offline
Joined: 2003-06-13

Hmm, it seems unfortunate that the setAlpha method exists only in the BufferedLayerUI and not in the LockableUI. So if I want to use the LockableUI, I can't call setAlpha. I don't have enough experience using JXLayer (or even JXPanel for that matter) to know what situations they are designed to handle, but is there a reason setAlpha is not a method in say, AbstractLayerUI? Then all the LayerUI subclasses would have it. Or is there some inter-dependency that makes it not a good idea to have setAlpha in the LockableUI implementation?

alexfromsun
Offline
Joined: 2005-09-05

Hello Rob

> Hmm, it seems unfortunate that the setAlpha method exists only in the BufferedLayerUI and
>not in the LockableUI

Actually every subclass of the AbstractLayerUI has the getComposite(JXLayer) method
which can be overridden to apply any composite

But it may not be applicable to the LockableUI, because its implementation is very specific

Thanks
alexp