Link to home
Start Free TrialLog in
Avatar of Mike Eghtebas
Mike EghtebasFlag for United States of America

asked on

Modify existing JAplet...

I have the following good code from rrz@871311. This animation takes speed and radius inputs from 2 slider controls (it runs okay via netbeans, otherwise, run the HTML code after compiling the applet code).

Could you help me to remove these slider to simplify the code content. Sliders will not be used. Use the default values for these variables.

Question: Could you please remove the sliders?

Also, x to be 60 max (will require some sort of scaling to be applied showin the drum-string assembly larger and in the center of the screen).

for ref, see: https://www.experts-exchange.com/questions/27245193/Animation-help-3.html?anchorAnswerId=36347813#a36347813 

Thank you.


import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;

public class Drum extends JApplet implements ActionListener, ChangeListener {
	int drumX = 20; // location of drum left side
	int drumY = 20; // location of drum top
	int diameter = 30; // drum radius times two
	int pull = drumX + diameter; // horizontal location of bottom of rope where it being pulled
	int speed = 6; // pixels per time interval set by timer
	Animator animator; // the applet's content pane
	JSlider speedValue, dia;
	JLabel speedLabel, radiusLabel;
	JButton start, stop;
	Timer timer; // fires ActionEvent
	private void createGUI() {
		start = new JButton("Start");
		start.addActionListener(this);
		stop = new JButton("Stop");
		stop.addActionListener(this);
		JPanel contentPane = new JPanel(new BorderLayout());
		JPanel controlPanel = new JPanel(new FlowLayout());
		setContentPane(contentPane);
		animator = new Animator();
		animator.setOpaque(true);
		animator.setBackground(Color.WHITE);
		contentPane.add(animator, BorderLayout.CENTER);
		speedLabel = new JLabel("Speed");
		radiusLabel = new JLabel("Radius");
		speedValue = new JSlider(JSlider.HORIZONTAL, 1, 20, 6);
		speedValue.addChangeListener(this);
		dia = new JSlider(JSlider.HORIZONTAL, 20, 60, 40);
		dia.addChangeListener(this);
		controlPanel.add(speedLabel);
		controlPanel.add(speedValue);
		controlPanel.add(radiusLabel);
		controlPanel.add(dia);
		controlPanel.add(start);
		controlPanel.add(stop);
		contentPane.add(controlPanel, BorderLayout.NORTH);
	}
	public void init() {
		try {
			SwingUtilities.invokeAndWait(new Runnable() {
				public void run() {
					createGUI();
				}
			});
		} catch (Exception e) {
			System.err.println("createGUI didn't successfully complete:");
			e.printStackTrace();
		}
		timer = new Timer(100, this);
	}
	public void stateChanged(ChangeEvent e) {
		JSlider source = (JSlider) e.getSource();
		if (!source.getValueIsAdjusting()) {
			int value = (int) source.getValue();
			if (source == speedValue) {
				speed = value;
				animator.repaint();
			}
			if (source == dia) {
				diameter = value;
				pull = drumX + diameter;
				animator.repaint();
			}
		}
	}
	public void actionPerformed(ActionEvent e) {
		Object source = e.getSource();
		if (source == start) {
			pull = drumX + diameter;
			animator.repaint();
			timer.start();
		} else if (source == stop) {
			timer.stop();
		} else {
			pull = pull + speed;
			animator.repaint();
		}
	}
	public class Animator extends JPanel {
		DecimalFormat df = new DecimalFormat("00.00");
		Graphics2D g2d;
		double b = 0; // angle on drum where rope makes contact		
		double C = 0; // equals cos(b)
		double a = 0; // angle the drum has been rotated
		double h = 200 - drumY - diameter / 2; // height of the center of the drum from base line
		double x = pull - drumX - diameter; // distance that rope was pulled along horizontal base line
		public Animator() {
			super();
		}
		private void calculate() {
			h = 90 - drumY - diameter / 2;
			x = pull - drumX - diameter;
			double j = x / h;
			double k = (diameter/2) / h;
			C = (k * (j + k) + Math.sqrt(j * j + 2 * j * k + 1))
					/ ((j + k) * (j + k) + 1);
			b = Math.acos(C);
			a = (diameter/2 * Math.tan(b) + h/C - h) / (diameter/2) - b;
		}
		protected void paintComponent(Graphics g) {
			g2d = (Graphics2D) g;
			super.paintComponent(g2d);
			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			calculate();
			g2d.setColor(Color.YELLOW);
			g2d.fillOval(drumX, drumY, diameter, diameter); // drum
			g2d.setColor(Color.RED);
			//g2d.setStroke(stroke);
			g2d.drawLine(drumX + diameter/2 + (int)((diameter / 2) * Math.cos(b)), 
					     drumY + (int) diameter/2 - (int)((diameter / 2) * Math.sin(b)),
					     pull, 
					     90); // rope
			g2d.setColor(Color.BLACK);
			g2d.fillArc(drumX + 2, drumY + 2, diameter - 4, diameter - 4, -(int)(a * 57.3), 25); // drum marker
			g2d.drawString("Speed is " + (speedValue.getValue()) * 10 + " pixels/second", 30, 110);
			g2d.drawString("Radius is " + diameter/2 + " pixels", 230, 110);
			g2d.drawString("b is " + df.format(b) + " radians", 30, 125);
			g2d.drawString("a is " + df.format(a) + " radians", 250, 125);
			g2d.drawString("h is " + df.format(h), 30, 140);
			g2d.drawString("x is " + df.format(x) + " pixels", 250, 140);
			g2d.setColor(Color.CYAN);
			g2d.drawLine(5, 90, 1000, 90);
			g2d.drawLine(5, 145, 500, 145);
		}
	}
	public void stop() {
		timer.stop();
	}
}

