// MovingBallApplication.cs Copyright (c) Kari Laitinen // http://www.naturalprogramming.com // 2008-02-23 File created. // 2022-12-20 Tested in Developer Command Prompt for VS 2022. // This program is a C# application that works in the same // way as the Java applet MovingBallApplet.java. // This program shows how Button, Panel, and ComboBox objects // can be used. // In this program the height of the application window is set to // 435 pixels. The actual drawing area in the window is about 400 // pixels high because the height of the title area is about // 35 pixels. // More notes at the end of this file. using System ; using System.Windows.Forms ; using System.Drawing ; class MovingBallForm : Form { const int WINDOW_WIDTH = 500 ; const int WINDOW_HEIGHT = 435 ; const int PANEL_HEIGHT = 30 ; Button left_button, up_button, down_button, right_button ; int ball_position_x, ball_position_y ; Color current_ball_color = Color.Red ; ComboBox color_selection_list ; // The following two initialized arrays must be organized so that // each name of a color has the same index as the corresponding // Color object in the other array. String[] selectable_color_names = { "Red", "Green", "Blue", "Tomato", "PaleGreen", "SkyBlue", "Cyan", "Magenta", "Yellow", "Black", "Gray" } ; Color[] selectable_colors = { Color.Red, Color.Green, Color.Blue, Color.Tomato, Color.PaleGreen, Color.SkyBlue, Color.Cyan, Color.Magenta, Color.Yellow, Color.Black, Color.Gray } ; public MovingBallForm() { Text = "MOVE THE BALL WITH THE BUTTONS" ; Size = new Size( WINDOW_WIDTH, WINDOW_HEIGHT ) ; ball_position_x = WINDOW_WIDTH / 2 - 40 ; ball_position_y = WINDOW_HEIGHT / 2 - 40 ; Panel operations_panel = new Panel() ; int panel_width = WINDOW_WIDTH * 3 / 4 ; operations_panel.Size = new Size( panel_width, PANEL_HEIGHT ) ; operations_panel.Location = new Point(( WINDOW_WIDTH - panel_width ) / 2, WINDOW_HEIGHT - PANEL_HEIGHT - 35 ); // If the window is resized, the operations panel will be kept // at the bottom of the form. operations_panel.Anchor = AnchorStyles.Bottom ; left_button = new Button() ; up_button = new Button() ; down_button = new Button() ; right_button = new Button() ; left_button.Text = " < " ; up_button.Text = " Up " ; down_button.Text = " Down " ; right_button.Text = " > " ; up_button.Location = new Point( panel_width / 5, 0 ) ; down_button.Location = new Point( panel_width * 2 / 5, 0 ) ; right_button.Location = new Point( panel_width * 3 / 5, 0 ) ; left_button.Click += new EventHandler( left_button_clicked ) ; up_button.Click += new EventHandler( up_button_clicked ) ; down_button.Click += new EventHandler( down_button_clicked ) ; right_button.Click += new EventHandler( right_button_clicked ) ; operations_panel.Controls.Add( left_button ) ; operations_panel.Controls.Add( up_button ) ; operations_panel.Controls.Add( down_button ) ; operations_panel.Controls.Add( right_button ) ; color_selection_list = new ComboBox() ; color_selection_list.Items.AddRange( selectable_color_names ) ; color_selection_list.SelectedIndex = 0 ; color_selection_list.Width = panel_width / 5 ; color_selection_list.Location = new Point( panel_width * 4 / 5, 0 ) ; color_selection_list.SelectedIndexChanged += new EventHandler( color_selection_made ) ; operations_panel.Controls.Add( color_selection_list ) ; // Add the operations panel to the form. Controls.Add( operations_panel ) ; } private void left_button_clicked( Object sender, EventArgs event_data ) { ball_position_x -= 3 ; Invalidate() ; } private void up_button_clicked( Object sender, EventArgs event_data ) { ball_position_y -= 3 ; Invalidate() ; } private void down_button_clicked( Object sender, EventArgs event_data ) { ball_position_y += 3 ; Invalidate() ; } private void right_button_clicked( Object sender, EventArgs event_data ) { ball_position_x += 3 ; Invalidate() ; } private void color_selection_made( Object sender, EventArgs event_data ) { int index_of_selected_color = color_selection_list.SelectedIndex ; // The following assignment statement selects the right color // when the array pointed by selectable_color_names is initialized // so that it corresponds to the array containing the selectable // colors. current_ball_color = selectable_colors[ index_of_selected_color ] ; Invalidate() ; } protected override void OnPaint( PaintEventArgs paint_data ) { Graphics graphics = paint_data.Graphics ; graphics.FillEllipse( new SolidBrush( current_ball_color ), ball_position_x, ball_position_y, 80, 80 ) ; graphics.DrawEllipse( new Pen( Color.Black ), ball_position_x, ball_position_y, 80, 80 ) ; graphics.DrawString( "(" + ball_position_x + ", " + ball_position_y + ")", Font, new SolidBrush( Color.Black ), 20, 20 ) ; } } public class MovingBallApplication { static void Main() { MovingBallForm moving_ball_form = new MovingBallForm() ; Application.Run( moving_ball_form ) ; } } /* NOTE: Some books about Windows programming say that graphical objects such as Pens and Brushes must be disposed with the Dispose() method when they are no longer used. The Dispose() method is used as follows Pen black_pen = new Pen( Color.Black ) ; ... black_pen.Dispose() ; I have not used the Dispose() method in these programs as I suppose that the garbage collector is quick enough to dispose these objects. */