Where is the viewport "connected to" the scrollbar in JScrollPane? - java

I may need to create my own JScrollPane subclass. I've looked at the JScrollPane and ScrollPaneLayout source and believe I understand how it works. However, I can't see where the scrollbar(s) (when present) are "connected to" the viewport. In other words, I was expecting to see the viewport listening to the scrollbar to determine the displayed view coordinates, but find nothing about that. Will someone explain and/or point to me to the code that is doing this?

The last thing I thought to examine were the listeners on the JScrollPane. Doing so led me to javax.swing.plaf.basic.BasicScrollPaneUI.Handler, which is where all the "wiring" happens. So that's the answer to the original question - but it points out an unfortunate reality: if I attempt to subclass JScrollPane to work as I intend, it seems unlikely that I'll be able to do so without breaking PLaF (with my current understanding of PLaF).
Edit: I found this link to be helpful in understanding swing.plaf.*, although it's quite old: http://www.oracle.com/technetwork/java/architecture-142923.html

Related

Swing: problems with component's background

I've got a problem, that swing components in different parts of program have sometimes wrong background. For example this or this.
As I mentioned, the bug is not permanent and it can appear in one place one time and never after. But still there are some places, where I can randomly reproduce it. Unfortunately, I don't see any solutions.
Has anyone some ideas how can I fix it?
If you set your components to non-opaque (I think the call is setOpaque(false)), that will let the background colour of the component that it is on top of show through.
in addition to what Paul said, there's the question if you use self made components.
Such components should take care of their complete occupied region (or at least the invalidated regions) in the paint callback. An error seen quite often that leads to strange artifacts when moving or resizing is that only "important" parts are repainted, for example a string to be shown, without drawing the background.
In this case, anything previously blitted ther will show through.

Programmatically Scroll an SWT Table horizontally

Similar question, but not exactly the same.
table.showColumn() is helpful, but the scrolling only has the granularity of the column width. But I want a more precise control of the scroll location.
Consider the following use case. I have two tables that I know are of the same width and have the same column widths. And I want to implement some kind of a scroll synchronizer so that when the user scrolls one table (horizontally), the other table scrolls to the same location.
EDIT:
On the Eclipse forum there seems to be the same question and some working ideas, but no resolution.
EDIT:
I discovered this behavior on Windows
The method setOrigin(x,y) in ScrolledComposite should help:
Scrolls the content so that the specified point in the content is in the top left corner. If no content has been set, nothing will occur. Negative values will be ignored. Values greater than the maximum scroll distance will result in scrolling to the end of the scrollbar.
I'm afraid I can't get a satisfying result in Windows Vista/7 either, but felt I was getting close.
I believe you will have to grab the Table's horizontal scroll bar by using table.getHorizontalBar(). Then, you can specify scrollbar.setSelection() to make it move to a specified position.
This is where I get stuck. Somehow, you have to notify either the Table or the ScrollBar that the value has changed. I've tried everything from update() to notifyListener(), but no dice. It seems that it is merely a matter of laying out, but layout() doesn't have any effect, either.
Incidentally, bear in mind that the ScrollBar's parent (type Scrollable) is not a ScrolledComposite like I had expected, but is actually the Table itself.
I hope this gives you some ideas and helps you find a solution. If so, please let me know, since it's bugging me now, too!
Having poked around in the ScrollBar source a bit, it looks like there are numerous (windows) bugs that have been overcome at one point or another. This may be another, though you didn't mention your OS, nor did Paul, so it's hard to tell.
All the "change the scroll bar position" functions end up calling SetScrollInfo which is package private. I suspect that the intention is for this to actually update things the way you want.
None of that solves your problem. Thankfully the same source also hints at a solution:
Slider.
You'd have to reimplement all the scrollbar behavior within slider, but once done, that should give you the control (har) you want. Hopefully. OTOH, you may run into exactly the same OS bug (if bug it be), and be back at square one.
At THAT point, you definitely register it as an Eclipse UI bug.
PS: Have you searched the Eclipse Bugzilla for anything similar? Poking around a bit turned up this bug related to the scroll bar being out of sync with a tree view in the Navigator (on PC Linux-Motif, but working fine in Windows). I suspect you'll find similar issues if you dig a bit more.

Creating a left-hand margin for a JEditorPane text box

