Summary: The original JScrollNavigator
uses the Swing opacity
property to render a convenient green NavBox
over a scaled thumbnail of the component in an adjacent JScrollPane
. Because it extends JPanel
, the (shared) UI delegate’s use of opacity
conflicts with that of the scrollable component. The images seen in edit 5 above typify the associated rendering artifact, also shown here. The solution is to let NavBox
, JScrollNavigator
and the scrollable component extend JComponent
, as suggested in the second addendum below. Each component can then manage it’s own properties individually.
I see no unusual rendering artifact with your code as posted on my platform, Mac OS X, Java 1.6. Sorry, I don’t see any glaring portability violations.
A few probably irrelevant, but perhaps useful, observations.
-
Even if you use
setSize()
, appropriately in this case, you should stillpack()
the enclosingWindow
.f.pack(); f.setSize(300, 200);
-
For convenience,
add()
forwards the component to the content pane.f.add(nav, BorderLayout.WEST);
-
Prefer
StringBuilder
toStringBuffer
. -
Consider
ComponentAdapter
in place ofComponentListener
.
Addendum: As suggested here, I got somewhat more flexible results using RenderingHints
instead of getScaledInstance()
as shown below. Adding a few icons makes it easier to see the disparate effect on images and text.
editPane.insertIcon(UIManager.getIcon("OptionPane.errorIcon"));
editPane.insertIcon(UIManager.getIcon("OptionPane.warningIcon"));
...
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Component view = jScrollPane.getViewport().getView();
BufferedImage img = new BufferedImage(view.getWidth(),
view.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D off = img.createGraphics();
off.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
off.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
view.paint(off);
Graphics2D on = (Graphics2D)g;
on.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
on.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
on.drawImage(img, 0, 0, getWidth(), getHeight(), null);
}
Addendum secundum: It looks like the JPanel
UI delegate is not cooperating. One workaround is to extend JComponent
so that you can control opacity. It’s only slightly more work to manage the backgroundColor
. NavBox
and JScrollNavigator
are also candidates for a similar treatment.
jsp.setViewportView(new JComponent() {
{
setBackground(Color.red);
setBorder(BorderFactory.createLineBorder(Color.BLACK, 16));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
});