This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 29684 - Cannot test form extending JComponent - unpaintable
Summary: Cannot test form extending JComponent - unpaintable
Status: VERIFIED FIXED
Alias: None
Product: guibuilder
Classification: Unclassified
Component: Code (show other bugs)
Version: 3.x
Hardware: PC Linux
: P3 blocker (vote)
Assignee: issues@guibuilder
URL:
Keywords:
Depends on:
Blocks: 28007
  Show dependency tree
 
Reported: 2002-12-21 00:28 UTC by Jesse Glick
Modified: 2003-02-04 13:26 UTC (History)
0 users

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
Screenshot (7.46 KB, image/png)
2002-12-21 00:28 UTC, Jesse Glick
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jesse Glick 2002-12-21 00:28:10 UTC
Start IDE - I used [dev dec 20], MDI, JDK
1.4.1_01, Linux.

Create class in default package in sampledir,
Test1.java:

public class Test1 extends javax.swing.JComponent {}

Compile it.

Open Options dialog and expand to Templates ->
Java GUI Forms.
Copy JPanel. Paste and name the copy Test2.
Right-click it and
edit it. Change its superclass to Test1. Save.

Create a Test2 from template in sampledir. Call it
Test3.

Add a JLabel to the center of the form.

Press the Test Form button.

Resize the form to be a bit larger, and move it
around. It does
not repaint properly and looks garbled (see
screenshot).

Change superclass of Test1 to be
javax.swing.JPanel. Recompile
it.

Create a Test2 from template in sampledir. Call it
Test4.

Add a JLabel to the center of the form.

Press the Test Form button.

Resize the form to be a bit larger, and move it
around. It looks
fine.

---

What is so special about JPanel? Turning on
double-buffering and
opacity in the component superclass did not make
any difference.
Could not have getUIClassID return PanelUI and
call updateUI in
constructor, as that threw CCE (not a BasicPanelUI
expects a
JPanel). Does the form module (VisualReplicator
perhaps??) expect
a JPanel specifically?
Comment 1 Jesse Glick 2002-12-21 00:28:35 UTC
Created attachment 8382 [details]
Screenshot
Comment 2 Tomas Pavek 2003-01-02 15:37:09 UTC
JPanel has PanelUI which does the painting - i.e. paints the
background at least. JComponent alone does no painting, it is expected
you implement it in subclass (e.g. by providing ComponentUI or
implementing paintComponent method). So that's why you see the strange
paint "effects". (If you put the component into a JFrame and executed
it, you would see similar repaint problems as in "Test Form" mode.)

In this case (using form editor) I guess you want to create a form
serving as a container for other components - which is the right case
where JPanel should be used. JComponent is too general for this, and
JPanel has almost no overhead...
Comment 3 Tomas Pavek 2003-01-02 15:45:18 UTC
So this does not seem to be problem in form editor...
Comment 4 Jesse Glick 2003-01-06 19:54:43 UTC
I'm afraid I don't follow the reasons for closing this. At least,
there is not enough information to help solve the problem with
TopComponent encountered in issue #28007.

1. BasicPanelUI does no painting. Do you mean rather that by virtue of
having a UI at all (called from updateUI) JPanel will call repaint
upon setUI, but JComponent does not? But this is only when it is
added, not every time. Or that paintComponent checks for ui != null,
and ComponentUI.update first clears the component if isOpaque()?

2. "If you put the component into a JFrame and executed it, you would
see similar repaint problems as in "Test Form" mode." - not true,
actually, I tried it and it looked fine:

import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class Test3 extends Test1x {
    public Test3() {initComponents();}
    private void initComponents() {
        jLabel1 = new javax.swing.JLabel();

        setLayout(new java.awt.BorderLayout());

        jLabel1.setText("jLabel1");
        add(jLabel1, java.awt.BorderLayout.CENTER);

    }
    // Variables declaration - do not modify
    private javax.swing.JLabel jLabel1;
    // End of variables declaration
    public static void main(String[] args) {
        JFrame f = new JFrame("hello");
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.getContentPane().add(new Test3());
        f.pack();
        f.show();
    }
}
class Test1x extends javax.swing.JComponent {}

Maybe it worked for some other reason, I don't know.

3. "I guess you want to create a form serving as a container for other
components - which is the right case where JPanel should be used" -
no, as mentioned in issue #28007 all I wanted to do (and the reason I
found & reported this bug) is that testing a form based on
TopComponent using the Test Form button does not work, though calling
open() with internal execution works fine. If there is something wrong
with TopComponent, I would appreciate advice on how to correct it. My
best guess is that TopComponent.java should be changed a bit:

public TopComponent() {
    setDoubleBuffered(true); // necessary??
    setOpaque(true);         // what about this?
    updateUI();
    // rest of constructor as before...
}
public void updateUI() {
    setUI(UIManager.getUI(this));
}
public String getUIClassID() {
    return "PanelUI";
}

Does this sound right? Making it extend JPanel sounds too extreme as
it is a public API class. Anyway I could imagine some TopComponent
subclass wishing to use a different kind of UI entirely, and this
(AFAIK) works currently so it should not be prevented by making
updateUI cast to PanelUI.
Comment 5 Tomas Pavek 2003-01-16 19:05:48 UTC
Okay, I'll try to workaround it in the "Test Form" feature. More
comments...

> 1. BasicPanelUI does no painting.
> ...
> Or that paintComponent checks for ui != null, and
> ComponentUI.update first clears the component if
> isOpaque()?

I believe that's it. ComponentUI.update() is called always from
component before the component is painted. The method by default fills
the background if the component is opaque. So this is done
automatically for any component having ComponentUI set.

> 2. "If you put the component into a JFrame and executed
> it, you would see similar repaint problems as in "Test
> Form" mode." - not true, actually, I tried it and it
> looked fine:

Well, when I tried it, I set opaque (and double buffering) to true. If
the component is opaque, the JFrame's content pane does no painting at
all as it is whole overlapped by an opaque component - but that
component "fails" in this case. If it is not opaque, the content pane
paints the background
and it looks ok (your example).

So I think the reason why TopComponent has no painting problems is
that it is always added to a container which paints the background for
it. And the reason why it fails when testing form? I have a suspicion
that the "tested" form component is put into a JFrame via
setContentPane method - so being probably the very top component which
simply must paint the background. This can be hopefully fixed - by
using JFrame.getContentPane().add(comp) instead of
JFrame.setContentPane(comp) for non-opaque components.

> ...
> public void updateUI() {
>     setUI(UIManager.getUI(this));
> }
> public String getUIClassID() {
>     return "PanelUI";
> }
>
> Does this sound right? ...

This would not work as UIManager instantiates BasicPanelUI which
requires the component to be JPanel (so some CCE appears).

> ... Making it extend JPanel sounds too extreme as it is a
> public API class. ...

Oh, I overlooked that we primarily want to extend TopComponent in this
case, sorry...


So I suggest not to use any setOpaque, double buffering, updateUI etc.
code, I'll try to do the fix in form editor as I described.
Comment 6 Tomas Pavek 2003-01-17 10:54:03 UTC
Done.
Comment 7 Jesse Glick 2003-01-19 18:32:30 UTC
Thanks! Seems to be working fine in [dev jan 17].