1

スクロールする画像を含むプログラムを作成していますが、ボタンが押された場合に画像を更新する方法がわかりません (たとえば、画像に緑色の楕円を追加します)。画像を JScrollPane に挿入するとスクロールできますが、ボタンをクリックしても画像は更新されません。(コードの詳細) コードは次のとおりです。

public class PegMaster extends JPanel implements ActionListener {

    //Note: not complete code
    public PegBox[] pegbox = new PegBox[9];

    public static Dimension size = new Dimension(520, 500);

    public BufferedImage canvas;
    public Graphics2D g2d;
    public JScrollPane scroller;
    JPanel panel;
    private Canvas window;

    JScrollPane pictureScrollPane;

    public PegMaster() {
        JButton button = new JButton("test");
        button.addActionListener(this);
        add(button);

        canvas = new BufferedImage((int)size.getWidth()-30, 75 * GUESSES, BufferedImage.TYPE_INT_RGB);
        g2d = canvas.createGraphics();
        for(int i = 0;i<=pegbox.length-1;i++) {
           pegbox[i] = new PegBox(i, g2d);
        }
        window = new Canvas(new ImageIcon(toImage(canvas)), 1);
        //Class Canvas is a Scrollable JLabel to draw to (the image)
        pictureScrollPane = new JScrollPane(window);
        pictureScrollPane.setPreferredSize(new Dimension((int)size.getWidth()-10, (int)size.getHeight()-20));
        pictureScrollPane.setViewportBorder(BorderFactory.createLineBorder(Color.black));
        add(pictureScrollPane);

        //adds the scrollpane, but can't update the image in it
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createGUI();
                //just adds the scrollpane
            }
        });
    }

    public void paint(Graphics g) {
        super.paint(g);

        for(int i = 0;i<=pegbox.length-1;i++) {
            //pegbox[i] = new PegBox(i);
            pegbox[i].draw(g2d);
        }
        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }   
        //tried re-making the scrollpane, didn't work.
        //window = new Canvas(new ImageIcon(toImage(canvas)), 1);
        //pictureScrollPane = new JScrollPane(window);
        //pictureScrollPane.setPreferredSize(new Dimension((int)size.getWidth()-10 (int)size.getHeight()-20));
        //pictureScrollPane.setViewportBorder(BorderFactory.createLineBorder(Color.black));
        //tried imageupdate: pictureScrollPane.imageUpdate(canvas, 0, 0, 0 (int)size.getWidth()-10, (int)size.getHeight()-20);
        //remove(pictureScrollPane);
        //tried this: pictureScrollPane.revalidate();
        repaint();
    }
}
4

3 に答える 3

6

まず、Canvas重いコンポーネントを使用しないでください。長期的に問題が発生するだけです。またはのいずれJComponentかを使用してください。JPanel

次に、オーバーライドしないで、代わり paintに使用してください。ボーダーや子コンポーネントなどの描画など、多くの作業を行います。やりたいことに対して、ペイント階層内の適切なレイヤーにあるので、使用する方が良いです。paintComponentpaintpaintComponent

Thread.sleep第 3に、イベント ディスパッチ スレッドでのような呼び出しは絶対に行わないでください。これにより、イベント キューが一時停止し、イベントへの応答が停止するため、プログラムが停止しているように見えます。

repaint第 4 に、ペイント メソッド内で( invalidaterevalidateまたは再描画要求を発生させる可能性のあるメソッド) を決して呼び出さないでください。単純に CPU を使い果たし、プロセスを強制終了することになります。

第 5 に、メソッドが提供されていませんactionPerformed。これは、おそらくすべてのアクション (および問題) が存在する場所です。window.repaint()おそらく(逆の順序で)呼び出す必要があると思いますがwindow.invalidate()、このコードで使用を提供していないため、それは単なる推測です...

于 2012-09-15T00:06:20.953 に答える
3

画像を表示するこのクラスを試してください。これは、JScrollPane

public class ImagePanel extends JPanel {

    public Image img;

    public ImagePanel(Image img){
        this.img = img;
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawImage(img, 0, 0, this);
    }

}

このクラスを に追加しJScrollPaneます。repaint()更新するには、画像参照を変更してコンポーネントのメソッドを呼び出すだけです

于 2012-09-15T01:31:15.540 に答える
0

上記の解決策は私の目的を解決しなかったので、これを調査して見つけまし。全体の例については、リンクをたどってください。リンクが変更された場合に参照するコードを追加しました。

public class ScrollablePicture extends JLabel
                           implements Scrollable,
                                      MouseMotionListener {

private int maxUnitIncrement = 1;
private boolean missingPicture = false;

public ScrollablePicture(ImageIcon i, int m) {
    super(i);
    if (i == null) {
        missingPicture = true;
        setText("No picture found.");
        setHorizontalAlignment(CENTER);
        setOpaque(true);
        setBackground(Color.white);
    }
    maxUnitIncrement = m;

    //Let the user scroll by dragging to outside the window.
    setAutoscrolls(true); //enable synthetic drag events
    addMouseMotionListener(this); //handle mouse drags
}

//Methods required by the MouseMotionListener interface:
public void mouseMoved(MouseEvent e) { }
public void mouseDragged(MouseEvent e) {
    //The user is dragging us, so scroll!
    Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
    scrollRectToVisible(r);
}

public Dimension getPreferredSize() {
    if (missingPicture) {
        return new Dimension(320, 480);
    } else {
        return super.getPreferredSize();
    }
}

public Dimension getPreferredScrollableViewportSize() {
    return getPreferredSize();
}

public int getScrollableUnitIncrement(Rectangle visibleRect,
                                      int orientation,
                                      int direction) {
    //Get the current position.
    int currentPosition = 0;
    if (orientation == SwingConstants.HORIZONTAL) {
        currentPosition = visibleRect.x;
    } else {
        currentPosition = visibleRect.y;
    }

    //Return the number of pixels between currentPosition
    //and the nearest tick mark in the indicated direction.
    if (direction < 0) {
        int newPosition = currentPosition -
                         (currentPosition / maxUnitIncrement)
                          * maxUnitIncrement;
        return (newPosition == 0) ? maxUnitIncrement : newPosition;
    } else {
        return ((currentPosition / maxUnitIncrement) + 1)
               * maxUnitIncrement
               - currentPosition;
    }
}

public int getScrollableBlockIncrement(Rectangle visibleRect,
                                       int orientation,
                                       int direction) {
    if (orientation == SwingConstants.HORIZONTAL) {
        return visibleRect.width - maxUnitIncrement;
    } else {
        return visibleRect.height - maxUnitIncrement;
    }
}

public boolean getScrollableTracksViewportWidth() {
    return false;
}

public boolean getScrollableTracksViewportHeight() {
    return false;
}

public void setMaxUnitIncrement(int pixels) {
    maxUnitIncrement = pixels;
}
于 2015-08-24T16:04:50.117 に答える