-1

ネットワーク対応の戦艦のようなゲームの GUI をプログラミングしています (私もそうです)。右クリックしてウェイポイントを設定すると、すべての mapLabels が消えて取得できません。これは、右クリックでサーバーに文字列を送信するだけで、表示自体にはまったく影響しないためです。panel.repaint(); を呼び出すと、pane.validate(); ウェイポイントを設定すると、すべてが再び表示されますが、パフォーマンスは信じられないほど遅くなります。

これは大量のコードであることは理解していますが、問題が FieldListener にあるとは想像できません。したがって、何を投稿すればよいかわかりません。他のものを見たい場合は、それを求めることができます...

問題の原因である可能性が最も高いコードの一部を次に示します。

/**
 * The listener for a field.
 * @author Andris
 *
 */
private class FieldListener implements MouseListener {

    private int[] xy;
    private int[] pressedPos = new int[] {-1,-1};


    @Override
    public void mousePressed(MouseEvent evt) {
        Field field = map.getField(xy[0],xy[1]);
        pressedPos = xy.clone();
        switch(evt.getButton()){
        case MouseEvent.BUTTON1://-------well, BUTTON1......
            break;
        case MouseEvent.BUTTON3:
            switch(selBtn){
            case 2://---------------this is the case
                client.Out("some string");// this sends to the server, nothing else...
                break;
            }
            break;
        }
    }

サーバーが応答した後、これが実行されます(異なるパッケージのまったく異なるクラスで、消えたフィールドはすべてプライベートです):

public class Server {
   client.Out(cfg.chat_server+"you have set a waypoint at ("+x+","+y+").");

public class ChatFrame extends JPanel {
    public void Out(String nextString){
        text.append(" "+nextString);
        text.append("\n");
        JScrollBar scroll = display.getVerticalScrollBar();
        if(!scroll.getValueIsAdjusting())scroll.setValue(Integer.MAX_VALUE);
    }

カスタムペイントメソッドは次のとおりです(ImageObserverが間違っている可能性があります):

private class MapLabel extends JLabel{ //------------- in MapFrame

    private Field field;
    private int[] xy;

    public void paint(Graphics g){
        Image image = getImageNsetToolTip();
        Graphics2D g2D=(Graphics2D)g;
        g2D.drawImage(image, 0, 0, actImgSize, actImgSize, this);
        g2D.setClip(0, 0, actImgSize, actImgSize);
        super.paint(g2D);
    }

    /**
     * gets the proper image and sets the tool-tip
     * @return
     */
    private Image getImageNsetToolTip(){
        Image result;
        String toolTip = "("+xy[0]+","+xy[1]+")";
        TileType type = field.getType();
        switch(type){
        case harbor:
            result=harborImg[0];
            break;
        case land: 
//------------------------------etc...


        this.setToolTipText(toolTip);
        return result;
    }

残りの一部を次に示します。

...lots of imports...

/**
 * This is the frame in which the GameMap is displayed.
 * @author Andris
 *
 */
@SuppressWarnings("serial")
public class MapFrame extends JPanel {

...lots of variables...

    /**
     * Creates the frame, but doesn't make it visible yet.
     * @param window the GameWindow in which this frame will be embedded.
     * @param client the client who runs this.
     */
    public MapFrame(GameWindow window, Client client){

...lots of variables initialized...

        panel = new JPanel();
        pane = new JScrollPane(panel,
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);


        buttons = new JButton[nButtons];
        buttonListener = new ButtonListener();
        for(int i=0; i<nButtons; i++){
            buttons[i] = new JButton(buttonTexts[i]);
            buttons[i].setName(buttonTexts[i].replace(' ', '_'));
            buttons[i].addActionListener(buttonListener);
            buttonPanel.add(buttons[i]);
        }
4

2 に答える 2

2

ペイントコードに問題があります

public void paint(Graphics g){
    Image image = getImageNsetToolTip();
    Graphics2D g2D=(Graphics2D)g;
    g2D.drawImage(image, 0, 0, actImgSize, actImgSize, this);
    g2D.setClip(0, 0, actImgSize, actImgSize);
    super.paint(g2D);
 }

前にペイントsuper.paintすると、以前にペイントしたものを一掃する可能性があります。これは、 、およびがpaint呼び出されるために発生します。paintComponentpaintBorderpaintComponents

のジョブの 1 つは、paintComponentペイント用のグラフィックス コンテキストを準備することです (クリーンアップ)。

また、クリップをいじらないでください。Swing での描画の仕組みにより、コンポーネントが物理的な境界を超えて描画できるようになるリスクがあります。paintクリップは、再描画マネージャーによって、呼び出される前にコンポーネントのサイズと等しくなるように設定されます。

代わりに、paintComponentカスタム ペインティングを実行するために使用する必要があります。

詳細については、Perofming カスタム ペインティングをご覧ください。

JLabelの機能の 1 つがJLabelアイコンを表示することであるのに、なぜ にカスタム イメージをペイントするのかという疑問が頭に浮かびます。

于 2013-05-09T21:03:33.330 に答える