Friday, June 20, 2008

Swinging with JScrollPanes

Let me tell you - Swing sucks - big time. Especially some parts of it - I am looking at you JScrollPane. I have fought with this monstrosity for a bunch of days, trying to coerce it do host a JPanel with some random content in it in a reliable and non-ugly manner, that would show the whole content of a panel and not clip it in weird ways.

Out of all approaches I tried, this brutal one seems to do the right thing for me, with least hassle:

class ScrollablePanel extends JPanel
implements Scrollable {
private static final int A_LOT = 100000;

// cheating obviously but this seems to do the
// right thing, so whatever :). Let's hope some
// time will pass till people routinely have
// monitors 100000 pixels high
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(1, A_LOT);
}

public int getScrollableUnitIncrement(
Rectangle visibleRect,
int orientation,
int direction) {
return 1;
}

public int getScrollableBlockIncrement(
Rectangle visibleRect,
int orientation,
int direction) {
return 1;
}

public boolean getScrollableTracksViewportWidth() {
return true;
}

public boolean getScrollableTracksViewportHeight() {
return false;
}
}

And then

ScrollablePanel panel = new ScrollablePanel();
// now put whatever you want in the panel,
// or even add stuff to it later, after putting it
// in the srcoll
JScrollPane scroll = new JScrollPane();
scroll.setViewportView(panel);

2 comments:

  1. But what's wrong with it? Why it sucks? What I see is a short and understandable code that works (well, I don't know that but I suppose you didn't write a shit :)

    Any idea why it sucks? :)

    ReplyDelete
  2. @przemek: making JScrollPane display its hosted JComponent properly (i.e. non-zero height, non-infinite width) is a challenge :)

    A challenge for you:
    Try to get me the code that would display JEditorPane in a JScrollPane in such a way that:
    (1) would preferrably display it without scrollers in a container of limited width, (2) but no higher than X (i.e. if higher than X then show vertical scroller), (3) but if the "natural" height is less then X - display at "natural height (less than X).

    If you can do it (and the code for doing it is not an utter hack), then I am buying you beer.

    And the code I have posted - Why do I have to cheat and pretend that the natural height of my JPanel is 100k pixels? WTF is this?

    ReplyDelete