0

在此处输入图像描述我有一个 JFrame(jf),在那个窗口中我得到了三个 JPanel。我在 JPanel 中有图形。当我按下键盘上的右箭头时,我想重新绘制这个图形。我在 JFrame 中添加了一个 keyListener。addKeyListener(this) -> JFrame 实现 KeyListener。

    if (arg0.getKeyCode() == KeyEvent.VK_RIGHT){
        start = System.currentTimeMillis();
        l.czas.addMinuty(1);
        aktualizuj();
    }

在每个面板中,我都调用 repaint,但是将调用此 repaint 和按下右箭头之间的时间很长。当我同时按多次右键时,程序将冻结,然后跳过一些步骤(和之间的图形)。我测量了 HITTING AN ARROW 和 Calling 之间的时间,例如代表时间的字符串。时间为0的地方是我多次按键的时刻。请帮我。

Paint component called  1   times
Before superPaintComponent      1734
After superPaintComponent       1734
Before drawing Time     1781
Paint component called  2   times
Before superPaintComponent      2953
After superPaintComponent       2953
Before drawing Time     2953
Paint component called  3   times
Before superPaintComponent      0
After superPaintComponent       0
Before drawing Time     0
Paint component called  4   times
Before superPaintComponent      0
After superPaintComponent       0
Before drawing Time     0
Paint component called  5   times
Before superPaintComponent      0
After superPaintComponent       0
Before drawing Time     16
rakowiecka.PNG
Paint component called  6   times
Before superPaintComponent      0
After superPaintComponent       0
Before drawing Time     0
Paint component called  7   times
Before superPaintComponent      0
After superPaintComponent       0
Before drawing Time     0
Paint component called  8   times
Before superPaintComponent      0
After superPaintComponent       0
Before drawing Time     16
placuniilubelskiej.PNG
Paint component called  9   times
Before superPaintComponent      15
After superPaintComponent       15
Before drawing Time     15
Paint component called  10  times
Before superPaintComponent      0
After superPaintComponent       0
Before drawing Time     0
Paint component called  11  times
Before superPaintComponent      0
After superPaintComponent       0
Before drawing Time     0
placzbawiciela.PNG
Paint component called  12  times
Before superPaintComponent      0
After superPaintComponent       0
Before drawing Time     0
**IT GOES ON...................**

public void aktualizuj(int nrPrzystanku){
        this.nrPrzystanku = nrPrzystanku;   
        repaint();
    }

    @Override
    public void paintComponent(Graphics g) {
        NR++;
        System.out.println("Paint component called\t" + NR + "\ttimes");
        System.out.println("Before superPaintComponent\t\t" + (System.currentTimeMillis() - GlowneOkno.start));
        super.paintComponent(g);
        System.out.println("After superPaintComponent\t\t" + (System.currentTimeMillis() - GlowneOkno.start));
        int Height = (int) d.getHeight(), Width = (int) d.getWidth();
    //  System.out.println("PAINT W InfoLiniaPanel");
        Font f = new Font(Font.SANS_SERIF,Font.BOLD, (4 *Height/10));
        g.setFont(f);
    //  System.out.println(Height);
        //rysowanie numeru linii
        g.drawString(linia.nr + "", Width/10, Height/3);
        //rysowanie czasu
        Font f1 = new Font(Font.SANS_SERIF,Font.BOLD, 2 * Height/18);
        g.setFont(f1);
        System.out.println("Before drawing Time\t\t" + (System.currentTimeMillis() - GlowneOkno.start));
        g.drawString(linia.czas +" ", Width/10 +  g.getFontMetrics(f).stringWidth(linia.nr+"") + Width/10, Height/3);
        //kierunek
    //  System.out.println(linia.kurs.get(linia.kurs.size() -1 ).kierunek);
        g.setFont( new Font(Font.SANS_SERIF,Font.BOLD,1 *Height/20));
        g.drawString(linia.kurs.get(linia.kurs.size() -1 ).kierunek + "",
                 Width/10 + g.getFontMetrics(f).stringWidth(linia.nr+"") + Width/10,
                 Height/3 - g.getFontMetrics(f1).getAscent() /*g.getFontMetrics(f1).getHeight()*/ );
    //      System.out.println(g.getFontMetrics(f1).getHeight());
        //nastepny przystanek
    //  System.out.println(linia.kurs.get(nrPrzystanku)); //TRZEBA ZMIENIC NA JAKIS INDEKS ZEBY SZLA SYMULKACJA!!!!!!
        //NAJLEPIEJ DAC POLE OBECNY PRZYSTANEK W KLASIE LINIA
        g.drawString("Następny przystanek:" , Width/10, Height/3 + g.getFontMetrics().getHeight() + Height/10);
        g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,1 *Height/18));

        if( nrPrzystanku +1 < Linia.trasa.length)
            g.drawString(linia.kurs.get(nrPrzystanku + 1).nazwa+"", Width/10, Height/3 + g.getFontMetrics().getHeight()*12/6 + Height/10);
        else
            g.drawString("Ostatni postój", Width/10, Height/3 + g.getFontMetrics().getHeight()*12/6 + Height/10);
    }
