如何在Java中平滑滚动JFrame

如何在Java中平滑滚动JFrame

本文介绍了如何在Java中平滑滚动JFrame的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Java应用程序中有一个JFrame,其中包含 JPanel ,其中我在运行时创建了一些绘图对象。问题是滚动 JFrame 为大数字滚动减慢并且滚动条不能平滑移动。请注意我正在使用 Graphics 2D 对象并在滚动操作上执行重绘

I have a JFrame in my Java application that contains a JPanel where I have some drawing objects created at run-time. The problem is while scrolling the JFrame for large figures the scrolling slows up and scroll bar does not move smoothly. Please note I am using Graphics 2D object and doing repaint on scroll action.

有没有办法平滑 JFrame 的滚动动作。

Is there any way of smoothing the scrolling action of JFrame.

以下是代码的一部分

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, 0, 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, 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, 0, 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

    }
}


推荐答案

为什么不将 Graphics2D 绘图放入(大) BufferedImage 并将其显示在滚动窗格的标签中?像这样的东西(动画,5000x5000px):

Why not put the Graphics2D drawing in a (large) BufferedImage and display it in a label in a scroll-pane? Something like this (animated, 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, 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();
            }
        });
    }
}

它试图每秒绘制200行,并且似乎在这里顺利滚动。

It tries to draw 200 hundred lines per second, and seems to scroll smoothly here.

这篇关于如何在Java中平滑滚动JFrame的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 07:17