Edit - in short, what I'm looking for is a reliable way to add a left margin to a JEditorPane (read on for the issues I'm having if you'd like).
I am trying to style some text in a JEditorPane, and have been fairly successful. The only problem I'm facing is that it seems impossible to create a margin.
Basically, I've extended PlainView and overridden the drawUnselectedText method. For now I just have it coloring the text red and changing the font. I've also overridden the drawSelectedText method to color the text.
This works consistently, whether text is selected or not, regardless of cursor position etc. - as long as I don't have a margin set.
However if I set a margin for the JEditorPane, the JEditorPane only works most of the time. The only case where it doesn't work is when a selection is made starting at the left-most character of any line. In that case, the margin is simply ignored and the selected text appears to the far left of the JEditorPane.
I know this is a pretty specific issue that most other people probably haven't experienced, and I have found nothing on the net about this, but I'm hoping someone here will have a solution.
Any ideas? Even anything that would allow me to set a margin using some other method than what I'm doing would be extremely helpful.
I gave up on finding an elegant solution to this problem. Basically I created a hack which tests whether or not the conditions exist where the bug will occur (selection from left, etc), and if they do it adjusts the rendering of the text.
I really don't like hacks as they are often bad for portability and maintainability, but this seems to work, so I suppose I'll abstract it away and hope it doesn't break anything.
In any case, it's working which is the key point. I didn't receive any answers, but I'm sure there are some people who at least tried to think of something, so thanks :)
Btw - if someone can come up with an elegant solution I will still accept that instead of my own answer (I can't anyways for two days).
Edit: This is one reason I like Java. Hacks are less likely to cause portability issues - even though this is related to rendering (it works through interaction with a Graphics object), it should still work on any OS.

Netbeans 6.7.1 mainPanel resizing problem

I've created a small gui app in Netbeans. As I was adding in some buttons and text areas the mainPanel resized itself. Now it is really wide [probably 4x as wide as I want] but when I try to drag the edge in it won't resize back down. If I drag it out, making it bigger, it takes that change. I would just like to return the mainPanel back to a reasonable size. Not sure what I'm doing wrong here. I've tried to change the min size, max size, and preferred size settings for the mainPanel with no success. I've even tried to change the menuBar & statusPanel settings at the same time as the mainPanel [thinking that one of them was making the others too big] without success.
Any ideas?
Netbeans does do really stupid things like that sometimes, and I generally get around them using either of these two methods:
First thing to try is to change the layout used. Try the Grid Bag Layout, or any of the others and see if you get better results.
If that doesn't work, then probably the easiest thing to do is to change stuff in the code. You will notice that Netbeans automatically adds a call to initComponents(); in the constructor (you have to switch to Code view from Design view). And if you look at initComponents, it will have a whole heap of auto-generated code to create the GUI. Do NOT edit this, because it's just a matter of time before Netbeans overwrites your changes. What I do is to create a new method initComponentsFix, and call that immeidtaely after initComponents in the constructor. In initComponentsFix, I would add the code to resize the component to the preferred size, and any other things you you want to fix.
BTW I empathise with you - Netbeans' GUI editor is still in need of much work. However, it's code auto-generation is still very useful, so I wouldn't recommend coding the GUI the good ol' fashioned way. That's why I'm advocating using it up until you start felling its limitations, after which you "take control".
There is also a third way, which I would not recommend, is to edit the file that Netbeans stores the Design view in, which is basically shares the same file name as your frame's class' source code, except with a .form extension.
This file is XML, and is pretty easy to edit. I don't recommend this because it is sorta going around the back door, but as a last resort, you can still try it.

How are Swing components internally created, laid out, repainted, notified of events, ...?

I wonder if there's a good documentation (or a (viewable) ebook) about
the lifecycle of Swing components.
Is "lifecycle" the correct term, anyway?
I hope to find answers to question such as:
How, when, in which order painting methods are called?
How, when, which events are called by whom?
What is the exact sequence of method calls for component creation?
From time to time I encounter strange behavior of my apps, for example:
ComponentListener's resize event is called before setVisible(true)
(so that root pane has negative dimensions!)
Some components are laid out correctly only after resizing the JFrame by hand
Changing a super class from JPanel to JLayeredPane causes my class
to be laid out differently inside an other container.
And lot of other strange things...
I had the same question long ago.
I can't believe how hard is to find a good resource about this topic in the internet.
Fortunately I've found this link and now I have it in my bookmark with golden tag. :)
A Swing Architecture Overview
Once you have a good grasp of how they work conceptually you will be able to fix most of the problems you mention.
I hope it helps.

Categories