1

I'm trying to add a custom scrollable JComponent to a JFrame.

JScrollPane sp = new JScrollPane(hg);
frame.getContentPane().add(sp, BorderLayout.CENTER);

hg is my custom component.

The problem is that my custom component is not displayed. However, if I do this:

hg.setBounds(0, 0, 800, 600);

Then it will be displayed. But of course I don't want to set size explicitly. I want it to fit in the center of the frame.

In my custom JComponent class, I override getPreferredSize():

private Dimension computePreferredSize() {
    return new Dimension((int) (this.getParent().getSize().width * scale),
            (int) (this.getParent().getSize().height * scale));
}

public Dimension getPreferredSize() {
    Dimension d = computePreferredSize();
    System.out.println("Dimension: " + d); // prints reasonable output: Dimension: java.awt.Dimension[width=1201,height=805]
    return d;
}

But this doesn't seem to have any effect. Even if I return a fixed dimension directly:

public Dimension getPreferredSize() {
    return new Dimension(800, 600);
}

This doesn't work either.

I also added println in my ComponentUI's paint() method, but nothing is printed, so I think for some reason paint() is not called. I think the reason why is that my custom component's size defaults to zero, and I'm not sure how to let it adjust its own size.

So my question is: why my JComponent is not displayed by default, and what I should do to make it automatically fit into the center of the JFrame?

Thank you!

Derek Chiang
  • 3,330
  • 6
  • 27
  • 34
  • For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Dec 02 '12 at 04:05
  • Andrew, thanks for telling me about it!! – Derek Chiang Dec 02 '12 at 04:42
  • 1
    You mention a `paint()` method. Two things: (1) it's better to override `paintComponent` than `paint` because it lets Swing paint borders and stuff; (2) that should be `paint(Graphics g)`, right? If not, then `paint()` will never be called. This is why [@Override](http://docs.oracle.com/javase/7/docs/api/java/lang/Override.html) is useful. – wchargin Dec 02 '12 at 05:18
  • Hello @WChargin, what I did was I implemented my own ComponentUI and overrided paint(Graphics, JComponent). According to my research this is essentially equivalent to overriding paintComponent() of JComponent. Also, since I'm able to display my custom component by explicitly setting a size, I think this is not the major problem. – Derek Chiang Dec 02 '12 at 05:42

1 Answers1

4

In the class that defines hg, override getPreferredSize() to return your component's preferred size. Examples may be found here and here. The rationale and some important caveats are discussed here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • 1
    Depending on content, also consider implementing [`Scrollable`](http://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane.html#scrollable). – trashgod Dec 02 '12 at 04:35
  • Hello trashgod, thanks for the prompt response! However I have already overriden the method but it doesn't work. Please see my edited question for details. I have also implemented Scrollable. – Derek Chiang Dec 02 '12 at 04:47
  • Does it work in the examples cited? Are you using [`pack()`](http://docs.oracle.com/javase/tutorial/uiswing/components/frame.html) and [`invokeLater()`](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html)? Definitely use `@Override`. Please edit your question to include your [sscce](http://sscce.org/). – trashgod Dec 02 '12 at 15:40
  • Thanks a lot for help. I'm using invokeLater() but not pack(). But when I call pack() on frame I actually get exceptions... I posted the exceptions [here](http://pastebin.com/xQjRmbzY), could you take a look? – Derek Chiang Dec 02 '12 at 23:34
  • It looks like your implementation of `Scrollable` is throwing a `NullPointerException`. Be sure to include it in your [sscce](http://sscce.org/). – trashgod Dec 02 '12 at 23:45
  • I was trying to provide a SSCCE but found myself unable to reproduce the bug when I cut down a large chunk of code, and yet I still can't locate where the bug exactly is..... my exact source code is [here](https://www.dropbox.com/sh/2wbx79qs4cxk7ru/GvJgvyfFvO), and the only GUI-related code is in the GUI package. The main class is MainWindow.java. My custom component is JHexagonalGrid.... would you please scan through my code and tell me what could possibly go wrong? Thank you so much!! – Derek Chiang Dec 03 '12 at 01:45
  • That's _way_ beyond the scope of SO, but `getGraphics()` is a likely culprit. See also this [answer](http://stackoverflow.com/a/8185020/230513). – trashgod Dec 03 '12 at 10:54
  • Thanks a lot for pointing me to that! I will do more research. – Derek Chiang Dec 04 '12 at 03:01