2015-12-08 2 views
1

У меня есть JFrame с маской границы, которая имеет два JPanel s. Один из JPanel в южной части кадра имеет несколько JButtons (номер n), а один показывает плату подключения - 4 (это для класса CS). По какой-то странной причине у меня есть странная ошибка, в которой анимации для кнопок отображаются в верхнем левом углу.Java Drawing Button Анимация в верхнем углу

enter image description here

Его довольно странно ошибка, я не эксперт на качелях я задавался вопросом, если он не имеет ничего общего со мной работает метод paint ([с repaint(), который я предполагаю, на другом потоке) в одном JPanel и actionPerformed в другом JPanel (что, я полагаю, есть в другом потоке), и в рендеринге есть конфликт или разупорядочение. Просто догадка.

Вот некоторые из кода GUI:

class Connect4GUI extends JFrame implements SetSpotInterface 
{ 
    private Connect4 connect4; 
    private Connect4PieceDisplay pieceDisplay; 
    public static final String DEFAULT_TITLE = "Connect 4"; 
    //... 
    public Connect4GUI(Connect4 connect4_, String title) 
    { 
     setTitle(title); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     connect4 = connect4_; 
     pieceDisplay = new Connect4PieceDisplay(this); 
     add(new Connect4ButtonDispencer(this), BorderLayout.SOUTH); 
     add(new Connect4PieceDisplay(this), BorderLayout.CENTER); 
     pack(); 
     setVisible(true); 
    } 
    public Connect4GUI(Connect4 connect4_) { 
     this(connect4_, DEFAULT_TITLE); 
    } 
    public Connect4GUI() { 
     this(new Connect4()); 
    } 
    //... 
} 

abstract class Connect4PanelComponent extends JPanel 
{ 
    public static final Connect4GUI DEFAULT_DISPLAY_WINDOW = null; 
    public final static Color DEFAULT_BACKROUND_COLOR = Color.YELLOW; 
    Connect4GUI displayGUI; 
    public Color backroundColor; 
} 

class Connect4PieceDisplay extends Connect4PanelComponent 
{ 
    XY offsetScaler, offsetModifier, pixelOffset, spacingModifier, spacingPixelOffset; 
    public final static XY DEFAULT_OFFSET_SCALER = new XY(5, 5); 
    public final static XY DEFAULT_OFFSET_MODIFIER = new XY(1, 1); 
    public final static XY DEFAULT_PIXEL_OFFSET = new XY(6, 6); 
    public final static XY DEFAULT_SPACING_MODIFIER = new XY(2, 2); 
    public final static XY DEFAULT_SPACING_PIXEL_OFFSET = new XY(0, 0); 
    public Connect4PieceDisplay(Connect4GUI displayGUI_, XY offsetScaler_, XY offsetModifier_, XY pixelOffset_, XY spacingModifier_, XY spacingPixelOffset_, Color backroundColor_) 
    { 
     super(); 
     displayGUI = displayGUI_; 
     offsetScaler = offsetScaler_; 
     offsetModifier = offsetModifier_; 
     pixelOffset = pixelOffset_; 
     spacingModifier = spacingModifier_; 
     spacingPixelOffset = spacingPixelOffset_; 
     backroundColor = backroundColor_; 

     setOpaque(true); 
     setBackground(backroundColor); 
    } 
    public Connect4PieceDisplay(Connect4GUI displayGUI_, XY offsetScaler_, XY offsetModifier_, XY pixelOffset_, XY spacingModifier_, XY spacingPixelOffset_) { 
     this(displayGUI_, offsetScaler_, offsetModifier_, pixelOffset_, spacingModifier_, spacingPixelOffset_, DEFAULT_BACKROUND_COLOR); 
    } 
    public Connect4PieceDisplay(Connect4GUI displayGUI_, XY offsetScaler_, XY offsetModifier_, XY pixelOffset_, XY spacingModifier_) { 
     this(displayGUI_, offsetScaler_, offsetModifier_, pixelOffset_, spacingModifier_, new XY(DEFAULT_SPACING_PIXEL_OFFSET)); 
    } 
    public Connect4PieceDisplay(Connect4GUI displayGUI_, XY offsetScaler_, XY offsetModifier_, XY pixelOffset_) { 
     this(displayGUI_, offsetScaler_, offsetModifier_, pixelOffset_, new XY(DEFAULT_SPACING_MODIFIER)); 
    } 
    public Connect4PieceDisplay(Connect4GUI displayGUI_, XY offsetScaler_, XY offsetModifier_) { 
     this(displayGUI_, offsetScaler_, offsetModifier_, new XY(DEFAULT_PIXEL_OFFSET)); 
    } 
    public Connect4PieceDisplay(Connect4GUI displayGUI_, XY offsetScaler_) { 
     this(displayGUI_, offsetScaler_, new XY(DEFAULT_OFFSET_MODIFIER)); 
    } 
    public Connect4PieceDisplay(Connect4GUI displayGUI_) { 
     this(displayGUI_, new XY(DEFAULT_OFFSET_SCALER)); 
    } 
    public Connect4PieceDisplay() { 
     this(DEFAULT_DISPLAY_WINDOW); 
    } 
    public void DefaultSetUpModifiers(int offset, int offsetModifier_, int spacing, int spacingPixel) 
    { 
     offsetScaler = new XY(offset, offset); 
     offsetModifier = new XY(offsetModifier_, offsetModifier_); 
     pixelOffset = new XY((offset + 1), (offset + 1)); 
     spacingModifier = new XY(spacing, spacing); 
     spacingPixelOffset = new XY(spacingPixel, spacingPixel); 
    } 
    public void paint(Graphics graphics) 
    { 
     final int X_DIMENTION = displayGUI.GetConnect4().dimentions.x; 
     final int Y_DIMENTION = displayGUI.GetConnect4().dimentions.y; 
     final int X_SPACING = (getWidth()/X_DIMENTION); 
     final int Y_SPACING = (getHeight()/Y_DIMENTION); 
     final int AMOUNT_OF_COLORS_IN_COLOR_MAP = displayGUI.colorMap.size(); 
     for(int i = 0; i < X_DIMENTION; ++i) 
     { 
      for(int j = 0; j < Y_DIMENTION; ++j) 
      { 
       final char CURRENT_SYMBOL = displayGUI.GetConnect4().GetSpot(i, j); 
       for(int o = 0; o < AMOUNT_OF_COLORS_IN_COLOR_MAP; ++o) 
       { 
        if(CURRENT_SYMBOL == displayGUI.colorMap.get(o).GetSymbol()) { 
         graphics.setColor(displayGUI.colorMap.get(o).GetColor()); 
         break; 
        } 
       } 
       graphics.fillOval(AttainXOffset(i), AttainYOffset(j), AttainXSpacing(), AttainYSpacing()); 
      } 
     } 
     repaint(); 
    } 
    public int AttainXOffset(int x) { 
     final int X_SPACING = (getWidth()/displayGUI.GetConnect4().dimentions.x); 
     return ((X_SPACING/DEFAULT_OFFSET_SCALER.x) + DEFAULT_PIXEL_OFFSET.x + (X_SPACING * DEFAULT_OFFSET_MODIFIER.x * x)); 
    } 
    public int AttainYOffset(int y) { 
     final int Y_SPACING = (getHeight()/displayGUI.GetConnect4().dimentions.y); 
     return ((Y_SPACING/DEFAULT_OFFSET_SCALER.y) + DEFAULT_PIXEL_OFFSET.y + (Y_SPACING * DEFAULT_OFFSET_MODIFIER.y * y)); 
    } 
    public int AttainXSpacing() { 
     final int X_SPACING = (getWidth()/displayGUI.GetConnect4().dimentions.x); 
     return ((X_SPACING/DEFAULT_SPACING_MODIFIER.x) + DEFAULT_SPACING_PIXEL_OFFSET.x); 
    } 
    public int AttainYSpacing() { 
     final int Y_SPACING = (getHeight()/displayGUI.GetConnect4().dimentions.y); 
     return ((Y_SPACING/DEFAULT_SPACING_MODIFIER.y) + DEFAULT_SPACING_PIXEL_OFFSET.y); 
    } 
} 

class Connect4ButtonDispencer extends Connect4PanelComponent implements ActionListener 
{ 
    public final static String DEFAULT_BUTTON_MESSAGE = ""; 
    public final static int DEPTH_OF_BUTTON_GRID = 1; 
    public JButton[] dispencerButtons; 
    public String buttonMessage; 
    public Connect4ButtonDispencer(Connect4GUI displayGUI_, Color backroundColor_, int amountOfDispencerButtons_, String buttonMessage_) 
    { 
     super(); 
     displayGUI = displayGUI_; 
     backroundColor = backroundColor_; 
     buttonMessage = buttonMessage_; 
     setLayout(new GridLayout(DEPTH_OF_BUTTON_GRID, amountOfDispencerButtons_)); 
     dispencerButtons = DefaultSetUpDispencerButtons(amountOfDispencerButtons_); 
     buttonMessage = buttonMessage_; 
     setOpaque(true); 
     setBackground(backroundColor); 
    } 
    public Connect4ButtonDispencer(Connect4GUI displayGUI_, Color backroundColor_, int amountOfDispencerButtons_) { 
     this(displayGUI_, backroundColor_, amountOfDispencerButtons_, DEFAULT_BUTTON_MESSAGE); 
    } 
    public Connect4ButtonDispencer(Connect4GUI displayGUI_, Color backroundColor_) { 
     this(displayGUI_, backroundColor_, displayGUI_.GetConnect4().dimentions.x); 
    } 
    public Connect4ButtonDispencer(Connect4GUI displayGUI_) { 
     this(displayGUI_, DEFAULT_BACKROUND_COLOR); 
    } 
    public Connect4ButtonDispencer() { 
     this(DEFAULT_DISPLAY_WINDOW); 
    } 
    public JButton[] DefaultSetUpDispencerButtons(int length) 
    { 
     dispencerButtons = new JButton[ length ]; 
     //What if I change something in between when I declare the array and the 'for' loop?// 
     final int AMOUNT_OF_DISPENCER_BUTTONS = dispencerButtons.length; 
     for(int i = 0; i < AMOUNT_OF_DISPENCER_BUTTONS; ++i) 
     { 
      dispencerButtons[ i ] = new JButton((buttonMessage + (i + 1))); 
      dispencerButtons[ i ].addActionListener(this); 
      add(dispencerButtons[ i ]); 
     } 
     return dispencerButtons; 
    } 
    public void actionPerformed(ActionEvent event) 
    { 
     final int AMOUNT_OF_DISPENCER_BUTTONS = dispencerButtons.length; 
     for(int i = 0; i < AMOUNT_OF_DISPENCER_BUTTONS; ++i) 
     { 
      System.out.println("A"); 
      if(dispencerButtons[ i ] == event.getSource()) 
      { 
       System.out.println("B"); 
       //...it could change dynamically especially when this is on a thread. #parinoi .// 
       final int Y_DIMENTIONS = displayGUI.GetConnect4().dimentions.y; 
       for(int j = (Y_DIMENTIONS - 1); j >= 0; --j) 
       { 
        if(displayGUI.GetConnect4().GetSpot(i, j) == Connect4.EMPTY_SPOT) 
        { 
         displayGUI.GetConnect4().SetSpot(i, j, displayGUI.turnSymbol); 
         displayGUI.ChangeTurn(); 
         break; 
        } 
       } 
       break; 
      } 
     } 
    } 
} 

Любое понимание или помощь по этому вопросу очень ценится! :)

Спасибо - ТФБ :-)

ответ

0
  1. Не называйте repaint() изнутри paint(...) как это приводит к
    • неконтролируемого анимации и
    • используя метод рисования для чего-то для которых он не был предназначен.
  2. Вы даже не должны быть переопределяющими красками, но должны быть переопределяющими paintComponent.
  3. И вот большая проблема: вы должны вызывать метод окраски супер в пределах вашей картины. Поэтому, если вы переопределяете paintComponent, вызовите метод super.paintComponent(...) внутри него.
+0

Благодарим за ответ! Могу ли я безопасно называть 'repaint' из' paintComponent' (который, похоже, работает, но теоретически он безопасен [?])? –

+0

@ Кристофер Грили: нет - так же плохо. Никогда не делай этого. Если вы хотите анимацию, сделайте это правильно и ** контролируемым способом **, например, с таймером Swing. –

+0

@ChristopherGreeley: но для игры с подключением 4 не нужна анимация, если вы не хотите анимировать падающие жетоны или некоторые такие, а затем это ограниченная анимация. –

Смежные вопросы