How to smoothly scroll JFrame in Java
•
Java
A JFrame in my java application contains a JPanel, and I create some drawing objects at runtime The problem is that when scrolling JFrame for large numbers, the scrolling speed slows down and the scroll bar does not move smoothly Please note that I am using graphics 2D objects and redrawing on the scroll operation
Is there any way to smooth the scrolling action of JFrame
This is part of the code
public class DiagramPanel implements MouseListener{ int click=0; Point p1; Point p2; private Dimension panelDimension; .... // variables public void go() { p1 = new Point(); p2 = new Point(); JFrame f = new JFrame(); f.setVisible(true); f.setDefaultCloSEOperation(JFrame.DISPOSE_ON_CLOSE); f.setSize(1200,500); panelx = new DiaPanel(); panelx.setOpaque(true); panelx.setBackground(Color.white); panelx.setAutoscrolls(true); panelx.addMouseListener(this); JScrollPane scrollPane = new JScrollPane(); // scrollPane.add(panelx); ClassRectangle tempRect = null; for (ClassRectangle rect : this.classRectangles) { tempRect = rect; } Rectangle rect = new Rectangle(); rect.setBounds(tempRect.getW() - 100,1000,tempLife.getEndpointY() * 500); panelDimension = new Dimension(0,0); for (ClassRectangle rectx : classRectangles){ panelDimension.width=rectx.getW()+300; } for (LifeLine life : lifeLines) { panelDimension.height=life.getEndpointY()+300; } scrollPane.setViewportView(panelx); panelx.computeVisibleRect(rect); JScrollPane scrollPane1 = new JScrollPane(panelx); panelx.setPreferredSize(panelDimension); panelx.repaint(); panelx.revalidate(); p1.x=0; p1.y=0; p2.y=panelDimension.height; p2.x=panelDimension.width; f.add( scrollPane1); scrollPane.revalidate(); f.setBackground(Color.white); } public DiagramPanel(ArrayList<Rectangle> classRectangles,ArrayList<Pair> pairs,ArrayList<Line> lines,ArrayList<Life> meth) { // constructing obj of DrawingPanel Here } public class SeqDiaPanel extends JPanel { /** * */ private static final long serialVersionUID = 1L; public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d2 = (Graphics2D) g; g2d2.setColor(Color.orange); //grid for (int i = 0; i < panelDimension.height; i++) { g2d2.drawLine(0,0 + i * 5,panelDimension.width+1000,0 + i * 5); } for (int i = 0; i < panelDimension.width; i++) { g2d2.drawLine(0 + i * 5,0 + i *5,panelDimension.height+300); } g2d2.setColor(Color.black); // objects .......... some objects here } } // draw Lines stroke drawingstroke = new Basicstroke(2,Basicstroke.CAP_BUTT,Basicstroke.JOIN_BEVEL,new float[] { 5 },0); // stroke drawingstroke = new Basicstroke(); Graphics2D g2d = (Graphics2D) g; g2d.setstroke(drawingstroke); for (Line life : lines) { g2d.drawLine(life.getStartpointX(),life.getStartpointY(),life.getEndpointX(),life.getEndpointY()); panelDimension.height=life.getEndpointY()+300; } // draw methodLfe for (Object2 ml1 : Obj2) { g2d2.fill3DRect(ml1.StartX(),ml1.getmethodStartY(),ml1.getBreadth(),ml1.getEndX(),true); } } } // tobeused public int calculateWidth(String name){ Font font = new Font("Serif",Font.BOLD,12); FontMetrics metrics = new FontMetrics(font){ /** * */ private static final long serialVersionUID = 1L;}; int tempInt2=SwingUtilities.computeStringWidth( metrics,name); tempInt2=tempInt2+10; return tempInt2; } /*public class MouseClick implements MouseListener{ Point p = new Point(0,0); @Override public void mouseClicked(MouseEvent evnt) { p.x=evnt.getX(); p.y=evnt.getY(); System.out.println("MouseClicked @"+p.x+":"+p.y); } @Override public void mouseEntered(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseReleased(MouseEvent arg0) { // TODO Auto-generated method stub } }*/ @Override public void mouseClicked(MouseEvent evnt) { click++; if(click==1){ //Point p= new Point(); p1.x=evnt.getX(); p1.y=evnt.getY(); // System.out.println("MouseClicked1 @"+p1.x+":"+p1.y); } if(click==2){ p2.x=evnt.getX(); p2.y=evnt.getY(); //System.out.println("MouseClicked2 @"+p2.x+":"+p2.y); click=0; if(p1.x<p2.x&&p1.y<p2.y){ panelx.repaint(); } else{ } }/*else{ p1.x=0; p1.y=0; p2.x=panelDimension.width+500; p2.y=panelDimension.height+700; }*/ } @Override public void mouseEntered(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseReleased(MouseEvent arg0) { // TODO Auto-generated method stub } }
Solution
Why not put the graphics2d drawing in the (large) bufferedimage and display it in the label of the scroll pane? Something like this (animation, 5000x5000px):
import java.awt.*; import java.awt.event.*; import java.awt.image.BufferedImage; import java.util.Random; import javax.swing.*; public class BigScrollImage { BigScrollImage() { final int x = 5000; final int y = 5000; final BufferedImage bi = new BufferedImage(x,y,BufferedImage.TYPE_INT_RGB); Graphics2D g1 = bi.createGraphics(); g1.setColor(Color.BLACK); g1.fillRect(0,x,y); g1.dispose(); final JLabel label = new JLabel(new ImageIcon(bi)); ActionListener listener = new ActionListener() { Random rand = new Random(); @Override public void actionPerformed(ActionEvent ae) { Graphics2D g2 = bi.createGraphics(); int x1 = rand.nextInt(x); int x2 = rand.nextInt(x); int y1 = rand.nextInt(y); int y2 = rand.nextInt(y); int r = rand.nextInt(255); int g = rand.nextInt(255); int b = rand.nextInt(255); g2.setColor(new Color(r,g,b)); g2.drawLine(x1,y1,x2,y2); g2.dispose(); label.repaint(); } }; Timer t = new Timer(5,listener); JScrollPane scroll = new JScrollPane(label); JFrame f = new JFrame("Big Scroll"); f.setDefaultCloSEOperation(JFrame.DISPOSE_ON_CLOSE); f.add(scroll); f.pack(); f.setSize(800,600); f.setLocationByPlatform(true); f.setVisible(true); t.start(); } public static void main(String[] args) { SwingUtilities.invokelater(new Runnable(){ @Override public void run() { new BigScrollImage(); } }); } }
It tries to draw 200 lines per second and seems to scroll smoothly here
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
二维码