4

2 回答 2

0

我写了一个非常快速的测试。它绘制一个大图像(650x975)并绘制一些文本(时间)。

我试着想一些我可以在短时间内做的最耗时的动作,所以绘制图像和绘制透明组件是我能想到的最好的两个......

它产生以下输出

示例图像

(不按比例)。

我基本上在图像窗格中添加了一个“右键”操作,并在按下键时发送了一个重绘请求。

哪个输出这个...

Update
[ImagePane] Time since paint request: 0:0:0.49
[TimePane] Time since paint request: 0:0:0.58
Update
[ImagePane] Time since paint request: 0:0:0.0
[TimePane] Time since paint request: 0:0:0.1
Update
.
.
.

基本上:

  • Update从击键的动作事件中打印出来。
  • ImagePanepaintComponent在方法结束时被转储ImagePane
  • TimePanepaintComponent在方法结束时被转储TimePane

持续时间是从动作事件发生的时间开始计算的,即在其他任何事情之前

从我的时间来看,我看不出有什么大问题,实际上我可以在时间更新之间按几次右键

这是测试代码...

框架:

public class TestFrame extends JFrame {

    public TestFrame() {

        setLayout(new BorderLayout());
        ImagePane imagePane = new ImagePane();
        imagePane.setLayout(new BorderLayout());
        imagePane.add(new TimePane());
        imagePane.setFocusable(true);

        add(imagePane);

        pack();
        setLocationRelativeTo(null);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        InputMap im = imagePane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        ActionMap am = imagePane.getActionMap();
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "Right");
        am.put("Right", new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent e) {

                System.out.println("Update");

                Test.isTesting = true;
                Test.startTime = new DateTime();

                invalidate();
                repaint();

            }

        });

        imagePane.requestFocusInWindow();

    }

    public static void main(String[] args) {
        TestFrame jf = new TestFrame();

    }
}

图像窗格...

public class ImagePane extends JPanel {

    private BufferedImage background;


    public ImagePane() {

        try {
            background = ImageIO.read(getClass().getResource("/1246.jpg"));
        } catch (IOException ex) {

            ex.printStackTrace();

        }

    }

    @Override
    public Dimension getPreferredSize() {

        return new Dimension(background.getWidth(), background.getHeight());

    }

    @Override
    protected void paintComponent(Graphics g) {

        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;

        int width = getWidth() - 1;
        int height = getHeight() - 1;

        int x = (width - background.getWidth()) / 2;
        int y = (height - background.getHeight()) / 2;

        g2d.drawImage(background, x, y, this);

        if (Test.isTesting) {

            DateTime endTime = new DateTime();
            Duration duration = new Duration(Test.startTime, endTime);

            System.out.println("[ImagePane] Time since paint request: " + Test.toString(duration));

        }

    }

}

时间窗格...

public class TimePane extends JPanel {

    public TimePane() {

        setOpaque(false);

    }

    @Override
    public Dimension getPreferredSize() {

        FontMetrics fm = getFontMetrics(getFont());
        String text = DateFormat.getTimeInstance().format(new Date());

        return new Dimension(fm.stringWidth(text), fm.getHeight());
    }

    @Override
    protected void paintComponent(Graphics g) {

        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;

        FontMetrics fm = g2d.getFontMetrics();

        String text = DateFormat.getTimeInstance().format(new Date());

        int width = getWidth() - 1;
        int height = getHeight() - 1;

        int x = (width - fm.stringWidth(text)) / 2;
        int y = ((height - fm.getHeight()) / 2) + fm.getAscent();

        g2d.setColor(Color.WHITE);
        g2d.drawString(text, x, y);

        if (Test.isTesting) {

            DateTime endTime = new DateTime();
            Duration duration = new Duration(Test.startTime, endTime);

            System.out.println("[TimePane] Time since paint request: " + Test.toString(duration));

        }

    }
}

和测试实用程序类

public class Test {

    public static final PeriodFormatter PERIOD_FORMATER = new PeriodFormatterBuilder().printZeroAlways().
                    appendHours().appendSeparator(":").
                    appendMinutes().appendSeparator(":").
                    appendSeconds().appendSeparator(".").
                    appendMillis().toFormatter();

    public static DateTime startTime;
    public static boolean isTesting = false;

    static String toString(Duration duration) {

        return duration == null ? "[invalid duration]" : duration.toPeriod().toString(PERIOD_FORMATER);

    }
}

现在,我使用Joda Time来计算持续时间(对不起,我已经为它准备好了代码)

显然,您需要获得自己的图像。

于 2012-08-18T05:36:13.863 回答
0

首先
尝试注释System.out.println执行任何打印的每个不必要 或任何不必要的语句,console因为此类语句也会减慢应用程序的速度,我遇到过打印语句会增加应用程序响应时间的情况。

其次
尝试工作线程和摆动工人

于 2012-08-18T05:40:42.483 回答