Open in new window

<html>
<head>
    <style type="text/css">
           body{ background-color:#d6eff7;}     
    </style>
<title>Drum Applet</title>
</head>
<body>
<applet code="Drum.class" width="800" height="300"></applet>
</body>
</html>

Open in new window

Avatar of Peter Kwan
Peter Kwan
Flag of Hong Kong image

You just need to comment out the lines using JSlider and don't implement ChangeListener. Then it will work. The following is a working code:

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;

public class Drum extends JApplet implements ActionListener {
	int drumX = 20; // location of drum left side
	int drumY = 20; // location of drum top
	int diameter = 30; // drum radius times two
	int pull = drumX + diameter; // horizontal location of bottom of rope where it being pulled
	int speed = 6; // pixels per time interval set by timer
	Animator animator; // the applet's content pane
	//JSlider speedValue, dia;
	//JLabel speedLabel, radiusLabel;
	JButton start, stop;
	Timer timer; // fires ActionEvent
	private void createGUI() {
		start = new JButton("Start");
		start.addActionListener(this);
		stop = new JButton("Stop");
		stop.addActionListener(this);
		JPanel contentPane = new JPanel(new BorderLayout());
		JPanel controlPanel = new JPanel(new FlowLayout());
		setContentPane(contentPane);
		animator = new Animator();
		animator.setOpaque(true);
		animator.setBackground(Color.WHITE);
		contentPane.add(animator, BorderLayout.CENTER);
		//speedLabel = new JLabel("Speed");
		//radiusLabel = new JLabel("Radius");
		//speedValue = new JSlider(JSlider.HORIZONTAL, 1, 20, 6);
		//speedValue.addChangeListener(this);
		//dia = new JSlider(JSlider.HORIZONTAL, 20, 60, 40);
		//dia.addChangeListener(this);
		//controlPanel.add(speedLabel);
		//controlPanel.add(speedValue);
		//controlPanel.add(radiusLabel);
		//controlPanel.add(dia);
		controlPanel.add(start);
		controlPanel.add(stop);
		contentPane.add(controlPanel, BorderLayout.NORTH);
	}
	public void init() {
		try {
			SwingUtilities.invokeAndWait(new Runnable() {
				public void run() {
					createGUI();
				}
			});
		} catch (Exception e) {
			System.err.println("createGUI didn't successfully complete:");
			e.printStackTrace();
		}
		timer = new Timer(100, this);
	}
	/*public void stateChanged(ChangeEvent e) {
		JSlider source = (JSlider) e.getSource();
		if (!source.getValueIsAdjusting()) {
			int value = (int) source.getValue();
			if (source == speedValue) {
				speed = value;
				animator.repaint();
			}
			if (source == dia) {
				diameter = value;
				pull = drumX + diameter;
				animator.repaint();
			}
		}
	}*/
	public void actionPerformed(ActionEvent e) {
		Object source = e.getSource();
		if (source == start) {
			pull = drumX + diameter;
			animator.repaint();
			timer.start();
		} else if (source == stop) {
			timer.stop();
		} else {
			pull = pull + speed;
			animator.repaint();
		}
	}
	public class Animator extends JPanel {
		DecimalFormat df = new DecimalFormat("00.00");
		Graphics2D g2d;
		double b = 0; // angle on drum where rope makes contact		
		double C = 0; // equals cos(b)
		double a = 0; // angle the drum has been rotated
		double h = 200 - drumY - diameter / 2; // height of the center of the drum from base line
		double x = pull - drumX - diameter; // distance that rope was pulled along horizontal base line
		public Animator() {
			super();
		}
		private void calculate() {
			h = 90 - drumY - diameter / 2;
			x = pull - drumX - diameter;
			double j = x / h;
			double k = (diameter/2) / h;
			C = (k * (j + k) + Math.sqrt(j * j + 2 * j * k + 1))
					/ ((j + k) * (j + k) + 1);
			b = Math.acos(C);
			a = (diameter/2 * Math.tan(b) + h/C - h) / (diameter/2) - b;
		}
		protected void paintComponent(Graphics g) {
			g2d = (Graphics2D) g;
			super.paintComponent(g2d);
			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			calculate();
			g2d.setColor(Color.YELLOW);
			g2d.fillOval(drumX, drumY, diameter, diameter); // drum
			g2d.setColor(Color.RED);
			//g2d.setStroke(stroke);
			g2d.drawLine(drumX + diameter/2 + (int)((diameter / 2) * Math.cos(b)), 
					     drumY + (int) diameter/2 - (int)((diameter / 2) * Math.sin(b)),
					     pull, 
					     90); // rope
			g2d.setColor(Color.BLACK);
			g2d.fillArc(drumX + 2, drumY + 2, diameter - 4, diameter - 4, -(int)(a * 57.3), 25); // drum marker
			g2d.drawString("Speed is " + speed * 10 + " pixels/second", 30, 110);
			g2d.drawString("Radius is " + diameter/2 + " pixels", 230, 110);
			g2d.drawString("b is " + df.format(b) + " radians", 30, 125);
			g2d.drawString("a is " + df.format(a) + " radians", 250, 125);
			g2d.drawString("h is " + df.format(h), 30, 140);
			g2d.drawString("x is " + df.format(x) + " pixels", 250, 140);
			g2d.setColor(Color.CYAN);
			g2d.drawLine(5, 90, 1000, 90);
			g2d.drawLine(5, 145, 500, 145);
		}
	}
	public void stop() {
		timer.stop();
	}
}

Open in new window

Avatar of Mike Eghtebas

ASKER

hi pkwan,

I wish it was that easy. I tried but couldn't make it work. I will test your modification after I get to my computer.
No surprize. You solutions always work. But what about the second part described below:

re:> Also, x to be 60 max (will require some sort of scaling to be applied showin the drum-string assembly larger and in the center of the screen).

?

thx
ASKER CERTIFIED SOLUTION
Avatar of Peter Kwan
Peter Kwan
Flag of Hong Kong image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you