У меня есть JFrame
с маской границы, которая имеет два JPanel
s. Один из JPanel
в южной части кадра имеет несколько JButtons (номер n
), а один показывает плату подключения - 4 (это для класса CS). По какой-то странной причине у меня есть странная ошибка, в которой анимации для кнопок отображаются в верхнем левом углу.Java Drawing Button Анимация в верхнем углу
Его довольно странно ошибка, я не эксперт на качелях я задавался вопросом, если он не имеет ничего общего со мной работает метод 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;
}
}
}
}
Любое понимание или помощь по этому вопросу очень ценится! :)
Спасибо - ТФБ :-)
Благодарим за ответ! Могу ли я безопасно называть 'repaint' из' paintComponent' (который, похоже, работает, но теоретически он безопасен [?])? –
@ Кристофер Грили: нет - так же плохо. Никогда не делай этого. Если вы хотите анимацию, сделайте это правильно и ** контролируемым способом **, например, с таймером Swing. –
@ChristopherGreeley: но для игры с подключением 4 не нужна анимация, если вы не хотите анимировать падающие жетоны или некоторые такие, а затем это ограниченная анимация. –