0

ここに画像の説明を入力してください私はJFrame(jf)を持っていて、そのウィンドウで3つのJPanelを取得しました。そのJPanelsにグラフィックがあります。キーボードの右矢印を押したときに、このグラフィックを再描画したいと思います。JFrameにkeyListenerを追加しました。addKeyListener(this)->JFrameはKeyListenerを実装します。

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

すべてのパネルでリペイントと呼びますが、このリペイントと右矢印を押すまでの時間が長くなります。同時に右キーを何度も押すと、プログラムがフリーズし、いくつかの手順(およびその間のグラフィックス)がスキップされます。HITTINGANARROWからCallingまでの時間を測定しました。たとえば文字列は時間を表します。時間がないところは、キーを何度も押した瞬間です。私を助けてください。

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) を描画し、テキスト (時間) を描画します。

短時間で実行できる最も時間のかかるアクションをいくつか考えてみました。そのため、イメージの描画と透明コンポーネントのペイントが、私が思いつくことができる 2 つの最良の方法です...

次の出力が生成されます

サンプル画像

(縮尺どおりではありません)。

基本的に、画像ペインに「右キー」アクションを追加し、キーが押されたときに再描画要求を送信しました..

これを出力するのは...

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));

        }

    }
}

そして Test ユーティリティクラス

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.printlnconsole

次に、ワーカースレッドとスイングワーカーを
試してください

于 2012-08-18T05:40:42.483 に答える