3

コンポーネントが画面よりも大きく、その一部が表示されていません (スクロールバーを使用します)。
電話がかかってきたとき、paintComponent(g)どのエリアをペイントすればよいかをどのように知ることができますか?

4

3 に答える 3

1

これがあなたの言いたいことかどうかはわかりませんが、問題は、 の呼び出しを受けるたびに を呼び出す必要があるrepaint()ことJScrollPaneです。そうしないと、 の更新が に表示されません。paintComponent(Graphics g)JPanelJPanelJScrollPane

また、使用したいですJScrollBarか(または用語を混同した可能性があります)?私はお勧めしますJScrollPane

2秒ごとに色が変わるグリッドを持つ小さな例を作成しましたJPanel(赤から黒へ、またはその逆)。JPanel/Grid は ; よりも大きいですJScrollPane。インスタンスを呼び出す必要があるかどうかに関係なくrepaint()JScrollPaneそうしないとグリッドの色が変わりません。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class Test {

    public static void main(String[] args) throws Exception {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Test().createAndShowUI();
            }
        });
    }

    private void createAndShowUI() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        initComponents(frame);
        frame.setPreferredSize(new Dimension(400, 400));
        frame.pack();
        frame.setVisible(true);
    }

    private void initComponents(JFrame frame) {
        JScrollPane jsp = new JScrollPane();
        jsp.setViewportView(new Panel(800, 800, jsp));
        frame.getContentPane().add(jsp);
    }
}

class Panel extends JPanel {

    private int across, down;
    private Panel.Tile[][] tiles;
    private Color color = Color.black;
    private final JScrollPane jScrollPane;

    public Panel(int width, int height, JScrollPane jScrollPane) {
        this.setPreferredSize(new Dimension(width, height));
        this.jScrollPane = jScrollPane;
        createTiles();
        changePanelColorTimer();//just something to do to check if its repaints fine
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int i = 0; i < across; i++) {
            for (int j = 0; j < down; j++) {
                g.setColor(color);
                for (int k = 0; k < 5; k++) {
                    g.drawRect(tiles[i][j].x + k, tiles[i][j].y + k, tiles[i][j].side - k * 2, tiles[i][j].side - 2 * k);
                }
            }
        }
        updateScrollPane();//refresh the pane after every paint
    }

    //calls repaint on the scrollPane instance
    private void updateScrollPane() {
        jScrollPane.repaint();
    }

    private void createTiles() {
        across = 13;
        down = 9;
        tiles = new Panel.Tile[across][down];

        for (int i = 0; i < across; i++) {
            for (int j = 0; j < down; j++) {
                tiles[i][j] = new Panel.Tile((i * 50), (j * 50), 50);
            }
        }
    }

    //change the color of the grid lines from black to red and vice versa every 2s
    private void changePanelColorTimer() {
        Timer timer = new Timer(2000, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (color == Color.black) {
                    color = Color.red;
                } else {
                    color = Color.black;
                }
            }
        });
        timer.setInitialDelay(2000);
        timer.start();
    }

    private class Tile {

        int x, y, side;

        public Tile(int inX, int inY, int inSide) {
            x = inX;
            y = inY;
            side = inSide;
        }
    }
}

クラスで行にPanelコメントを付けても、グリッドの色が変わることはありません。updateScrollPane();paintComponent(Graphics g)

于 2012-09-29T15:55:49.583 に答える
0

すべての答えは間違っています。それで、質問が2年前のものであるという事実にもかかわらず、私は質問に答えることにしました.

g.getClipBounds()メソッド内で呼び出すのが正解だと思いますpaintComponent(Graphics g)。無効化され、再描画する必要がある領域のコントロールの座標系で四角形を返します。

于 2014-08-15T18:34:11.667 に答える