Win a copy of The Java Performance Companion this week in the Performance forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

paint method problem

 
Javed Inamdar
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi ,

I have problem with paint method in following Java file. Drawing logic is not given there but drawing logic is taking 1 minute to execute. Problem here is that whenever i try to move scrollbar entire drawing get called once again. I want it to be executed only once and result should be scrollable.

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.HeadlessException;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;

public class Canvasext extends JFrame
{

private JPanel jContentPane = null;
private JScrollPane jScrollPane = null;
private JPanel jPanel = null;
private JViewport port =null;

public Canvasext() throws HeadlessException
{
super();
initialize();
}

private JScrollPane getJScrollPane()
{
if (jScrollPane == null)
{
jScrollPane = new JScrollPane();
jScrollPane.setBounds(new Rectangle(4, 3, 516, 371));
port=new JViewport();
port.setView(getJPanel());

jScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
jScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
jScrollPane.getHorizontalScrollBar().setBlockIncrement(10);
jScrollPane.getHorizontalScrollBar().setMinimum(0);
jScrollPane.getHorizontalScrollBar().setMaximum(1000);
jScrollPane.updateUI();
jScrollPane.setViewport(port);
}
return jScrollPane;
}

private JPanel getJPanel()
{
if (jPanel == null)
{
jPanel = new JPanel()
{
public void paintComponent(Graphics g)
{
super.paintComponent(g);
//Entire Drawing logic will appear here
g.drawString("Hi.........", 100, 100);
System.out.println("Hi.........");
}
};
jPanel.setPreferredSize(new Dimension(2000000000, 500));
}
return jPanel;
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Canvasext thisClass = new Canvasext();
thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
thisClass.setVisible(true);
}
});
}

private void initialize()
{
this.setSize(533, 411);
this.setContentPane(getJContentPane());
this.setTitle("JFrame");
}

private JPanel getJContentPane()
{
if (jContentPane == null)
{
jContentPane = new JPanel();
jContentPane.setLayout(null);
jContentPane.add(getJScrollPane(), null);
}
return jContentPane;
}
}
 
Rob Spoor
Sheriff
Pie
Posts: 20552
57
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Javed Inamdar:
I have problem with paint method in following Java file. Drawing logic is not given there but drawing logic is taking 1 minute to execute. Problem here is that whenever i try to move scrollbar entire drawing get called once again. I want it to be executed only once and result should be scrollable.

You can't solve the being painted every time, because that's just how Java's painting of ANY component works. As soon as the window is (re)activated, moved, resized or the contents of a scroll pane are moved, it is redrawn.

The thing you have to question yourself is: why does it take a full minute to execute a simple thing as drawing a frame? I've done quite some extensive painting at times but that still did not lead to any slowing down of the entire application.
 
Javed Inamdar
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually while drawing I am reading values/arguments for drawing from 30 MB text file thats why it is taking time. But is there any other way to achieve this........
 
Rob Spoor
Sheriff
Pie
Posts: 20552
57
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Read the data one time, during the constructor or when first painting, and cache that data. Then every next time use that data.

Pseudo code for the loading when first painting:
 
Brian Cole
Author
Ranch Hand
Posts: 907
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Javed Inamdar:
Actually while drawing I am reading values/arguments for drawing from 30 MB text file thats why it is taking time. But is there any other way to achieve this........


You could read the data once and draw onto a BufferedImage, then in paint() simply call drawImage().

If the drawing area is resizable you'll have to decide how you want to handle painting after resize. You could read the data again, mess with image scaling, or come up with something else.
 
Javed Inamdar
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Rob Prime
I had tried caching of data ........but it is giving OutOfMemory Error
 
Javed Inamdar
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Brian Cole

yeh........its working fine but one problem here.
As we are using buffering here it is giving Java Heap Space error for big image.

Another thing, I am drawing on JPanel and we can specify length of JPanel in integers. But here I want length of JPanel/image in long as length of drawing is greater than (2^31)-1
 
Nathan Pruett
Bartender
Posts: 4121
IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're definitely going to get OutOfMemoryError if you think you need a long to specify the size of the panel you want to render the image on. Why do the images need to be this big? You're going to need to do some work to provide scaling and/or only render the portion of the image that is currently visible.
 
Javed Inamdar
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am drawing on JPanel and saving drawing over JPanel as bufferedImage and from next time i am loading that image on JPanel so drawing multiple time problem is solved......But My drawing's legth is too big, maxlength of JPanel is also short for that. so problem of drawing as well as creating bufferedimage is occuring there...........please tell me rigth way to do this
 
Javed Inamdar
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How to do rendering of portion of image?
 
Brian Cole
Author
Ranch Hand
Posts: 907
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Javed Inamdar:
I am drawing on JPanel and saving drawing over JPanel as bufferedImage and from next time i am loading that image on JPanel so drawing multiple time problem is solved......But My drawing's legth is too big, maxlength of JPanel is also short for that. so problem of drawing as well as creating bufferedimage is occuring there.


How big an image are you using? Earlier you mentioned "Java Heap Space error for big image" and "length of drawing is greater than (2^31)-1" but what kind of monitor does your user have where you need an image (or panel) that is two billion pixels wide? Even if your user has three 30" 2560x1600 screens, that's still less than 10,000 pixels total width.

Originally posted by Javed Inamdar:
How to do rendering of portion of image?


Graphics has several drawImage() methods, some of which are designed to do this.
 
Javed Inamdar
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi.......

1. Create class extending JFrame
2. create JscrollPane
3. create JPanel, setSize(10000,1000);
4. draw some drawing on JPanel
5. add Jpanel to Jscrollpane
6. add JScrollPane
7. create image of JPanel
8. save that image and see how big is this?

I hope you will understand my problem after doing this?
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic