Java 在顶角绘制按钮动画
Java Drawing Button Animations In Top Corner
我有一个 JFrame
,其边框布局有两个 JPanel
。框架南部的一个 JPanel
有一些 JButton(一个 n
数字),一个显示连接 - 4 板(这是用于 CS class)。出于某种奇怪的原因,我有一个奇怪的错误,按钮的动画显示在左上角。
这是一个很奇怪的错误,我不是挥杆专家 我想知道它是否与我有任何关系 运行 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;
}
}
}
}
非常感谢对此问题的任何见解或帮助! :)
谢谢
- TFB :-)
- 不要从
paint(...)
中调用 repaint()
,因为这会导致
- 动画无法控制,
- 对不适合的东西使用绘画方法。
- 您甚至不应该覆盖 paint,而应该覆盖 paintComponent。
- 这是个大问题:您必须在您的绘画重写中调用 super 的绘画方法。因此,如果您要覆盖 paintComponent,请在其中调用
super.paintComponent(...)
方法。
我有一个 JFrame
,其边框布局有两个 JPanel
。框架南部的一个 JPanel
有一些 JButton(一个 n
数字),一个显示连接 - 4 板(这是用于 CS class)。出于某种奇怪的原因,我有一个奇怪的错误,按钮的动画显示在左上角。
这是一个很奇怪的错误,我不是挥杆专家 我想知道它是否与我有任何关系 运行 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;
}
}
}
}
非常感谢对此问题的任何见解或帮助! :)
谢谢 - TFB :-)
- 不要从
paint(...)
中调用repaint()
,因为这会导致- 动画无法控制,
- 对不适合的东西使用绘画方法。
- 您甚至不应该覆盖 paint,而应该覆盖 paintComponent。
- 这是个大问题:您必须在您的绘画重写中调用 super 的绘画方法。因此,如果您要覆盖 paintComponent,请在其中调用
super.paintComponent(...)
方法。