Skip to main content

How to make 2 children being painted in one paint ?

10 replies [Last post]
Anonymous

I have the following structure: 2 JScrollPanes on Left and Right side of the vertical JSplitPane, 2 JTables - one on each JScrollPane and, external to the JSplitPane, vertical JScroll to controll both tables vertical scrolling.
When I move the scroll an event handler calculates and then applys new coordinates to both JScrolPane's viewports. As a result JTables gets repainted one after another and the delay between each paint event is clearly visible. How to remove this effect and make tables being repainted without the visible delay?
Thanks.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Anonymous

Hi Zander

Now I know why not JViewports - no table column headers. So, if I'll have to render them separately inside additional JPanels then I'll also have to take care on horizontal scrolling, which I expect to cause similar delay problems as I have with vertical.
JScrollPane synchronizes table with the header the way, that you see no delay in between header and table while scrolling horizontally. I guess the component applies internaly some smart rendering I'm looking for.

Piotr

Anonymous

Hi Shannon,

You can see the code above in the previous post. You can test it's efficiency by replacing my small JTableLeft with JTreeTable example from SUN article on JTreeTable - the one with the model based on file system and attach jTableRight to the same model, which is the original idea. Thanks.

Anonymous

Hi there

Finally there's a sollution. First I modified JScrollPane.paintChildren() so it can be disabled by JScrollPane.setDuringScroll(true) to prevent automatic repaint after Viewport's location change. Then, in scrollBar event handler I do the following:
[code]Point p = new Point(0, evt.getValue());
JScrollLeft.setDuringScroll(true); //In scroll mode
JScrollRight.setDuringScroll(true);//In scroll mode
JScrollLeft.getViewport().setViewPosition(p);
JScrollRight.getViewport().setViewPosition(p);
JScrollLeft.invalidate(); // mark as Dirty region
JScrollRight.invalidate(); // mark as Dirty region
JScrollLeft.setDuringScroll(false); //out of scroll mode
JScrollRight.setDuringScroll(false);//out of scroll mode
this.repaint(); //this = top level container
[/code]
The solution is based on RepaintManager's ability to cumulate multiple "Dirty" regions into one and then paint it in one step. May be this is not the best approach but it works.

Piotr.

Message was edited by: Piotr

viravan
Offline
Joined: 2003-06-23
Points: 0

I haven't read all of your posts but it seems to me that your problem can be easily solved by looking at the scrollbar's [b]isAdjusting[/b] method -- by skipping the screen update while the scrollbar is adjusting should eliminate the need to constantly repaint and synchronize the two panels.

;o)

V.V.

Anonymous

Thanks viravan,

While examinating your suggestion I've found something I should had found at the beginning - that it is possible to link 2 JScrollPanes to one JScrollBar by JScrollPane.setVerticalScrollBar(). It appeared, that this solves the problem in a much easier way -> JAVA takes care on the synchronization itself. Thanks for pointing me in the right direction. ;-)

zander
Offline
Joined: 2003-06-13
Points: 0

Why 2 JScrollpanes to contain the jtables? I think you need JViewport instances for that..
This enables you to call viewPort.setViewPosition(p) to move the JTable a bit more instead of working your way around a JScrollPane

Additionally; there are 3 rendering modes for viewports; see JViewport.setScrollMode.

Anonymous

Probably you're right. I do not need all of the JScrollPane automatics on scroll bars. What I need is a scrollable container for tables. Since I'm quite a new to JAVA JScrollPane was an easy choice. I'll try JViewport tomorrow. Thanks.

shan-man
Offline
Joined: 2006-02-17
Points: 0

Hi Piotr,

If you could post a minimal [u]runnable[/u] test case, it will help us find an answer. If possible, please try and reduce your code to only that required to display the problem.

Oh, and please wrap it in [ code] and [/ code] blocks (without the spaces). ;)

Thanks!
Shannon

Anonymous

This is a minimum ;-). On fast machine with such a small model the negative effect is almost invisible, but I have to work with quite a big tables.

[code]import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JTable;
import javax.swing.JSplitPane;
import javax.swing.JScrollPane;
import java.awt.Point;
public class Main extends javax.swing.JFrame {
private JSplitPane jSplit;
private JScrollPane jScrollLeft, jScrollRight;
private JScrollBar jScrollBar1;
private JTable jTableLeft, jTableRight;
public Main() {
this.setBounds(0, 0, 400, 300);
jSplit = new JSplitPane();
jScrollBar1 = new JScrollBar();
jScrollLeft = new JScrollPane();
jScrollRight = new JScrollPane();
jTableLeft = new JTable();
jTableRight = new JTable();
jScrollBar1.setMaximum(300);
jScrollBar1.setMinimum(0);
this.getContentPane().add(jSplit, java.awt.BorderLayout.CENTER);
this.getContentPane().add(jScrollBar1, java.awt.BorderLayout.EAST);
jSplit.setLeftComponent(jScrollLeft);
jSplit.setRightComponent(jScrollRight);
jSplit.setDividerSize(2);
java.awt.Color cw = new java.awt.Color(255,255,255);
jTableLeft.setBackground(cw);
jTableRight.setBackground(cw);
jTableRight.setAutoCreateColumnsFromModel(true);
jTableLeft.setAutoCreateColumnsFromModel(true);
jTableRight.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{"1","1"},{"2","2"},{"3","3"},{"4","4"},
{"5","5"},{"6","6"},{"7","7"},{"8","8"},
{"9","9"},{"1","1"},{"2","2"},{"3","3"},
{"5","5"},{"6","6"},{"7","7"},{"8","8"},
{"9","9"},{"1","1"},{"2","2"},{"3","3"},
},
new String [] {"Title 1", "Title 2"}
));
jTableLeft.setModel(jTableRight.getModel());
jScrollLeft.setViewportView(jTableLeft);
jScrollRight.setViewportView(jTableRight);
Point p1 = new Point(jScrollLeft.getViewport().getViewPosition());
Point p2 = new Point(jScrollRight.getViewport().getViewPosition());
jScrollBar1.setUnitIncrement(jTableRight.getRowHeight());
jScrollRight.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
jScrollRight.setVerticalScrollBarPolicy(javax.swing.JScrollPane.VERTICAL_SCROLLBAR_NEVER);
jScrollLeft.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
jScrollLeft.setVerticalScrollBarPolicy(javax.swing.JScrollPane.VERTICAL_SCROLLBAR_NEVER);

jScrollBar1.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
public void adjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {
jScrollAdjustmentValueChanged(evt);
}
});

addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
exitForm(evt);
}
});
pack();
}
private void jScrollAdjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {
Point p1 = new Point(0, evt.getValue());
jScrollLeft.getViewport().setViewPosition(p1);
jScrollRight.getViewport().setViewPosition(p1);
}
public static void main(String[] args) {new Main().setVisible(true);}
private void exitForm(java.awt.event.WindowEvent evt) {System.exit(0);}
}[/code]

zander
Offline
Joined: 2003-06-13
Points: 0

Please edit your message and remove the space in the [ code ] tag.
It should become colored and all...